From 033f35fe420ba437789e00bf64a3270c9999f5c8 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 25 Dec 2024 16:10:29 +0100 Subject: [PATCH] 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. --- cpp/ql/lib/semmle/code/cpp/PrintAST.qll | 87 +++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll index 492788202b4..7636f137259 100644 --- a/cpp/ql/lib/semmle/code/cpp/PrintAST.qll +++ b/cpp/ql/lib/semmle/code/cpp/PrintAST.qll @@ -88,6 +88,10 @@ private Declaration getAnEnclosingDeclaration(Locatable ast) { or result = ast.(Initializer).getDeclaration() or + exists(ConceptIdExpr concept | ast = concept.getATemplateArgument() | + result = concept.getEnclosingFunction() + ) + or result = ast } @@ -107,6 +111,12 @@ private newtype TPrintAstNode = TRequiresExprParametersNode(RequiresExpr req) { shouldPrintDeclaration(getAnEnclosingDeclaration(req)) } or + TConceptIdExprArgumentsNode(ConceptIdExpr concept) { + shouldPrintDeclaration(getAnEnclosingDeclaration(concept)) + } or + TConceptIdExprTypeArgumentNode(Type type, ConceptIdExpr concept, int childIndex) { + type = concept.getTemplateArgument(childIndex) + } or TConstructorInitializersNode(Constructor ctor) { ctor.hasEntryPoint() and shouldPrintDeclaration(ctor) @@ -357,6 +367,26 @@ class StringLiteralNode extends ExprNode { override string getValue() { result = "\"" + escapeString(expr.getValue()) + "\"" } } +/** + * A node representing a `ConceptIdExpr`. + */ +class ConceptIdExprNode extends ExprNode { + override ConceptIdExpr expr; + + override PrintAstNode getChildInternal(int childIndex) { + result = super.getChildInternal(childIndex) + or + childIndex = -1 and + result.(ConceptIdExprArgumentsNode).getConceptIdExpr() = expr + } + + override string getChildAccessorPredicateInternal(int childIndex) { + result = super.getChildAccessorPredicateInternal(childIndex) + or + childIndex = -1 and result = "" + } +} + /** * A node representing a `Conversion`. */ @@ -593,6 +623,63 @@ class InitializerNode extends AstNode { } } +/** + * A node representing the arguments of a `ConceptIdExpr`. + */ +class ConceptIdExprArgumentsNode extends PrintAstNode, TConceptIdExprArgumentsNode { + ConceptIdExpr concept; + + ConceptIdExprArgumentsNode() { this = TConceptIdExprArgumentsNode(concept) } + + final override string toString() { result = "" } + + final override Location getLocation() { result = getRepresentativeLocation(concept) } + + override PrintAstNode getChildInternal(int childIndex) { + exists(Locatable arg | arg = concept.getTemplateArgument(childIndex) | + result.(ConceptIdExprTypeArgumentNode).isArgumentNode(arg, concept, childIndex) + or + result.(ExprNode).getAst() = arg + ) + } + + override string getChildAccessorPredicateInternal(int childIndex) { + exists(this.getChildInternal(childIndex)) and + result = "getTemplateArgument(" + childIndex.toString() + ")" + } + + /** + * Gets the `ConceptIdExpr` for which this node represents the parameters. + */ + final ConceptIdExpr getConceptIdExpr() { result = concept } +} + +/** + * A node representing a type argument of a `ConceptIdExpr`. + */ +class ConceptIdExprTypeArgumentNode extends PrintAstNode, TConceptIdExprTypeArgumentNode { + Type type; + ConceptIdExpr concept; + int index; + + ConceptIdExprTypeArgumentNode() { this = TConceptIdExprTypeArgumentNode(type, concept, index) } + + final override string toString() { result = qlClass(type) + type.toString() } + + final override Location getLocation() { result = getRepresentativeLocation(type) } + + override AstNode getChildInternal(int childIndex) { none() } + + override string getChildAccessorPredicateInternal(int childIndex) { none() } + + /** + * Holds if `t` is the `i`th template argument of `c`. + */ + predicate isArgumentNode(Type t, ConceptIdExpr c, int i) { + type = t and concept = c and index = i + } +} + /** * A node representing the parameters of a `Function`. */