Skip to content

Commit

Permalink
C++: Add NonTypeTemplateParameter class
Browse files Browse the repository at this point in the history
  • Loading branch information
jketema committed Dec 18, 2024
1 parent a99c9b5 commit 1306e48
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 80 deletions.
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

0 comments on commit 1306e48

Please sign in to comment.