Skip to content

Commit 204afab

Browse files
authored
Merge pull request #18367 from github/jketema/template-parameters-6
C++: Handle template variable specializations
2 parents 928c66a + 347edc4 commit 204afab

File tree

11 files changed

+9749
-173
lines changed

11 files changed

+9749
-173
lines changed

cpp/downgrades/1a4bbe5ded083b9de87911c155fc99ca22ecb0ce/old.dbscheme

Lines changed: 2383 additions & 0 deletions
Large diffs are not rendered by default.

cpp/downgrades/1a4bbe5ded083b9de87911c155fc99ca22ecb0ce/semmlecode.cpp.dbscheme

Lines changed: 2382 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
description: Support variable template specializations
2+
compatibility: full
3+
var_specialized.rel: delete
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
category: feature
3+
---
4+
* A new class `VariableTemplateSpecialization` was introduced, which represents explicit specializations of variable templates.
5+
* A new predicate `isSpecialization` was added to the `Variable` class, which holds if the variable is a template specialization.

cpp/ql/lib/semmle/code/cpp/Function.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
253253
*/
254254
override Location getADeclarationLocation() { result = this.getADeclarationEntry().getLocation() }
255255

256-
/** Holds if this Function is a Template specialization. */
256+
/** Holds if this function is a template specialization. */
257257
predicate isSpecialization() {
258258
exists(FunctionDeclarationEntry fde |
259259
fun_decls(unresolveElement(fde), underlyingElement(this), _, _, _) and
@@ -665,7 +665,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
665665
/** Holds if this declaration is also a definition of its function. */
666666
override predicate isDefinition() { fun_def(underlyingElement(this)) }
667667

668-
/** Holds if this declaration is a Template specialization. */
668+
/** Holds if this declaration is a template specialization. */
669669
predicate isSpecialization() { fun_specialized(underlyingElement(this)) }
670670

671671
/**

cpp/ql/lib/semmle/code/cpp/Variable.qll

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,14 @@ class Variable extends Declaration, @variable {
187187
* `for (char c : str) { ... }`
188188
*/
189189
predicate isCompilerGenerated() { compgenerated(underlyingElement(this)) }
190+
191+
/** Holds if this variable is a template specialization. */
192+
predicate isSpecialization() {
193+
exists(VariableDeclarationEntry vde |
194+
var_decls(unresolveElement(vde), underlyingElement(this), _, _, _) and
195+
vde.isSpecialization()
196+
)
197+
}
190198
}
191199

192200
/**
@@ -267,6 +275,9 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
267275
override predicate isDefinition() { var_def(underlyingElement(this)) }
268276

269277
override string getASpecifier() { var_decl_specifiers(underlyingElement(this), result) }
278+
279+
/** Holds if this declaration is a template specialization. */
280+
predicate isSpecialization() { var_specialized(underlyingElement(this)) }
270281
}
271282

272283
/**
@@ -594,7 +605,10 @@ class TemplateVariable extends Variable {
594605
/**
595606
* Gets an instantiation of this variable template.
596607
*/
597-
Variable getAnInstantiation() { result.isConstructedFrom(this) }
608+
Variable getAnInstantiation() {
609+
result.isConstructedFrom(this) and
610+
not result.isSpecialization()
611+
}
598612
}
599613

600614
/**
@@ -624,6 +638,21 @@ class VariableTemplateInstantiation extends Variable {
624638
TemplateVariable getTemplate() { result = tv }
625639
}
626640

641+
/**
642+
* An explicit specialization of a C++ variable template.
643+
*/
644+
class VariableTemplateSpecialization extends Variable {
645+
VariableTemplateSpecialization() { this.isSpecialization() }
646+
647+
override string getAPrimaryQlClass() { result = "VariableTemplateSpecialization" }
648+
649+
/**
650+
* Gets the primary template for the specialization (the function template
651+
* this specializes).
652+
*/
653+
TemplateVariable getPrimaryTemplate() { this.isConstructedFrom(result) }
654+
}
655+
627656
/**
628657
* A non-static local variable or parameter that is not part of an
629658
* uninstantiated template. Uninstantiated templates are purely syntax, and

cpp/ql/lib/semmlecode.cpp.dbscheme

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ var_decls(
495495
int location: @location_default ref
496496
);
497497
var_def(unique int id: @var_decl ref);
498+
var_specialized(int id: @var_decl ref);
498499
var_decl_specifiers(
499500
int id: @var_decl ref,
500501
string name: string ref

0 commit comments

Comments
 (0)