Skip to content

Commit

Permalink
Merge pull request #18320 from jketema/template-parameters
Browse files Browse the repository at this point in the history
C++: Support non-type template parameters
  • Loading branch information
jketema authored Dec 19, 2024
2 parents 90dbc34 + 2209ee6 commit 84b60d2
Show file tree
Hide file tree
Showing 12 changed files with 12,983 additions and 3,600 deletions.
2,343 changes: 2,343 additions & 0 deletions cpp/downgrades/d6a03a00b9824f27241b58b8e18208f31c03904a/old.dbscheme

Large diffs are not rendered by default.

2,339 changes: 2,339 additions & 0 deletions cpp/downgrades/d6a03a00b9824f27241b58b8e18208f31c03904a/semmlecode.cpp.dbscheme

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
description: Support non-type template parameters
compatibility: full
nontype_template_parameters.rel: delete
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: feature
---
* A new class `NonTypeTemplateParameter` was introduced, which represents C++ non-type template parameters.
1 change: 1 addition & 0 deletions cpp/ql/lib/cpp.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
92 changes: 92 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll
Original file line number Diff line number Diff line change
@@ -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 }
}
82 changes: 2 additions & 80 deletions cpp/ql/lib/semmle/code/cpp/Type.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand Down Expand Up @@ -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 }
}

/**
Expand Down Expand Up @@ -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.
*
Expand Down
4 changes: 4 additions & 0 deletions cpp/ql/lib/semmlecode.cpp.dbscheme
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading

0 comments on commit 84b60d2

Please sign in to comment.