@@ -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
0 commit comments