1
1
/**
2
2
* Provides queries to pretty-print a C++ AST as a graph.
3
3
*
4
- * By default, this will print the AST for all functions in the database. To change this behavior,
5
- * extend `PrintASTConfiguration` and override `shouldPrintDeclaration` to hold for only the
6
- * declarations you wish to view the AST for.
4
+ * By default, this will print the AST for all functions and global and namespace variables in
5
+ * the database. To change this behavior, extend `PrintASTConfiguration` and override
6
+ * `shouldPrintDeclaration` to hold for only the declarations you wish to view the AST for.
7
7
*/
8
8
9
9
import cpp
@@ -22,16 +22,15 @@ class PrintAstConfiguration extends TPrintAstConfiguration {
22
22
23
23
/**
24
24
* Holds if the AST for `decl` should be printed. By default, holds for all
25
- * functions. Currently, does not support any other declaration types.
25
+ * functions and global and namespace variables. Currently, does not support any
26
+ * other declaration types.
26
27
*/
27
28
predicate shouldPrintDeclaration ( Declaration decl ) { any ( ) }
28
29
}
29
30
30
31
private predicate shouldPrintDeclaration ( Declaration decl ) {
31
- exists ( PrintAstConfiguration config |
32
- config .shouldPrintDeclaration ( decl ) and
33
- decl instanceof Function
34
- )
32
+ exists ( PrintAstConfiguration config | config .shouldPrintDeclaration ( decl ) ) and
33
+ ( decl instanceof Function or decl instanceof GlobalOrNamespaceVariable )
35
34
}
36
35
37
36
bindingset [ s]
@@ -72,7 +71,7 @@ private predicate locationSortKeys(Locatable ast, string file, int line, int col
72
71
)
73
72
}
74
73
75
- private Function getEnclosingFunction ( Locatable ast ) {
74
+ private Declaration getEnclosingDeclaration ( Locatable ast ) {
76
75
result = ast .( Expr ) .getEnclosingFunction ( )
77
76
or
78
77
result = ast .( Stmt ) .getEnclosingFunction ( )
@@ -81,6 +80,10 @@ private Function getEnclosingFunction(Locatable ast) {
81
80
or
82
81
result = ast .( Parameter ) .getFunction ( )
83
82
or
83
+ result = ast .( Expr ) .getEnclosingDeclaration ( )
84
+ or
85
+ result = ast .( Initializer ) .getDeclaration ( )
86
+ or
84
87
result = ast
85
88
}
86
89
@@ -89,7 +92,7 @@ private Function getEnclosingFunction(Locatable ast) {
89
92
* nodes for things like parameter lists and constructor init lists.
90
93
*/
91
94
private newtype TPrintAstNode =
92
- TAstNode ( Locatable ast ) { shouldPrintDeclaration ( getEnclosingFunction ( ast ) ) } or
95
+ TAstNode ( Locatable ast ) { shouldPrintDeclaration ( getEnclosingDeclaration ( ast ) ) } or
93
96
TDeclarationEntryNode ( DeclStmt stmt , DeclarationEntry entry ) {
94
97
// We create a unique node for each pair of (stmt, entry), to avoid having one node with
95
98
// multiple parents due to extractor bug CPP-413.
@@ -161,10 +164,10 @@ class PrintAstNode extends TPrintAstNode {
161
164
162
165
/**
163
166
* Holds if this node should be printed in the output. By default, all nodes
164
- * within a function are printed, but the query can override
165
- * `PrintASTConfiguration.shouldPrintDeclaration` to filter the output.
167
+ * within functions and global and namespace variables are printed, but the query
168
+ * can override `PrintASTConfiguration.shouldPrintDeclaration` to filter the output.
166
169
*/
167
- final predicate shouldPrint ( ) { shouldPrintDeclaration ( this .getEnclosingFunction ( ) ) }
170
+ final predicate shouldPrint ( ) { shouldPrintDeclaration ( this .getEnclosingDeclaration ( ) ) }
168
171
169
172
/**
170
173
* Gets the children of this node.
@@ -232,10 +235,15 @@ class PrintAstNode extends TPrintAstNode {
232
235
abstract string getChildAccessorPredicateInternal ( int childIndex ) ;
233
236
234
237
/**
235
- * Gets the `Function ` that contains this node.
238
+ * Gets the `Declaration ` that contains this node.
236
239
*/
237
- private Function getEnclosingFunction ( ) {
238
- result = this .getParent * ( ) .( FunctionNode ) .getFunction ( )
240
+ private Declaration getEnclosingDeclaration ( ) { result = this .getParent * ( ) .getDeclaration ( ) }
241
+
242
+ /**
243
+ * Gets the `Declaration` this node represents.
244
+ */
245
+ private Declaration getDeclaration ( ) {
246
+ result = this .( AstNode ) .getAst ( ) and shouldPrintDeclaration ( result )
239
247
}
240
248
}
241
249
@@ -574,16 +582,53 @@ class DestructorDestructionsNode extends PrintAstNode, TDestructorDestructionsNo
574
582
final Destructor getDestructor ( ) { result = dtor }
575
583
}
576
584
585
+ abstract private class FunctionOrGlobalOrNamespaceVariableNode extends AstNode {
586
+ override string toString ( ) { result = qlClass ( ast ) + getIdentityString ( ast ) }
587
+
588
+ private int getOrder ( ) {
589
+ this =
590
+ rank [ result ] ( FunctionOrGlobalOrNamespaceVariableNode node , Declaration decl , string file ,
591
+ int line , int column |
592
+ node .getAst ( ) = decl and
593
+ locationSortKeys ( decl , file , line , column )
594
+ |
595
+ node order by file , line , column , getIdentityString ( decl )
596
+ )
597
+ }
598
+
599
+ override string getProperty ( string key ) {
600
+ result = super .getProperty ( key )
601
+ or
602
+ key = "semmle.order" and result = this .getOrder ( ) .toString ( )
603
+ }
604
+ }
605
+
606
+ /**
607
+ * A node representing a `GlobalOrNamespaceVariable`.
608
+ */
609
+ class GlobalOrNamespaceVariableNode extends FunctionOrGlobalOrNamespaceVariableNode {
610
+ GlobalOrNamespaceVariable var ;
611
+
612
+ GlobalOrNamespaceVariableNode ( ) { var = ast }
613
+
614
+ override PrintAstNode getChildInternal ( int childIndex ) {
615
+ childIndex = 0 and
616
+ result .( AstNode ) .getAst ( ) = var .getInitializer ( )
617
+ }
618
+
619
+ override string getChildAccessorPredicateInternal ( int childIndex ) {
620
+ childIndex = 0 and result = "getInitializer()"
621
+ }
622
+ }
623
+
577
624
/**
578
625
* A node representing a `Function`.
579
626
*/
580
- class FunctionNode extends AstNode {
627
+ class FunctionNode extends FunctionOrGlobalOrNamespaceVariableNode {
581
628
Function func ;
582
629
583
630
FunctionNode ( ) { func = ast }
584
631
585
- override string toString ( ) { result = qlClass ( func ) + getIdentityString ( func ) }
586
-
587
632
override PrintAstNode getChildInternal ( int childIndex ) {
588
633
childIndex = 0 and
589
634
result .( ParametersNode ) .getFunction ( ) = func
@@ -607,31 +652,10 @@ class FunctionNode extends AstNode {
607
652
or
608
653
childIndex = 3 and result = "<destructions>"
609
654
}
610
-
611
- private int getOrder ( ) {
612
- this =
613
- rank [ result ] ( FunctionNode node , Function function , string file , int line , int column |
614
- node .getAst ( ) = function and
615
- locationSortKeys ( function , file , line , column )
616
- |
617
- node order by file , line , column , getIdentityString ( function )
618
- )
619
- }
620
-
621
- override string getProperty ( string key ) {
622
- result = super .getProperty ( key )
623
- or
624
- key = "semmle.order" and result = this .getOrder ( ) .toString ( )
625
- }
626
-
627
- /**
628
- * Gets the `Function` this node represents.
629
- */
630
- final Function getFunction ( ) { result = func }
631
655
}
632
656
633
657
private string getChildAccessorWithoutConversions ( Locatable parent , Element child ) {
634
- shouldPrintDeclaration ( getEnclosingFunction ( parent ) ) and
658
+ shouldPrintDeclaration ( getEnclosingDeclaration ( parent ) ) and
635
659
(
636
660
exists ( Stmt s | s = parent |
637
661
namedStmtChildPredicates ( s , child , result )
@@ -650,7 +674,7 @@ private string getChildAccessorWithoutConversions(Locatable parent, Element chil
650
674
}
651
675
652
676
private predicate namedStmtChildPredicates ( Locatable s , Element e , string pred ) {
653
- shouldPrintDeclaration ( getEnclosingFunction ( s ) ) and
677
+ shouldPrintDeclaration ( getEnclosingDeclaration ( s ) ) and
654
678
(
655
679
exists ( int n | s .( BlockStmt ) .getStmt ( n ) = e and pred = "getStmt(" + n + ")" )
656
680
or
@@ -738,7 +762,7 @@ private predicate namedStmtChildPredicates(Locatable s, Element e, string pred)
738
762
}
739
763
740
764
private predicate namedExprChildPredicates ( Expr expr , Element ele , string pred ) {
741
- shouldPrintDeclaration ( expr .getEnclosingFunction ( ) ) and
765
+ shouldPrintDeclaration ( expr .getEnclosingDeclaration ( ) ) and
742
766
(
743
767
expr .( Access ) .getTarget ( ) = ele and pred = "getTarget()"
744
768
or
0 commit comments