Skip to content

Commit

Permalink
C++: Support arguments and instantiations of template template parame…
Browse files Browse the repository at this point in the history
…ters
  • Loading branch information
jketema committed Dec 22, 2024
1 parent b60c860 commit be884b8
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 3 deletions.
9 changes: 6 additions & 3 deletions cpp/ql/lib/semmle/code/cpp/Class.qll
Original file line number Diff line number Diff line change
Expand Up @@ -570,10 +570,13 @@ class Class extends UserType {
/**
* Holds if this class, struct or union is constructed from another class as
* a result of template instantiation. It originates either from a class
* template or from a class nested in a class template.
* template, a class nested in a class template, or a template template
* parameter.
*/
predicate isConstructedFrom(Class c) {
class_instantiation(underlyingElement(this), unresolveElement(c))
predicate isConstructedFrom(UserType t) {
class_instantiation(underlyingElement(this), unresolveElement(t))
or
template_template_instantiation(underlyingElement(this), unresolveElement(t))
}

/**
Expand Down
4 changes: 4 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/Declaration.qll
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ class Declaration extends Locatable, @declaration {
function_template_argument(underlyingElement(this), index, unresolveElement(result))
or
variable_template_argument(underlyingElement(this), index, unresolveElement(result))
or
template_template_argument(underlyingElement(this), index, unresolveElement(result))
}

private Expr getTemplateArgumentValue(int index) {
Expand All @@ -285,6 +287,8 @@ class Declaration extends Locatable, @declaration {
function_template_argument_value(underlyingElement(this), index, unresolveElement(result))
or
variable_template_argument_value(underlyingElement(this), index, unresolveElement(result))
or
template_template_argument_value(underlyingElement(this), index, unresolveElement(result))
}
}

Expand Down
44 changes: 44 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,21 @@ class TemplateTemplateParameter extends TypeTemplateParameter {
TemplateTemplateParameter() { usertypes(underlyingElement(this), _, 8) }

override string getAPrimaryQlClass() { result = "TemplateTemplateParameter" }

/**
* Gets a class instantiated from this template template parameter.
*
* For example for `Container<T>` in the following code, the results is
* `Container<Elem>`:
* ```
* template <template <typename T> class Container, class Elem>
* void foo(const Container<Elem> &value) { }
* ```
*/
Class getAnInstantiation() {
result.isConstructedFrom(this) and
exists(result.getATemplateArgument())
}
}

/**
Expand All @@ -90,3 +105,32 @@ class AutoType extends TypeTemplateParameter {

override Location getLocation() { result instanceof UnknownDefaultLocation }
}

/**
* A class that is an instantiation of a template template parameter. For example,
* in the following code there is a `Container<Elem>` instantiation:
* ```
* template <template <typename T> class Container, class Elem>
* void foo(const Container<Elem> &value) { }
* ```
* For the `Container` template itself, see `TemplateTemplateParameter`.
*/
class TemplateTemplateInstantiation extends Class {
TemplateTemplateParameter ttp;

TemplateTemplateInstantiation() { ttp.getAnInstantiation() = this }

override string getAPrimaryQlClass() { result = "TemplateTemplateInstantiation" }

/**
* Gets the template template parameter from which this instantiation was instantiated.
*
* For example for `Container<Elem>` in the following code, the result is
* `Container<T>`:
* ```
* template <template <typename T> class Container, class Elem>
* void foo(const Container<Elem> &value) { }
* ```
*/
TemplateTemplateParameter getTemplate() { result = ttp }
}
15 changes: 15 additions & 0 deletions cpp/ql/lib/semmlecode.cpp.dbscheme
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,21 @@ variable_template_argument_value(
int arg_value: @expr ref
);

template_template_instantiation(
unique int to: @usertype ref,
int from: @usertype ref
);
template_template_argument(
int type_id: @usertype ref,
int index: int ref,
int arg_type: @type ref
);
template_template_argument_value(
int type_id: @usertype ref,
int index: int ref,
int arg_value: @expr ref
);

routinetypes(
unique int id: @routinetype,
int return_type: @type ref
Expand Down

0 comments on commit be884b8

Please sign in to comment.