Skip to content

Commit 033f35f

Browse files
committed
C++: Improve PrintAST for concept ids
If a type would be used in multiple places in the AST, rendering of the AST would be broken. Hence, we cannot directly use types as AST nodes.
1 parent f8458f6 commit 033f35f

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

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

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ private Declaration getAnEnclosingDeclaration(Locatable ast) {
8888
or
8989
result = ast.(Initializer).getDeclaration()
9090
or
91+
exists(ConceptIdExpr concept | ast = concept.getATemplateArgument() |
92+
result = concept.getEnclosingFunction()
93+
)
94+
or
9195
result = ast
9296
}
9397

@@ -107,6 +111,12 @@ private newtype TPrintAstNode =
107111
TRequiresExprParametersNode(RequiresExpr req) {
108112
shouldPrintDeclaration(getAnEnclosingDeclaration(req))
109113
} or
114+
TConceptIdExprArgumentsNode(ConceptIdExpr concept) {
115+
shouldPrintDeclaration(getAnEnclosingDeclaration(concept))
116+
} or
117+
TConceptIdExprTypeArgumentNode(Type type, ConceptIdExpr concept, int childIndex) {
118+
type = concept.getTemplateArgument(childIndex)
119+
} or
110120
TConstructorInitializersNode(Constructor ctor) {
111121
ctor.hasEntryPoint() and
112122
shouldPrintDeclaration(ctor)
@@ -357,6 +367,26 @@ class StringLiteralNode extends ExprNode {
357367
override string getValue() { result = "\"" + escapeString(expr.getValue()) + "\"" }
358368
}
359369

370+
/**
371+
* A node representing a `ConceptIdExpr`.
372+
*/
373+
class ConceptIdExprNode extends ExprNode {
374+
override ConceptIdExpr expr;
375+
376+
override PrintAstNode getChildInternal(int childIndex) {
377+
result = super.getChildInternal(childIndex)
378+
or
379+
childIndex = -1 and
380+
result.(ConceptIdExprArgumentsNode).getConceptIdExpr() = expr
381+
}
382+
383+
override string getChildAccessorPredicateInternal(int childIndex) {
384+
result = super.getChildAccessorPredicateInternal(childIndex)
385+
or
386+
childIndex = -1 and result = "<args>"
387+
}
388+
}
389+
360390
/**
361391
* A node representing a `Conversion`.
362392
*/
@@ -593,6 +623,63 @@ class InitializerNode extends AstNode {
593623
}
594624
}
595625

626+
/**
627+
* A node representing the arguments of a `ConceptIdExpr`.
628+
*/
629+
class ConceptIdExprArgumentsNode extends PrintAstNode, TConceptIdExprArgumentsNode {
630+
ConceptIdExpr concept;
631+
632+
ConceptIdExprArgumentsNode() { this = TConceptIdExprArgumentsNode(concept) }
633+
634+
final override string toString() { result = "" }
635+
636+
final override Location getLocation() { result = getRepresentativeLocation(concept) }
637+
638+
override PrintAstNode getChildInternal(int childIndex) {
639+
exists(Locatable arg | arg = concept.getTemplateArgument(childIndex) |
640+
result.(ConceptIdExprTypeArgumentNode).isArgumentNode(arg, concept, childIndex)
641+
or
642+
result.(ExprNode).getAst() = arg
643+
)
644+
}
645+
646+
override string getChildAccessorPredicateInternal(int childIndex) {
647+
exists(this.getChildInternal(childIndex)) and
648+
result = "getTemplateArgument(" + childIndex.toString() + ")"
649+
}
650+
651+
/**
652+
* Gets the `ConceptIdExpr` for which this node represents the parameters.
653+
*/
654+
final ConceptIdExpr getConceptIdExpr() { result = concept }
655+
}
656+
657+
/**
658+
* A node representing a type argument of a `ConceptIdExpr`.
659+
*/
660+
class ConceptIdExprTypeArgumentNode extends PrintAstNode, TConceptIdExprTypeArgumentNode {
661+
Type type;
662+
ConceptIdExpr concept;
663+
int index;
664+
665+
ConceptIdExprTypeArgumentNode() { this = TConceptIdExprTypeArgumentNode(type, concept, index) }
666+
667+
final override string toString() { result = qlClass(type) + type.toString() }
668+
669+
final override Location getLocation() { result = getRepresentativeLocation(type) }
670+
671+
override AstNode getChildInternal(int childIndex) { none() }
672+
673+
override string getChildAccessorPredicateInternal(int childIndex) { none() }
674+
675+
/**
676+
* Holds if `t` is the `i`th template argument of `c`.
677+
*/
678+
predicate isArgumentNode(Type t, ConceptIdExpr c, int i) {
679+
type = t and concept = c and index = i
680+
}
681+
}
682+
596683
/**
597684
* A node representing the parameters of a `Function`.
598685
*/

0 commit comments

Comments
 (0)