Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,561 changes: 2,561 additions & 0 deletions cpp/downgrades/837c4e02326aee4582405d069263092e80a15d82/old.dbscheme

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
description: Support alias templates
compatibility: full
is_alias_template.rel: delete
alias_instantiation.rel: delete
alias_template_argument.rel: delete
alias_template_argument_value.rel: delete
4 changes: 4 additions & 0 deletions cpp/ql/lib/change-notes/2026-05-16-alias-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: feature
---
* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations.
4 changes: 4 additions & 0 deletions cpp/ql/lib/change-notes/2026-05-18-alias-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: deprecated
---
* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead.
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 @@ -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))
Expand All @@ -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))
Expand Down
18 changes: 18 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/Element.qll
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,15 @@ private predicate isFromTemplateInstantiationRec(Element e, Element instantiatio
instantiation.(Variable).isConstructedFrom(_) and
e = instantiation
or
instantiation.(TypeAliasType).isConstructedFrom(_) and
e = instantiation
or
instantiation.(TemplateTemplateParameterInstantiation).isConstructedFrom(_) and
e = instantiation
or
exists(instantiation.(ConceptIdExpr).getConcept()) and
e = instantiation
or
isFromTemplateInstantiationRec(e.getEnclosingElement(), instantiation)
}

Expand All @@ -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
Comment thread
jketema marked this conversation as resolved.
Dismissed
e = template
or
template instanceof @concept_template and
e = template
or
isFromUninstantiatedTemplateRec(e.getEnclosingElement(), template)
}

Expand Down
89 changes: 84 additions & 5 deletions cpp/ql/lib/semmle/code/cpp/TypedefType.qll
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,102 @@ class CTypedefType extends TypedefType {
}

/**
* A using alias C++ typedef type. For example the type declared in the following code:
* DEPRECATED: Use `TypeAlias` instead.
*
* A C++ type alias or alias template.
*
* For example the type declared in the following code:
* ```
* using my_int2 = int;
* ```
*/
class UsingAliasTypedefType extends TypedefType {
UsingAliasTypedefType() { usertype_alias_kind(underlyingElement(this), 1) }
deprecated class UsingAliasTypedefType = TypeAliasType;

override string getAPrimaryQlClass() { result = "UsingAliasTypedefType" }
/**
* A C++ type alias or alias template.
*
* For example the type declared in the following code:
* ```
* using my_int2 = int;
* ```
*/
class TypeAliasType extends TypedefType {
TypeAliasType() { usertype_alias_kind(underlyingElement(this), 1) }

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

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(TypeAliasType 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 AliasTemplateType extends TypeAliasType {
AliasTemplateType() { is_alias_template(underlyingElement(this)) }

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

/**
* Gets an 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;
* ```
*/
TypeAliasType 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 AliasTemplateInstantiationType extends TypeAliasType {
AliasTemplateType at;

AliasTemplateInstantiationType() { at.getAnInstantiation() = this }

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

/**
* Gets the alias template from which this instantiation was instantiated.
*/
AliasTemplateType getTemplate() { result = at }
}

/**
* A C++ `typedef` type that is directly enclosed by a function. For example the type declared inside the function `foo` in
* A C++ `typedef` type that is directly enclosed by a function.
*
* For example the type declared inside the function `foo` in
* the following code:
* ```
* int foo(void) { typedef int local; }
Expand Down
16 changes: 16 additions & 0 deletions cpp/ql/lib/semmlecode.cpp.dbscheme
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Comment on lines +969 to +974
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name is not really relevant. I've another scheme update in the pipeline. I'll fix this as part of that update.

int index: int ref,
int arg_value: @expr ref
);

template_template_instantiation(
int to: @usertype ref,
int from: @usertype ref
Expand Down
Loading
Loading