11/**
22 * Provides queries to pretty-print a C++ AST as a graph.
33 *
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.
77 */
88
99import cpp
@@ -22,16 +22,15 @@ class PrintAstConfiguration extends TPrintAstConfiguration {
2222
2323 /**
2424 * 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.
2627 */
2728 predicate shouldPrintDeclaration ( Declaration decl ) { any ( ) }
2829}
2930
3031private 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 )
3534}
3635
3736bindingset [ s]
@@ -72,7 +71,7 @@ private predicate locationSortKeys(Locatable ast, string file, int line, int col
7271 )
7372}
7473
75- private Function getEnclosingFunction ( Locatable ast ) {
74+ private Declaration getEnclosingDeclaration ( Locatable ast ) {
7675 result = ast .( Expr ) .getEnclosingFunction ( )
7776 or
7877 result = ast .( Stmt ) .getEnclosingFunction ( )
@@ -81,6 +80,10 @@ private Function getEnclosingFunction(Locatable ast) {
8180 or
8281 result = ast .( Parameter ) .getFunction ( )
8382 or
83+ result = ast .( Expr ) .getEnclosingDeclaration ( )
84+ or
85+ result = ast .( Initializer ) .getDeclaration ( )
86+ or
8487 result = ast
8588}
8689
@@ -89,7 +92,7 @@ private Function getEnclosingFunction(Locatable ast) {
8992 * nodes for things like parameter lists and constructor init lists.
9093 */
9194private newtype TPrintAstNode =
92- TAstNode ( Locatable ast ) { shouldPrintDeclaration ( getEnclosingFunction ( ast ) ) } or
95+ TAstNode ( Locatable ast ) { shouldPrintDeclaration ( getEnclosingDeclaration ( ast ) ) } or
9396 TDeclarationEntryNode ( DeclStmt stmt , DeclarationEntry entry ) {
9497 // We create a unique node for each pair of (stmt, entry), to avoid having one node with
9598 // multiple parents due to extractor bug CPP-413.
@@ -161,10 +164,10 @@ class PrintAstNode extends TPrintAstNode {
161164
162165 /**
163166 * 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.
166169 */
167- final predicate shouldPrint ( ) { shouldPrintDeclaration ( this .getEnclosingFunction ( ) ) }
170+ final predicate shouldPrint ( ) { shouldPrintDeclaration ( this .getEnclosingDeclaration ( ) ) }
168171
169172 /**
170173 * Gets the children of this node.
@@ -232,10 +235,15 @@ class PrintAstNode extends TPrintAstNode {
232235 abstract string getChildAccessorPredicateInternal ( int childIndex ) ;
233236
234237 /**
235- * Gets the `Function ` that contains this node.
238+ * Gets the `Declaration ` that contains this node.
236239 */
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 )
239247 }
240248}
241249
@@ -574,16 +582,53 @@ class DestructorDestructionsNode extends PrintAstNode, TDestructorDestructionsNo
574582 final Destructor getDestructor ( ) { result = dtor }
575583}
576584
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+
577624/**
578625 * A node representing a `Function`.
579626 */
580- class FunctionNode extends AstNode {
627+ class FunctionNode extends FunctionOrGlobalOrNamespaceVariableNode {
581628 Function func ;
582629
583630 FunctionNode ( ) { func = ast }
584631
585- override string toString ( ) { result = qlClass ( func ) + getIdentityString ( func ) }
586-
587632 override PrintAstNode getChildInternal ( int childIndex ) {
588633 childIndex = 0 and
589634 result .( ParametersNode ) .getFunction ( ) = func
@@ -607,31 +652,10 @@ class FunctionNode extends AstNode {
607652 or
608653 childIndex = 3 and result = "<destructions>"
609654 }
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 }
631655}
632656
633657private string getChildAccessorWithoutConversions ( Locatable parent , Element child ) {
634- shouldPrintDeclaration ( getEnclosingFunction ( parent ) ) and
658+ shouldPrintDeclaration ( getEnclosingDeclaration ( parent ) ) and
635659 (
636660 exists ( Stmt s | s = parent |
637661 namedStmtChildPredicates ( s , child , result )
@@ -650,7 +674,7 @@ private string getChildAccessorWithoutConversions(Locatable parent, Element chil
650674}
651675
652676private predicate namedStmtChildPredicates ( Locatable s , Element e , string pred ) {
653- shouldPrintDeclaration ( getEnclosingFunction ( s ) ) and
677+ shouldPrintDeclaration ( getEnclosingDeclaration ( s ) ) and
654678 (
655679 exists ( int n | s .( BlockStmt ) .getStmt ( n ) = e and pred = "getStmt(" + n + ")" )
656680 or
@@ -738,7 +762,7 @@ private predicate namedStmtChildPredicates(Locatable s, Element e, string pred)
738762}
739763
740764private predicate namedExprChildPredicates ( Expr expr , Element ele , string pred ) {
741- shouldPrintDeclaration ( expr .getEnclosingFunction ( ) ) and
765+ shouldPrintDeclaration ( expr .getEnclosingDeclaration ( ) ) and
742766 (
743767 expr .( Access ) .getTarget ( ) = ele and pred = "getTarget()"
744768 or
0 commit comments