Merge pull request #18320 from jketema/template-parameters

C++: Support non-type template parameters
This commit is contained in:
Jeroen Ketema
2024-12-19 16:21:49 +01:00
committed by GitHub
12 changed files with 12993 additions and 3610 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
description: Support non-type template parameters
compatibility: full
nontype_template_parameters.rel: delete

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* A new class `NonTypeTemplateParameter` was introduced, which represents C++ non-type template parameters.

View File

@@ -35,6 +35,7 @@ import semmle.code.cpp.Field
import semmle.code.cpp.Function
import semmle.code.cpp.MemberFunction
import semmle.code.cpp.Parameter
import semmle.code.cpp.TemplateParameter
import semmle.code.cpp.Variable
import semmle.code.cpp.Initializer
import semmle.code.cpp.FriendDecl

View File

@@ -0,0 +1,92 @@
/**
* Provides a hierarchy of classes for modeling C/C++ template parameters.
*/
import semmle.code.cpp.Type
private import semmle.code.cpp.internal.ResolveClass
abstract private class TemplateParameterImpl extends Locatable {
override string getAPrimaryQlClass() { result = "TemplateParameterImpl" }
}
/**
* A C++ template parameter.
*
* In the example below, `T`, `TT`, and `I` are template parameters:
* ```
* template <class T, template<typename> TT, int I>
* class C { };
* ```
*/
final class TemplateParameterBase = TemplateParameterImpl;
/**
* A C++ non-type template parameter.
*
* In the example below, `I` is a non-type template parameter:
* ```
* template <int I>
* class C { };
* ```
*/
class NonTypeTemplateParameter extends Literal, TemplateParameterImpl {
NonTypeTemplateParameter() { nontype_template_parameters(underlyingElement(this)) }
override string getAPrimaryQlClass() { result = "NonTypeTemplateParameter" }
}
/**
* A C++ `typename` (or `class`) template parameter.
*
* DEPRECATED: Use `TypeTemplateParameter` instead.
*/
deprecated class TemplateParameter = TypeTemplateParameter;
/**
* A C++ `typename` (or `class`) template parameter.
*
* In the example below, `T` is a template parameter:
* ```
* template <class T>
* class C { };
* ```
*/
class TypeTemplateParameter extends UserType, TemplateParameterImpl {
TypeTemplateParameter() {
usertypes(underlyingElement(this), _, 7) or usertypes(underlyingElement(this), _, 8)
}
override string getAPrimaryQlClass() { result = "TypeTemplateParameter" }
override predicate involvesTemplateParameter() { any() }
}
/**
* A C++ template template parameter.
*
* In the example below, `T` is a template template parameter (although its name
* may be omitted):
* ```
* template <template <typename T> class Container, class Elem>
* void foo(const Container<Elem> &value) { }
* ```
*/
class TemplateTemplateParameter extends TypeTemplateParameter {
TemplateTemplateParameter() { usertypes(underlyingElement(this), _, 8) }
override string getAPrimaryQlClass() { result = "TemplateTemplateParameter" }
}
/**
* A type representing the use of the C++11 `auto` keyword.
* ```
* auto val = some_typed_expr();
* ```
*/
class AutoType extends TypeTemplateParameter {
AutoType() { usertypes(underlyingElement(this), "auto", 7) }
override string getAPrimaryQlClass() { result = "AutoType" }
override Location getLocation() { result instanceof UnknownDefaultLocation }
}

View File

@@ -4,6 +4,7 @@
import semmle.code.cpp.Element
import semmle.code.cpp.Function
import semmle.code.cpp.TemplateParameter
private import semmle.code.cpp.internal.ResolveClass
/**
@@ -288,10 +289,7 @@ class Type extends Locatable, @type {
*/
Type stripType() { result = this }
override Location getLocation() {
suppressUnusedThis(this) and
result instanceof UnknownDefaultLocation
}
override Location getLocation() { result instanceof UnknownDefaultLocation }
}
/**
@@ -1666,82 +1664,6 @@ class RoutineType extends Type, @routinetype {
}
}
abstract private class TemplateParameterImpl extends Locatable {
override string getAPrimaryQlClass() { result = "TemplateParameterImpl" }
}
/**
* A C++ template parameter.
*
* In the example below, `T`, `TT`, and `I` are template parameters:
* ```
* template <class T, template<typename> TT, int I>
* class C { };
* ```
*/
final class TemplateParameterBase = TemplateParameterImpl;
/**
* A C++ `typename` (or `class`) template parameter.
*
* DEPRECATED: Use `TypeTemplateParameter` instead.
*/
deprecated class TemplateParameter = TypeTemplateParameter;
/**
* A C++ `typename` (or `class`) template parameter.
*
* In the example below, `T` is a template parameter:
* ```
* template <class T>
* class C { };
* ```
*/
class TypeTemplateParameter extends UserType, TemplateParameterImpl {
TypeTemplateParameter() {
usertypes(underlyingElement(this), _, 7) or usertypes(underlyingElement(this), _, 8)
}
override string getAPrimaryQlClass() { result = "TypeTemplateParameter" }
override predicate involvesTemplateParameter() { any() }
}
/**
* A C++ template template parameter.
*
* In the example below, `T` is a template template parameter (although its name
* may be omitted):
* ```
* template <template <typename T> class Container, class Elem>
* void foo(const Container<Elem> &value) { }
* ```
*/
class TemplateTemplateParameter extends TypeTemplateParameter {
TemplateTemplateParameter() { usertypes(underlyingElement(this), _, 8) }
override string getAPrimaryQlClass() { result = "TemplateTemplateParameter" }
}
/**
* A type representing the use of the C++11 `auto` keyword.
* ```
* auto val = some_typed_expr();
* ```
*/
class AutoType extends TypeTemplateParameter {
AutoType() { usertypes(underlyingElement(this), "auto", 7) }
override string getAPrimaryQlClass() { result = "AutoType" }
override Location getLocation() {
suppressUnusedThis(this) and
result instanceof UnknownDefaultLocation
}
}
private predicate suppressUnusedThis(Type t) { any() }
/**
* A source code location referring to a user-defined type.
*

View File

@@ -785,6 +785,10 @@ usertype_uuid(
string uuid: string ref
);
nontype_template_parameters(
int id: @expr ref
);
mangled_name(
unique int id: @declaration ref,
int mangled_name : @mangledname,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Support non-type template parameters
compatibility: partial