C++: Add support for alias templates

Add other missing cases to `isFromTemplateInstantiationRec` and
`isFromUninstantiatedTemplateRec` while here.
This commit is contained in:
Jeroen Ketema
2026-05-16 09:11:54 +02:00
parent d47ee6bed9
commit 336bbc229e
4 changed files with 100 additions and 1 deletions

View File

@@ -278,6 +278,8 @@ class Declaration extends Locatable, @declaration {
or
variable_template_argument(underlyingElement(this), index, unresolveElement(result))
or
alias_template_argument(underlyingElement(this), index, unresolveElement(result))
or
template_template_argument(underlyingElement(this), index, unresolveElement(result))
or
concept_template_argument(underlyingElement(this), index, unresolveElement(result))
@@ -290,6 +292,8 @@ class Declaration extends Locatable, @declaration {
or
variable_template_argument_value(underlyingElement(this), index, unresolveElement(result))
or
alias_template_argument_value(underlyingElement(this), index, unresolveElement(result))
or
template_template_argument_value(underlyingElement(this), index, unresolveElement(result))
or
concept_template_argument_value(underlyingElement(this), index, unresolveElement(result))

View File

@@ -278,6 +278,15 @@ private predicate isFromTemplateInstantiationRec(Element e, Element instantiatio
instantiation.(Variable).isConstructedFrom(_) and
e = instantiation
or
instantiation.(UsingAliasTypedefType).isConstructedFrom(_) and
e = instantiation
or
instantiation.(TemplateTemplateParameterInstantiation).isConstructedFrom(_) and
e = instantiation
or
exists(instantiation.(ConceptIdExpr).getConcept()) and
e = instantiation
or
isFromTemplateInstantiationRec(e.getEnclosingElement(), instantiation)
}
@@ -291,6 +300,15 @@ private predicate isFromUninstantiatedTemplateRec(Element e, Element template) {
is_variable_template(unresolveElement(template)) and
e = template
or
is_alias_template(unresolveElement(template)) and
e = template
or
usertypes(unresolveElement(template), _, 8) and // template template parameter
e = template
or
template instanceof @concept_template and
e = template
or
isFromUninstantiatedTemplateRec(e.getEnclosingElement(), template)
}

View File

@@ -64,7 +64,8 @@ class CTypedefType extends TypedefType {
}
/**
* A using alias C++ typedef type. For example the type declared in the following code:
* A C++ type alias or alias template. For example the type declared in the following
* code:
* ```
* using my_int2 = int;
* ```
@@ -77,6 +78,66 @@ class UsingAliasTypedefType extends TypedefType {
override string explain() {
result = "using {" + this.getBaseType().explain() + "} as \"" + this.getName() + "\""
}
/**
* Holds if this alias is constructed from another alias as a result of
* template instantiation.
*/
predicate isConstructedFrom(UsingAliasTypedefType t) {
alias_instantiation(underlyingElement(this), unresolveElement(t))
}
}
/**
* A C++ alias template. For example the type declared in the following code:
* ```
* template <typename T>
* using my_type = T;
* ```
*/
class AliasTemplateTypedefType extends TypedefType {
AliasTemplateTypedefType() { is_alias_template(underlyingElement(this)) }
override string getAPrimaryQlClass() { result = "AliasTemplateTypedefType" }
/**
* Gets a alias instantiated from this template.
*
* For example for `MyAliasTemplate<T>` in the following code, the results are
* `MyAliasTemplate<int>` and `MyAliasTemplate<long>`:
* ```
* template<typename T>
* using MyAliasTemplate = ;
*
* MyAliasTemplate<int> instance1;
*
* MyAliasTemplate<long> instance2;
* ```
*/
UsingAliasTypedefType getAnInstantiation() { result.isConstructedFrom(this) }
}
/**
* A C++ alias template instantiation. For example the `my_int_type` type declared in
* the following code:
* ```
* template <typename T>
* using my_type = T;
*
* using my_int_type = my_type<int>;
* ```
*/
class AliasTemplateInstantiationTypedefType extends UsingAliasTypedefType {
AliasTemplateTypedefType ta;
AliasTemplateInstantiationTypedefType() { ta.getAnInstantiation() = this }
override string getAPrimaryQlClass() { result = "AliasTemplateInstantiationTypedefType" }
/**
* Gets the alias template from which this instantiation was instantiated.
*/
AliasTemplateTypedefType getTemplate() { result = ta }
}
/**

View File

@@ -960,6 +960,22 @@ variable_template_argument_value(
int arg_value: @expr ref
);
is_alias_template(unique int id: @usertype ref);
alias_instantiation(
unique int to: @usertype ref,
int from: @usertype ref
);
alias_template_argument(
int variable_id: @usertype ref,
int index: int ref,
int arg_type: @type ref
);
alias_template_argument_value(
int variable_id: @usertype ref,
int index: int ref,
int arg_value: @expr ref
);
template_template_instantiation(
int to: @usertype ref,
int from: @usertype ref