[clang] [Clang] Fix AST dump for {CXXDefaultArgExpr, CXXDefaultInitExpr} (PR #88269)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 10 06:50:28 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: None (yronglin)
<details>
<summary>Changes</summary>
This PR fix a AST dump issue since https://github.com/llvm/llvm-project/pull/80001
When Clang dumps `CXXDefaultArgExpr`/`CXXDefaultInitExpr`, there has no recursively dump the complete `CXXDefaultArgExpr`/`CXXDefaultInitExpr`.
Since this PR, Clang will recursively dump a `CXXDefaultArgExpr`/`CXXDefaultInitExpr` node, even if the node has no rewritten init.
*Consider*:
*Before*:
```
`-FunctionDecl <line:9:1, line:11:1> line:9:6 test 'void ()'
`-CompoundStmt <col:13, line:11:1>
`-DeclStmt <line:10:3, col:8>
`-VarDecl <col:3, col:7> col:5 b 'B' listinit
`-InitListExpr <col:6, col:7> 'B'
`-CXXDefaultInitExpr <col:7> 'const A' lvalue has rewritten init
`-ExprWithCleanups <line:6:16, col:21> 'const A' lvalue
```
*After*:
```
`-FunctionDecl 0x15a9455a8 <line:9:1, line:11:1> line:9:6 test 'void ()'
`-CompoundStmt 0x15a945850 <col:13, line:11:1>
`-DeclStmt 0x15a945838 <line:10:3, col:8>
`-VarDecl 0x15a945708 <col:3, col:7> col:5 b 'B' listinit
`-InitListExpr 0x15a9457b0 <col:6, col:7> 'B'
`-CXXDefaultInitExpr 0x15a9457f8 <col:7> 'const A' lvalue has rewritten init
`-ExprWithCleanups 0x15a945568 <line:6:16, col:21> 'const A' lvalue
`-MaterializeTemporaryExpr 0x15a945500 <col:16, col:21> 'const A' lvalue extended by Field 0x15a945160 'a' 'const A &'
`-ImplicitCastExpr 0x15a9454e8 <col:16, col:21> 'const A' <NoOp>
`-CXXFunctionalCastExpr 0x15a9454c0 <col:16, col:21> 'A' functional cast to A <NoOp>
`-InitListExpr 0x15a9452c0 <col:17, col:21> 'A'
`-InitListExpr 0x15a945308 <col:18, col:20> 'int[1]'
`-IntegerLiteral 0x15a945210 <col:19> 'int' 0
```
---
Full diff: https://github.com/llvm/llvm-project/pull/88269.diff
5 Files Affected:
- (modified) clang/include/clang/AST/ASTNodeTraverser.h (+8)
- (modified) clang/lib/AST/TextNodeDumper.cpp (+2-12)
- (added) clang/test/AST/ast-dump-default-init.cpp (+24)
- (modified) clang/test/AST/ast-dump-for-range-lifetime.cpp (+21)
- (modified) clang/unittests/AST/ASTTraverserTest.cpp (+8)
``````````diff
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index 94e7dd817809dd..a6e3b05b005968 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -932,6 +932,14 @@ class ASTNodeTraverser
Visit(TArg);
}
+ void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node) {
+ Visit(Node->getExpr());
+ }
+
+ void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) {
+ Visit(Node->getExpr());
+ }
+
// Implements Visit methods for Attrs.
#include "clang/AST/AttrNodeTraverse.inc"
};
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 431f5d8bdb2b5f..830d3ff0faebd4 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1439,23 +1439,13 @@ void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) {
}
void TextNodeDumper::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node) {
- if (Node->hasRewrittenInit()) {
+ if (Node->hasRewrittenInit())
OS << " has rewritten init";
- AddChild([=] {
- ColorScope Color(OS, ShowColors, StmtColor);
- Visit(Node->getExpr());
- });
- }
}
void TextNodeDumper::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) {
- if (Node->hasRewrittenInit()) {
+ if (Node->hasRewrittenInit())
OS << " has rewritten init";
- AddChild([=] {
- ColorScope Color(OS, ShowColors, StmtColor);
- Visit(Node->getExpr());
- });
- }
}
void TextNodeDumper::VisitMaterializeTemporaryExpr(
diff --git a/clang/test/AST/ast-dump-default-init.cpp b/clang/test/AST/ast-dump-default-init.cpp
new file mode 100644
index 00000000000000..a2ce4ba57aa968
--- /dev/null
+++ b/clang/test/AST/ast-dump-default-init.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -ast-dump %s | FileCheck %s
+
+// CXXDefaultArgExpr should inherit dependence from the inner Expr, in this case
+// RecoveryExpr.
+
+struct A {
+ int arr[1];
+};
+
+struct B {
+ const A &a = A{{0}};
+};
+
+void test() {
+ B b{};
+}
+// CHECK: -CXXDefaultInitExpr 0x{{[^ ]*}} <{{.*}}> 'const A' lvalue has rewritten init
+// CHECK-NEXT: `-ExprWithCleanups 0x{{[^ ]*}} <{{.*}}> 'const A' lvalue
+// CHECK-NEXT: `-MaterializeTemporaryExpr 0x{{[^ ]*}} <{{.*}}> 'const A' lvalue extended by Var 0x{{[^ ]*}} 'b' 'B'
+// CHECK-NEXT: `-ImplicitCastExpr 0x{{[^ ]*}} <{{.*}}> 'const A' <NoOp>
+// CHECK-NEXT: `-CXXFunctionalCastExpr 0x{{[^ ]*}} <{{.*}}> 'A' functional cast to A <NoOp>
+// CHECK-NEXT: `-InitListExpr 0x{{[^ ]*}} <{{.*}}> 'A'
+// CHECK-NEXT: `-InitListExpr 0x{{[^ ]*}} <{{.*}}> 'int[1]'
+// CHECK-NEXT: `-IntegerLiteral 0x{{[^ ]*}} <{{.*}}> 'int' 0
diff --git a/clang/test/AST/ast-dump-for-range-lifetime.cpp b/clang/test/AST/ast-dump-for-range-lifetime.cpp
index 88b838268be2e0..0e92b6990ed504 100644
--- a/clang/test/AST/ast-dump-for-range-lifetime.cpp
+++ b/clang/test/AST/ast-dump-for-range-lifetime.cpp
@@ -132,6 +132,9 @@ void test4() {
// CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'int (&(const A &))[3]' lvalue Function {{.*}} 'default_arg_fn' 'int (&(const A &))[3]'
// CHECK-NEXT: | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const A':'const P2718R0::A' lvalue has rewritten init
// CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const A':'const P2718R0::A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A':'const P2718R0::A' <NoOp>
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'A':'P2718R0::A' 'void ()'
for (auto e : default_arg_fn())
bar(e);
}
@@ -179,10 +182,19 @@ void test5() {
// CHECK-NEXT: | | | | `-CXXTemporaryObjectExpr {{.*}} 'A':'P2718R0::A' 'void ()'
// CHECK-NEXT: | | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA':'const P2718R0::DefaultA' lvalue has rewritten init
// CHECK-NEXT: | | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' <NoOp>
+ // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' 'void ()'
// CHECK-NEXT: | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA':'const P2718R0::DefaultA' lvalue has rewritten init
// CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' <NoOp>
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' 'void ()'
// CHECK-NEXT: | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA':'const P2718R0::DefaultA' lvalue has rewritten init
// CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' <NoOp>
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' 'void ()'
for (auto e : default_arg_fn(foo(foo(foo(A())))))
bar(e);
}
@@ -219,10 +231,19 @@ void test6() {
// CHECK-NEXT: | | | | `-CXXTemporaryObjectExpr {{.*}} 'C':'P2718R0::C' 'void ()'
// CHECK-NEXT: | | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA':'const P2718R0::DefaultA' lvalue has rewritten init
// CHECK-NEXT: | | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' lvalue extended by Var {{.*}} '__range1' 'C &&'
+ // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' <NoOp>
+ // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' 'void ()'
// CHECK-NEXT: | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA':'const P2718R0::DefaultA' lvalue has rewritten init
// CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' lvalue extended by Var {{.*}} '__range1' 'C &&'
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' <NoOp>
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' 'void ()'
// CHECK-NEXT: | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA':'const P2718R0::DefaultA' lvalue has rewritten init
// CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' lvalue extended by Var {{.*}} '__range1' 'C &&'
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' <NoOp>
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' 'void ()'
for (auto e : C(0, C(0, C(0, C()))))
bar(e);
}
diff --git a/clang/unittests/AST/ASTTraverserTest.cpp b/clang/unittests/AST/ASTTraverserTest.cpp
index 362f37655a0ae4..8b6e3e90c0ea67 100644
--- a/clang/unittests/AST/ASTTraverserTest.cpp
+++ b/clang/unittests/AST/ASTTraverserTest.cpp
@@ -368,6 +368,8 @@ FunctionDecl 'stringConstruct'
| |-ImplicitCastExpr
| | `-StringLiteral
| `-CXXDefaultArgExpr
+ | `-UnaryOperator
+ | `-IntegerLiteral
`-ExprWithCleanups
`-CXXOperatorCallExpr
|-ImplicitCastExpr
@@ -378,6 +380,8 @@ FunctionDecl 'stringConstruct'
|-ImplicitCastExpr
| `-StringLiteral
`-CXXDefaultArgExpr
+ `-UnaryOperator
+ `-IntegerLiteral
)cpp");
EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource,
@@ -415,6 +419,8 @@ FunctionDecl 'overloadCall'
| |-ImplicitCastExpr
| | `-StringLiteral
| `-CXXDefaultArgExpr
+ | `-UnaryOperator
+ | `-IntegerLiteral
`-CXXMemberCallExpr
`-MemberExpr
`-ParenExpr
@@ -1219,6 +1225,7 @@ CXXRecordDecl 'Record'
| | `-IntegerLiteral
| |-CXXCtorInitializer 'm_i2'
| | `-CXXDefaultInitExpr
+| | `-IntegerLiteral
| |-CXXCtorInitializer 'm_s'
| | `-CXXConstructExpr
| `-CompoundStmt
@@ -1485,6 +1492,7 @@ CallExpr
| `-DeclRefExpr 'hasDefaultArg'
|-IntegerLiteral
`-CXXDefaultArgExpr
+ `-IntegerLiteral
)cpp");
EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource,
BN[0].getNodeAs<CallExpr>("funcCall")),
``````````
</details>
https://github.com/llvm/llvm-project/pull/88269
More information about the cfe-commits
mailing list