Merge pull request #18367 from github/jketema/template-parameters-6

C++: Handle template variable specializations
This commit is contained in:
Jeroen Ketema
2025-01-09 22:21:03 +01:00
committed by GitHub
11 changed files with 9759 additions and 183 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,3 @@
description: Support variable template specializations
compatibility: full
var_specialized.rel: delete

View File

@@ -0,0 +1,5 @@
---
category: feature
---
* A new class `VariableTemplateSpecialization` was introduced, which represents explicit specializations of variable templates.
* A new predicate `isSpecialization` was added to the `Variable` class, which holds if the variable is a template specialization.

View File

@@ -253,7 +253,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
*/
override Location getADeclarationLocation() { result = this.getADeclarationEntry().getLocation() }
/** Holds if this Function is a Template specialization. */
/** Holds if this function is a template specialization. */
predicate isSpecialization() {
exists(FunctionDeclarationEntry fde |
fun_decls(unresolveElement(fde), underlyingElement(this), _, _, _) and
@@ -665,7 +665,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
/** Holds if this declaration is also a definition of its function. */
override predicate isDefinition() { fun_def(underlyingElement(this)) }
/** Holds if this declaration is a Template specialization. */
/** Holds if this declaration is a template specialization. */
predicate isSpecialization() { fun_specialized(underlyingElement(this)) }
/**

View File

@@ -187,6 +187,14 @@ class Variable extends Declaration, @variable {
* `for (char c : str) { ... }`
*/
predicate isCompilerGenerated() { compgenerated(underlyingElement(this)) }
/** Holds if this variable is a template specialization. */
predicate isSpecialization() {
exists(VariableDeclarationEntry vde |
var_decls(unresolveElement(vde), underlyingElement(this), _, _, _) and
vde.isSpecialization()
)
}
}
/**
@@ -267,6 +275,9 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
override predicate isDefinition() { var_def(underlyingElement(this)) }
override string getASpecifier() { var_decl_specifiers(underlyingElement(this), result) }
/** Holds if this declaration is a template specialization. */
predicate isSpecialization() { var_specialized(underlyingElement(this)) }
}
/**
@@ -594,7 +605,10 @@ class TemplateVariable extends Variable {
/**
* Gets an instantiation of this variable template.
*/
Variable getAnInstantiation() { result.isConstructedFrom(this) }
Variable getAnInstantiation() {
result.isConstructedFrom(this) and
not result.isSpecialization()
}
}
/**
@@ -624,6 +638,21 @@ class VariableTemplateInstantiation extends Variable {
TemplateVariable getTemplate() { result = tv }
}
/**
* An explicit specialization of a C++ variable template.
*/
class VariableTemplateSpecialization extends Variable {
VariableTemplateSpecialization() { this.isSpecialization() }
override string getAPrimaryQlClass() { result = "VariableTemplateSpecialization" }
/**
* Gets the primary template for the specialization (the function template
* this specializes).
*/
TemplateVariable getPrimaryTemplate() { this.isConstructedFrom(result) }
}
/**
* A non-static local variable or parameter that is not part of an
* uninstantiated template. Uninstantiated templates are purely syntax, and

View File

@@ -495,6 +495,7 @@ var_decls(
int location: @location_default ref
);
var_def(unique int id: @var_decl ref);
var_specialized(int id: @var_decl ref);
var_decl_specifiers(
int id: @var_decl ref,
string name: string 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 variable template specializations
compatibility: partial