Merge pull request #18360 from github/jketema/template-parameters-3

C++: Support arguments and instantiations of template template parameters
This commit is contained in:
Jeroen Ketema
2025-01-06 13:41:45 +01:00
committed by GitHub
12 changed files with 10262 additions and 484 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,5 @@
description: Support template template parameter arguments and instantiations
compatibility: full
template_template_instantiation.rel: delete
template_template_argument.rel: delete
template_template_argument_value.rel: delete

View File

@@ -0,0 +1,6 @@
---
category: feature
---
* A new class `TemplateTemplateParameterInstantiation` was introduced, which represents instantiations of template template parameters.
* A new predicate `getAnInstantiation` was added to the `TemplateTemplateParameter` class, which yields instantiations of template template parameters.
* The `getTemplateArgumentType` and `getTemplateArgumentValue` predicates of the `Declaration` class now also yield template arguments of template template parameters.

View File

@@ -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))
}
/**

View File

@@ -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) {
@@ -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))
}
}

View File

@@ -75,6 +75,18 @@ 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 result is
* `Container<Elem>`:
* ```
* template <template <typename T> class Container, class Elem>
* void foo(const Container<Elem> &value) { }
* ```
*/
Class getAnInstantiation() { result.isConstructedFrom(this) }
}
/**
@@ -90,3 +102,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 TemplateTemplateParameterInstantiation extends Class {
TemplateTemplateParameter ttp;
TemplateTemplateParameterInstantiation() { ttp.getAnInstantiation() = this }
override string getAPrimaryQlClass() { result = "TemplateTemplateParameterInstantiation" }
/**
* 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 }
}

View File

@@ -861,6 +861,21 @@ variable_template_argument_value(
int arg_value: @expr ref
);
template_template_instantiation(
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

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 template template parameter arguments and instantiations
compatibility: partial