riccibruno created this revision. riccibruno added reviewers: aaron.ballman, steveire, ilya-biryukov, sammccall, martong. riccibruno added a project: clang. Herald added subscribers: cfe-commits, rnkovacs.
Currently `APValue`s are dumped as a single string. This becomes quickly completely unreadable since `APValue` is a tree-like structure. Even a simple example is not pretty: struct S { int arr[4]; float f; }; constexpr S s = { .arr = {1,2}, .f = 3.1415f }; // Struct fields: Array: Int: 1, Int: 2, 2 x Int: 0, Float: 3.141500e+00 With this patch this becomes: -Struct |-field: Array size=4 | |-elements: Int 1, Int 2 | `-filler: 2 x Int 0 `-field: Float 3.141500e+00 Additionally `APValue`s are currently only dumped as part of visiting a `ConstantExpr`. This patch also dump the value of the initializer (if any) of constexpr variable declarations: constexpr int foo(int a, int b) { return a + b - 42; } constexpr int a = 1, b = 2; constexpr int c = foo(a, b) > 0 ? foo(a, b) : foo(b, a); // VarDecl 0x62100008aec8 <col:3, col:57> col:17 c 'const int' constexpr cinit // |-value: Int -39 // `-ConditionalOperator 0x62100008b4d0 <col:21, col:57> 'int' // <snip> Do the above by moving the dump functions to `TextNodeDumper` which already has the machinery to display trees. The cases `APValue::LValue`, `APValue::MemberPointer` and `APValue::AddrLabelDiff` are left as they were before (unimplemented). We try to display multiple elements on the same line if they are considered to be "simple". This is to avoid wasting large amounts of vertical space in an example like: constexpr int arr[8] = {0,1,2,3,4,5,6,7}; // VarDecl 0x62100008bb78 <col:3, col:42> col:17 arr 'int const[8]' constexpr cinit // |-value: Array size=8 // | |-elements: Int 0, Int 1, Int 2, Int 3 // | `-elements: Int 4, Int 5, Int 6, Int 7 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D83183 Files: clang/include/clang/AST/APValue.h clang/include/clang/AST/ASTNodeTraverser.h clang/include/clang/AST/JSONNodeDumper.h clang/include/clang/AST/TextNodeDumper.h clang/lib/AST/APValue.cpp clang/lib/AST/ASTDumper.cpp clang/lib/AST/JSONNodeDumper.cpp clang/lib/AST/TextNodeDumper.cpp clang/test/AST/alignas_maybe_odr_cleanup.cpp clang/test/AST/ast-dump-APValue-anon-union.cpp clang/test/AST/ast-dump-APValue-arithmetic.cpp clang/test/AST/ast-dump-APValue-array.cpp clang/test/AST/ast-dump-APValue-struct.cpp clang/test/AST/ast-dump-APValue-todo.cpp clang/test/AST/ast-dump-APValue-union.cpp clang/test/AST/ast-dump-APValue-vector.cpp clang/test/AST/ast-dump-attr.cpp clang/test/AST/ast-dump-color.cpp clang/test/AST/ast-dump-constant-expr.cpp clang/test/AST/ast-dump-decl.cpp clang/test/AST/ast-dump-records.cpp clang/test/AST/ast-dump-stmt.cpp clang/test/AST/pr43983.cpp clang/test/Import/switch-stmt/test.cpp clang/test/Tooling/clang-check-ast-dump.cpp
Index: clang/test/Tooling/clang-check-ast-dump.cpp =================================================================== --- clang/test/Tooling/clang-check-ast-dump.cpp +++ clang/test/Tooling/clang-check-ast-dump.cpp @@ -33,6 +33,7 @@ // CHECK-ATTR-NEXT: FieldDecl{{.*}}n // CHECK-ATTR-NEXT: AlignedAttr // CHECK-ATTR-NEXT: ConstantExpr +// CHECK-ATTR-NEXT: value: Int 2 // CHECK-ATTR-NEXT: BinaryOperator // // RUN: clang-check -ast-dump -ast-dump-filter test_namespace::AfterNullNode "%s" -- 2>&1 | FileCheck -check-prefix CHECK-AFTER-NULL %s Index: clang/test/Import/switch-stmt/test.cpp =================================================================== --- clang/test/Import/switch-stmt/test.cpp +++ clang/test/Import/switch-stmt/test.cpp @@ -5,20 +5,26 @@ // CHECK-NEXT: CompoundStmt // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 1 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 2 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 3 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 4 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 5 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 5 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt @@ -30,16 +36,20 @@ // CHECK-NEXT: CompoundStmt // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 1 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 2 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 3 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 5 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt Index: clang/test/AST/pr43983.cpp =================================================================== --- clang/test/AST/pr43983.cpp +++ clang/test/AST/pr43983.cpp @@ -9,6 +9,7 @@ struct B { _Alignas(64) struct { int b; }; }; -// CHECK: AlignedAttr {{.*}} _Alignas -// CHECK: ConstantExpr {{.*}} 64 -// CHECK: IntegerLiteral {{.*}} 64 +// CHECK: | `-AlignedAttr {{.*}} <col:12> _Alignas +// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:21> 'int' +// CHECK-NEXT: | |-value: Int 64 +// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:21> 'int' 64 Index: clang/test/AST/ast-dump-stmt.cpp =================================================================== --- clang/test/AST/ast-dump-stmt.cpp +++ clang/test/AST/ast-dump-stmt.cpp @@ -130,6 +130,7 @@ ; // CHECK: IfStmt 0x{{[^ ]*}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:5> // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <line:[[@LINE-3]]:17, col:30> 'bool' + // CHECK-NEXT: value: Int 1 // CHECK-NEXT: BinaryOperator // CHECK-NEXT: UnaryExprOrTypeTraitExpr // CHECK-NEXT: ParenExpr @@ -144,6 +145,7 @@ ; // CHECK: IfStmt 0x{{[^ ]*}} <line:[[@LINE-4]]:3, line:[[@LINE-1]]:5> has_else // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <line:[[@LINE-5]]:17, col:30> 'bool' + // CHECK-NEXT: value: Int 1 // CHECK-NEXT: BinaryOperator // CHECK-NEXT: UnaryExprOrTypeTraitExpr // CHECK-NEXT: ParenExpr Index: clang/test/AST/ast-dump-records.cpp =================================================================== --- clang/test/AST/ast-dump-records.cpp +++ clang/test/AST/ast-dump-records.cpp @@ -15,7 +15,7 @@ // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:8> col:8 referenced struct B struct A { - // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+29]]:1> line:[[@LINE-1]]:8 struct A definition + // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+32]]:1> line:[[@LINE-1]]:8 struct A definition // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param @@ -33,14 +33,17 @@ int d : 12; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 d 'int' // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int' + // CHECK-NEXT: value: Int 12 // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 12 int : 0; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> col:7 'int' // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:9> 'int' + // CHECK-NEXT: value: Int 0 // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:9> 'int' 0 int e : 10; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 e 'int' // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int' + // CHECK-NEXT: value: Int 10 // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 10 B *f; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:6> col:6 f 'B *' @@ -141,7 +144,7 @@ // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:7> col:7 union F union E { - // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+29]]:1> line:[[@LINE-1]]:7 union E definition + // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+32]]:1> line:[[@LINE-1]]:7 union E definition // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param @@ -159,14 +162,17 @@ int d : 12; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 d 'int' // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int' + // CHECK-NEXT: value: Int 12 // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 12 int : 0; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:9> col:7 'int' // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:9> 'int' + // CHECK-NEXT: value: Int 0 // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:9> 'int' 0 int e : 10; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:11> col:7 e 'int' // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} <col:11> 'int' + // CHECK-NEXT: value: Int 10 // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:11> 'int' 10 B *f; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:6> col:6 f 'B *' Index: clang/test/AST/ast-dump-decl.cpp =================================================================== --- clang/test/AST/ast-dump-decl.cpp +++ clang/test/AST/ast-dump-decl.cpp @@ -439,6 +439,7 @@ // CHECK-NEXT: |-NonTypeTemplateParmDecl 0x{{.+}} <col:12, col:20> col:16 'int' depth 0 index 0 I // CHECK-NEXT: | `-TemplateArgument expr // CHECK-NEXT: | `-ConstantExpr 0x{{.+}} <col:20> 'int' +// CHECK-NEXT: | |-value: Int 42 // CHECK-NEXT: | `-IntegerLiteral 0x{{.+}} <col:20> 'int' 42 // CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:24, col:31> col:31 struct TestTemplateDefaultNonType @@ -644,6 +645,7 @@ // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 0 I // CHECK-NEXT: TemplateArgument expr // CHECK-NEXT: ConstantExpr{{.*}} 'int' +// CHECK-NEXT: value: Int 1 // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 1 ... J Index: clang/test/AST/ast-dump-constant-expr.cpp =================================================================== --- clang/test/AST/ast-dump-constant-expr.cpp +++ clang/test/AST/ast-dump-constant-expr.cpp @@ -54,27 +54,32 @@ // CHECK-NEXT:FunctionDecl {{.*}} <{{.*}}ast-dump-constant-expr.cpp:42:1, line:52:1> line:42:6{{( imported)?}} Test 'void ()' // CHECK-NEXT:`-CompoundStmt {{.*}} <col:13, line:52:1> // CHECK-NEXT: |-CStyleCastExpr {{.*}} <line:43:3, col:19> 'void' <ToVoid> -// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:10, col:19> 'int' Int: 42 +// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:10, col:19> 'int' +// CHECK-NEXT: | |-value: Int 42 // CHECK-NEXT: | `-CallExpr {{.*}} <col:10, col:19> 'int' // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <col:10> 'int (*)()' <FunctionToPointerDecay> // CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:10> 'int ()' lvalue Function {{.*}} 'test_Int' 'int ()' // CHECK-NEXT: |-CStyleCastExpr {{.*}} <line:44:3, col:21> 'void' <ToVoid> -// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:10, col:21> 'float' Float: 1.000000e+00 +// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:10, col:21> 'float' +// CHECK-NEXT: | |-value: Float 1.000000e+00 // CHECK-NEXT: | `-CallExpr {{.*}} <col:10, col:21> 'float' // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <col:10> 'float (*)()' <FunctionToPointerDecay> // CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:10> 'float ()' lvalue Function {{.*}} 'test_Float' 'float ()' // CHECK-NEXT: |-CStyleCastExpr {{.*}} <line:45:3, col:26> 'void' <ToVoid> -// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:10, col:26> '_Complex int' ComplexInt: 1, 2 +// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:10, col:26> '_Complex int' +// CHECK-NEXT: | |-value: ComplexInt 1 + 2i // CHECK-NEXT: | `-CallExpr {{.*}} <col:10, col:26> '_Complex int' // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <col:10> '_Complex int (*)()' <FunctionToPointerDecay> // CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:10> '_Complex int ()' lvalue Function {{.*}} 'test_ComplexInt' '_Complex int ()' // CHECK-NEXT: |-CStyleCastExpr {{.*}} <line:46:3, col:28> 'void' <ToVoid> -// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:10, col:28> '_Complex float' ComplexFloat: 1.200000e+00, 3.400000e+00 +// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:10, col:28> '_Complex float' +// CHECK-NEXT: | |-value: ComplexFloat 1.200000e+00 + 3.400000e+00i // CHECK-NEXT: | `-CallExpr {{.*}} <col:10, col:28> '_Complex float' // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <col:10> '_Complex float (*)()' <FunctionToPointerDecay> // CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:10> '_Complex float ()' lvalue Function {{.*}} 'test_ComplexFloat' '_Complex float ()' // CHECK-NEXT: `-CStyleCastExpr {{.*}} <line:47:3, col:22> 'void' <ToVoid> -// CHECK-NEXT: `-ConstantExpr {{.*}} <col:10, col:22> '__int128' Int: 18446744073709551616 +// CHECK-NEXT: `-ConstantExpr {{.*}} <col:10, col:22> '__int128' +// CHECK-NEXT: |-value: Int 18446744073709551616 // CHECK-NEXT: `-CallExpr {{.*}} <col:10, col:22> '__int128' // CHECK-NEXT: `-ImplicitCastExpr {{.*}} <col:10> '__int128 (*)()' <FunctionToPointerDecay> // CHECK-NEXT: `-DeclRefExpr {{.*}} <col:10> '__int128 ()' lvalue Function {{.*}} 'test_Int128' '__int128 ()' Index: clang/test/AST/ast-dump-color.cpp =================================================================== --- clang/test/AST/ast-dump-color.cpp +++ clang/test/AST/ast-dump-color.cpp @@ -49,13 +49,15 @@ //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}} -//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] Int: 1[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | | |-value: [[RESET]][[Cyan]]Int [[CYAN]]1[[RESET]][[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | | | `-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]AttributedStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:12:5[[RESET]], [[Yellow]]col:27[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[BLUE]]FallThroughAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:7[[RESET]], [[Yellow]]col:14[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:3[[RESET]], [[Yellow]]line:14:5[[RESET]]>{{$}} -//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] Int: 2[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | |-value: [[RESET]][[Cyan]]Int [[CYAN]]2[[RESET]][[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:14:5[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}} Index: clang/test/AST/ast-dump-attr.cpp =================================================================== --- clang/test/AST/ast-dump-attr.cpp +++ clang/test/AST/ast-dump-attr.cpp @@ -45,6 +45,7 @@ // CHECK: VarDecl{{.*}}TestAlignedExpr // CHECK-NEXT: AlignedAttr {{.*}} aligned // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 4 // CHECK-NEXT: IntegerLiteral int TestEnum __attribute__((visibility("default"))); Index: clang/test/AST/ast-dump-APValue-vector.cpp =================================================================== --- /dev/null +++ clang/test/AST/ast-dump-APValue-vector.cpp @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +void Test() { + constexpr int __attribute__((vector_size(sizeof(int)*1))) v1i = {1}; +// CHECK: | `-VarDecl {{.*}} <col:2, col:68> col:60 v1i '__attribute__((__vector_size__(1 * sizeof(int)))) int const' constexpr cinit +// CHECK-NEXT: | |-value: Vector length=1 +// CHECK-NEXT: | | `-element: Int 1 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:66, col:68> '__attribute__((__vector_size__(1 * sizeof(int)))) int' +// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:67> 'int' 1 + constexpr int __attribute__((vector_size(sizeof(int)*4))) v4i = {1,2,3,4}; +// CHECK: | `-VarDecl {{.*}} <col:2, col:74> col:60 v4i '__attribute__((__vector_size__(4 * sizeof(int)))) int const' constexpr cinit +// CHECK-NEXT: | |-value: Vector length=4 +// CHECK-NEXT: | | `-elements: Int 1, Int 2, Int 3, Int 4 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:66, col:74> '__attribute__((__vector_size__(4 * sizeof(int)))) int' +// CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:67> 'int' 1 +// CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:69> 'int' 2 +// CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:71> 'int' 3 +// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:73> 'int' 4 + constexpr int __attribute__((vector_size(sizeof(int)*5))) v5i = {1,2,3,4}; +// CHECK: | `-VarDecl {{.*}} <col:2, col:74> col:60 v5i '__attribute__((__vector_size__(5 * sizeof(int)))) int const' constexpr cinit +// CHECK-NEXT: | |-value: Vector length=5 +// CHECK-NEXT: | | |-elements: Int 1, Int 2, Int 3, Int 4 +// CHECK-NEXT: | | `-element: Int 0 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:66, col:74> '__attribute__((__vector_size__(5 * sizeof(int)))) int' +// CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:67> 'int' 1 +// CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:69> 'int' 2 +// CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:71> 'int' 3 +// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:73> 'int' 4 + constexpr int __attribute__((vector_size(sizeof(int)*8))) v8i = {1,2,3,4}; +// CHECK: | `-VarDecl {{.*}} <col:2, col:74> col:60 v8i '__attribute__((__vector_size__(8 * sizeof(int)))) int const' constexpr cinit +// CHECK-NEXT: | |-value: Vector length=8 +// CHECK-NEXT: | | |-elements: Int 1, Int 2, Int 3, Int 4 +// CHECK-NEXT: | | `-elements: Int 0, Int 0, Int 0, Int 0 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:66, col:74> '__attribute__((__vector_size__(8 * sizeof(int)))) int' +// CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:67> 'int' 1 +// CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:69> 'int' 2 +// CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:71> 'int' 3 +// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:73> 'int' 4 + constexpr int __attribute__((vector_size(sizeof(int)*9))) v9i = {1,2,3,4}; +// CHECK: `-VarDecl {{.*}} <col:2, col:74> col:60 v9i '__attribute__((__vector_size__(9 * sizeof(int)))) int const' constexpr cinit +// CHECK-NEXT: |-value: Vector length=9 +// CHECK-NEXT: | |-elements: Int 1, Int 2, Int 3, Int 4 +// CHECK-NEXT: | |-elements: Int 0, Int 0, Int 0, Int 0 +// CHECK-NEXT: | `-element: Int 0 +// CHECK-NEXT: `-InitListExpr {{.*}} <col:66, col:74> '__attribute__((__vector_size__(9 * sizeof(int)))) int' +// CHECK-NEXT: |-IntegerLiteral {{.*}} <col:67> 'int' 1 +// CHECK-NEXT: |-IntegerLiteral {{.*}} <col:69> 'int' 2 +// CHECK-NEXT: |-IntegerLiteral {{.*}} <col:71> 'int' 3 +// CHECK-NEXT: `-IntegerLiteral {{.*}} <col:73> 'int' 4 +} Index: clang/test/AST/ast-dump-APValue-union.cpp =================================================================== --- /dev/null +++ clang/test/AST/ast-dump-APValue-union.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +union U0 { + int i = 42; + float f; +}; + +union U1 { + union Uinner { + int i; + float f = 3.1415f; + } uinner; +}; + +union U2 { + union Uinner { + double d; + int arr[2] = {1,2}; + } uinner; +}; + +union U3 { + union Uinner { + double d = 3.1415; + int arr[2]; + } uinner; + float f; +}; + +void Test() { + constexpr U0 u0{}; +// CHECK: | `-VarDecl {{.*}} <col:3, col:19> col:16 u0 'const U0' constexpr listinit +// CHECK-NEXT: | |-value: Union .i Int 42 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:18, col:19> 'const U0' field Field {{.*}} 'i' 'int' +// CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} <col:19> 'int' + constexpr U1 u1{}; +// CHECK: | `-VarDecl {{.*}} <col:3, col:19> col:16 u1 'const U1' constexpr listinit +// CHECK-NEXT: | |-value: Union .uinner Union .f Float 3.141500e+00 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:18, col:19> 'const U1' field Field {{.*}} 'uinner' 'union Uinner':'U1::Uinner' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19> 'union Uinner':'U1::Uinner' field Field {{.*}} 'f' 'float' +// CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} <col:19> 'float' + constexpr U2 u2{}; +// CHECK: | `-VarDecl {{.*}} <col:3, col:19> col:16 u2 'const U2' constexpr listinit +// CHECK-NEXT: | |-value: Union .uinner +// CHECK-NEXT: | | `-Union .arr +// CHECK-NEXT: | | `-Array size=2 +// CHECK-NEXT: | | `-elements: Int 1, Int 2 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:18, col:19> 'const U2' field Field {{.*}} 'uinner' 'union Uinner':'U2::Uinner' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19> 'union Uinner':'U2::Uinner' field Field {{.*}} 'arr' 'int [2]' +// CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} <col:19> 'int [2]' + constexpr U3 u3a = { .f = 3.1415 }; +// CHECK: | `-VarDecl {{.*}} <col:3, col:36> col:16 u3a 'const U3' constexpr cinit +// CHECK-NEXT: | |-value: Union .f Float 3.141500e+00 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:22, col:36> 'const U3' field Field {{.*}} 'f' 'float' +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <col:29> 'float' <FloatingCast> +// CHECK-NEXT: | `-FloatingLiteral {{.*}} <col:29> 'double' 3.141500e+00 + constexpr U3 u3b = { .uinner = {} }; +// CHECK: `-VarDecl {{.*}} <col:3, col:37> col:16 u3b 'const U3' constexpr cinit +// CHECK-NEXT: |-value: Union .uinner Union .d Float 3.141500e+00 +// CHECK-NEXT: `-InitListExpr {{.*}} <col:22, col:37> 'const U3' field Field {{.*}} 'uinner' 'union Uinner':'U3::Uinner' +// CHECK-NEXT: `-InitListExpr {{.*}} <col:34, col:35> 'union Uinner':'U3::Uinner' field Field {{.*}} 'd' 'double' +// CHECK-NEXT: `-CXXDefaultInitExpr {{.*}} <col:35> 'double' +} Index: clang/test/AST/ast-dump-APValue-todo.cpp =================================================================== --- /dev/null +++ clang/test/AST/ast-dump-APValue-todo.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +int i; +struct S { + int i; +}; + +void Test() { + constexpr int *pi = &i; +// CHECK: | `-VarDecl {{.*}} <col:2, col:23> col:17 pi 'int *const' constexpr cinit +// CHECK-NEXT: | |-value: LValue <todo> +// CHECK-NEXT: | `-UnaryOperator {{.*}} <col:22, col:23> 'int *' prefix '&' cannot overflow +// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int' + constexpr int (S::*pmi) = &S::i; +// CHECK: `-VarDecl {{.*}} <col:3, col:33> col:22 pmi 'int (S::*const)' constexpr cinit +// CHECK-NEXT: |-value: MemberPointer <todo> +// CHECK-NEXT: `-UnaryOperator {{.*}} <col:29, col:33> 'int S::*' prefix '&' cannot overflow +// CHECK-NEXT: `-DeclRefExpr {{.*}} <col:30, col:33> 'int' lvalue Field {{.*}} 'i' 'int' +} Index: clang/test/AST/ast-dump-APValue-struct.cpp =================================================================== --- /dev/null +++ clang/test/AST/ast-dump-APValue-struct.cpp @@ -0,0 +1,142 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +struct S0 { + int i=0; + union { + int j=0; + } u0; +}; + +struct S1 { + int i=0; + union { + struct { int j=0; } s; + } u1; +}; + +struct S2 { + int i=0; + union { + union { + int j=0; + } u; + } u2; +}; + +struct S3 { + int i=0; + union { + union { + struct { int j=0; } j; + } u; + } u3; +}; + +struct S4 : S0 { + int i=1,j=2,k=3; + struct {} s; + int a=4,b=5,c=6; +}; + +struct S5 : S4 { + int arr0[8] = {1,2,3,4}; + int arr1[8] = {1,2,3,4,0,0,0,0}; +}; + +void Test() { + constexpr S0 s0{}; +// CHECK: | `-VarDecl {{.*}} <col:3, col:19> col:16 s0 'const S0' constexpr listinit +// CHECK-NEXT: | |-value: Struct +// CHECK-NEXT: | | `-fields: Int 0, Union .j Int 0 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:18, col:19> 'const S0' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19> 'union (anonymous union at {{.*}}ast-dump-APValue-struct.cpp:7:3)':'S0::(anonymous union at {{.*}}ast-dump-APValue-struct.cpp:7:3)' field Field {{.*}} 'j' 'int' +// CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} <col:19> 'int' + constexpr S1 s1{}; +// CHECK: | `-VarDecl {{.*}} <col:3, col:19> col:16 s1 'const S1' constexpr listinit +// CHECK-NEXT: | |-value: Struct +// CHECK-NEXT: | | |-field: Int 0 +// CHECK-NEXT: | | `-field: Union .s +// CHECK-NEXT: | | `-Struct +// CHECK-NEXT: | | `-field: Int 0 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:18, col:19> 'const S1' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19> 'union (anonymous union at {{.*}}ast-dump-APValue-struct.cpp:14:3)':'S1::(anonymous union at {{.*}}ast-dump-APValue-struct.cpp:14:3)' field Field {{.*}} 's' 'struct (anonymous struct at {{.*}}ast-dump-APValue-struct.cpp:15:5)':'S1::(anonymous struct at {{.*}}ast-dump-APValue-struct.cpp:15:5)' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19> 'struct (anonymous struct at {{.*}}ast-dump-APValue-struct.cpp:15:5)':'S1::(anonymous struct at {{.*}}ast-dump-APValue-struct.cpp:15:5)' +// CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} <col:19> 'int' + constexpr S2 s2{}; +// CHECK: | `-VarDecl {{.*}} <col:3, col:19> col:16 s2 'const S2' constexpr listinit +// CHECK-NEXT: | |-value: Struct +// CHECK-NEXT: | | `-fields: Int 0, Union .u Union .j Int 0 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:18, col:19> 'const S2' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19> 'union (anonymous union at {{.*}}ast-dump-APValue-struct.cpp:21:3)':'S2::(anonymous union at {{.*}}ast-dump-APValue-struct.cpp:21:3)' field Field {{.*}} 'u' 'union (anonymous union at {{.*}}ast-dump-APValue-struct.cpp:22:5)':'S2::(anonymous union at {{.*}}ast-dump-APValue-struct.cpp:22:5)' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19> 'union (anonymous union at {{.*}}ast-dump-APValue-struct.cpp:22:5)':'S2::(anonymous union at {{.*}}ast-dump-APValue-struct.cpp:22:5)' field Field {{.*}} 'j' 'int' +// CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} <col:19> 'int' + constexpr S3 s3{}; +// CHECK: | `-VarDecl {{.*}} <col:3, col:19> col:16 s3 'const S3' constexpr listinit +// CHECK-NEXT: | |-value: Struct +// CHECK-NEXT: | | |-field: Int 0 +// CHECK-NEXT: | | `-field: Union .u +// CHECK-NEXT: | | `-Union .j +// CHECK-NEXT: | | `-Struct +// CHECK-NEXT: | | `-field: Int 0 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:18, col:19> 'const S3' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19> 'union (anonymous union at {{.*}}ast-dump-APValue-struct.cpp:30:3)':'S3::(anonymous union at {{.*}}ast-dump-APValue-struct.cpp:30:3)' field Field {{.*}} 'u' 'union (anonymous union at {{.*}}ast-dump-APValue-struct.cpp:31:5)':'S3::(anonymous union at {{.*}}ast-dump-APValue-struct.cpp:31:5)' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19> 'union (anonymous union at {{.*}}ast-dump-APValue-struct.cpp:31:5)':'S3::(anonymous union at {{.*}}ast-dump-APValue-struct.cpp:31:5)' field Field {{.*}} 'j' 'struct (anonymous struct at {{.*}}ast-dump-APValue-struct.cpp:32:7)':'S3::(anonymous struct at {{.*}}ast-dump-APValue-struct.cpp:32:7)' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19> 'struct (anonymous struct at {{.*}}ast-dump-APValue-struct.cpp:32:7)':'S3::(anonymous struct at {{.*}}ast-dump-APValue-struct.cpp:32:7)' +// CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} <col:19> 'int' + constexpr S4 s4{}; +// CHECK: | `-VarDecl {{.*}} <col:3, col:19> col:16 s4 'const S4' constexpr listinit +// CHECK-NEXT: | |-value: Struct +// CHECK-NEXT: | | |-base: Struct +// CHECK-NEXT: | | | `-fields: Int 0, Union .j Int 0 +// CHECK-NEXT: | | |-fields: Int 1, Int 2, Int 3 +// CHECK-NEXT: | | |-field: Struct +// CHECK-NEXT: | | `-fields: Int 4, Int 5, Int 6 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:18, col:19> 'const S4' +// CHECK-NEXT: | |-InitListExpr {{.*}} <col:19> 'S0' +// CHECK-NEXT: | | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | | `-InitListExpr {{.*}} <col:19> 'union (anonymous union at {{.*}}ast-dump-APValue-struct.cpp:7:3)':'S0::(anonymous union at {{.*}}ast-dump-APValue-struct.cpp:7:3)' field Field {{.*}} 'j' 'int' +// CHECK-NEXT: | | `-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | |-InitListExpr {{.*}} <col:19> 'struct (anonymous struct at {{.*}}ast-dump-APValue-struct.cpp:39:3)':'S4::(anonymous struct at {{.*}}ast-dump-APValue-struct.cpp:39:3)' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} <col:19> 'int' + constexpr S5 s5{}; +// CHECK: `-VarDecl {{.*}} <col:3, col:19> col:16 s5 'const S5' constexpr listinit +// CHECK-NEXT: |-value: Struct +// CHECK-NEXT: | |-base: Struct +// CHECK-NEXT: | | |-base: Struct +// CHECK-NEXT: | | | `-fields: Int 0, Union .j Int 0 +// CHECK-NEXT: | | |-fields: Int 1, Int 2, Int 3 +// CHECK-NEXT: | | |-field: Struct +// CHECK-NEXT: | | `-fields: Int 4, Int 5, Int 6 +// CHECK-NEXT: | |-field: Array size=8 +// CHECK-NEXT: | | |-elements: Int 1, Int 2, Int 3, Int 4 +// CHECK-NEXT: | | `-filler: 4 x Int 0 +// CHECK-NEXT: | `-field: Array size=8 +// CHECK-NEXT: | |-elements: Int 1, Int 2, Int 3, Int 4 +// CHECK-NEXT: | `-elements: Int 0, Int 0, Int 0, Int 0 +// CHECK-NEXT: `-InitListExpr {{.*}} <col:18, col:19> 'const S5' +// CHECK-NEXT: |-InitListExpr {{.*}} <col:19> 'S4' +// CHECK-NEXT: | |-InitListExpr {{.*}} <col:19> 'S0' +// CHECK-NEXT: | | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | | `-InitListExpr {{.*}} <col:19> 'union (anonymous union at {{.*}}ast-dump-APValue-struct.cpp:7:3)':'S0::(anonymous union at {{.*}}ast-dump-APValue-struct.cpp:7:3)' field Field {{.*}} 'j' 'int' +// CHECK-NEXT: | | `-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | |-InitListExpr {{.*}} <col:19> 'struct (anonymous struct at {{.*}}ast-dump-APValue-struct.cpp:39:3)':'S4::(anonymous struct at {{.*}}ast-dump-APValue-struct.cpp:39:3)' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | |-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} <col:19> 'int' +// CHECK-NEXT: |-CXXDefaultInitExpr {{.*}} <col:19> 'int [8]' +// CHECK-NEXT: `-CXXDefaultInitExpr {{.*}} <col:19> 'int [8]' +} Index: clang/test/AST/ast-dump-APValue-array.cpp =================================================================== --- /dev/null +++ clang/test/AST/ast-dump-APValue-array.cpp @@ -0,0 +1,106 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +struct S0 { int arr[2]; }; +union U0 { int i; float f; }; + +struct S1 { + S0 s0 = {1,2}; + U0 u0 = { .i = 42 }; +}; + +void Test() { + constexpr int __attribute__((vector_size(sizeof(int)*5))) arr_v5i[5] = { + {1,2,3,4,5}, {1,2,3,4}, + }; +// CHECK: | `-VarDecl {{.*}} <line:14:2, line:16:3> line:14:60 arr_v5i '__attribute__((__vector_size__(5 * sizeof(int)))) int const[5]' constexpr cinit +// CHECK-NEXT: | |-value: Array size=5 +// CHECK-NEXT: | | |-element: Vector length=5 +// CHECK-NEXT: | | | |-elements: Int 1, Int 2, Int 3, Int 4 +// CHECK-NEXT: | | | `-element: Int 5 +// CHECK-NEXT: | | |-element: Vector length=5 +// CHECK-NEXT: | | | |-elements: Int 1, Int 2, Int 3, Int 4 +// CHECK-NEXT: | | | `-element: Int 0 +// CHECK-NEXT: | | `-filler: 3 x Vector length=5 +// CHECK-NEXT: | | |-elements: Int 0, Int 0, Int 0, Int 0 +// CHECK-NEXT: | | `-element: Int 0 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:73, line:16:3> '__attribute__((__vector_size__(5 * sizeof(int)))) int const[5]' +// CHECK-NEXT: | |-array_filler: ImplicitValueInitExpr {{.*}} <<invalid sloc>> '__attribute__((__vector_size__(5 * sizeof(int)))) int const' +// CHECK-NEXT: | |-InitListExpr {{.*}} <line:15:5, col:15> '__attribute__((__vector_size__(5 * sizeof(int)))) int' +// CHECK-NEXT: | | |-IntegerLiteral {{.*}} <col:6> 'int' 1 +// CHECK-NEXT: | | |-IntegerLiteral {{.*}} <col:8> 'int' 2 +// CHECK-NEXT: | | |-IntegerLiteral {{.*}} <col:10> 'int' 3 +// CHECK-NEXT: | | |-IntegerLiteral {{.*}} <col:12> 'int' 4 +// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:14> 'int' 5 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:18, col:26> '__attribute__((__vector_size__(5 * sizeof(int)))) int' +// CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:19> 'int' 1 +// CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:21> 'int' 2 +// CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:23> 'int' 3 +// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:25> 'int' 4 + constexpr float arr_f[3][5] = { { 1,2,3,4,5 }, }; +// CHECK: | `-VarDecl {{.*}} <col:3, col:50> col:19 arr_f 'float const[3][5]' constexpr cinit +// CHECK-NEXT: | |-value: Array size=3 +// CHECK-NEXT: | | |-element: Array size=5 +// CHECK-NEXT: | | | |-elements: Float 1.000000e+00, Float 2.000000e+00, Float 3.000000e+00, Float 4.000000e+00 +// CHECK-NEXT: | | | `-element: Float 5.000000e+00 +// CHECK-NEXT: | | `-filler: 2 x Array size=5 +// CHECK-NEXT: | | `-filler: 5 x Float 0.000000e+00 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:33, col:50> 'float const[3][5]' +// CHECK-NEXT: | |-array_filler: ImplicitValueInitExpr {{.*}} <<invalid sloc>> 'float const[5]' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:35, col:47> 'float const[5]' +// CHECK-NEXT: | |-ImplicitCastExpr {{.*}} <col:37> 'const float' <IntegralToFloating> +// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:37> 'int' 1 +// CHECK-NEXT: | |-ImplicitCastExpr {{.*}} <col:39> 'const float' <IntegralToFloating> +// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:39> 'int' 2 +// CHECK-NEXT: | |-ImplicitCastExpr {{.*}} <col:41> 'const float' <IntegralToFloating> +// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:41> 'int' 3 +// CHECK-NEXT: | |-ImplicitCastExpr {{.*}} <col:43> 'const float' <IntegralToFloating> +// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:43> 'int' 4 +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <col:45> 'const float' <IntegralToFloating> +// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:45> 'int' 5 + constexpr S0 arr_s0[2] = { {1,2}, {3,4} }; +// CHECK: | `-VarDecl {{.*}} <col:3, col:43> col:16 arr_s0 'S0 const[2]' constexpr cinit +// CHECK-NEXT: | |-value: Array size=2 +// CHECK-NEXT: | | |-element: Struct +// CHECK-NEXT: | | | `-field: Array size=2 +// CHECK-NEXT: | | | `-elements: Int 1, Int 2 +// CHECK-NEXT: | | `-element: Struct +// CHECK-NEXT: | | `-field: Array size=2 +// CHECK-NEXT: | | `-elements: Int 3, Int 4 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:28, col:43> 'S0 const[2]' +// CHECK-NEXT: | |-InitListExpr {{.*}} <col:30, col:34> 'const S0' +// CHECK-NEXT: | | `-InitListExpr {{.*}} <col:31, col:33> 'int [2]' +// CHECK-NEXT: | | |-IntegerLiteral {{.*}} <col:31> 'int' 1 +// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:33> 'int' 2 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:37, col:41> 'const S0' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:38, col:40> 'int [2]' +// CHECK-NEXT: | |-IntegerLiteral {{.*}} <col:38> 'int' 3 +// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:40> 'int' 4 + constexpr U0 arr_u0[2] = { {.i = 42}, {.f = 3.1415f} }; +// CHECK: | `-VarDecl {{.*}} <col:3, col:56> col:16 arr_u0 'U0 const[2]' constexpr cinit +// CHECK-NEXT: | |-value: Array size=2 +// CHECK-NEXT: | | `-elements: Union .i Int 42, Union .f Float 3.141500e+00 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:28, col:56> 'U0 const[2]' +// CHECK-NEXT: | |-InitListExpr {{.*}} <col:30, col:38> 'const U0' field Field {{.*}} 'i' 'int' +// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:36> 'int' 42 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:41, col:54> 'const U0' field Field {{.*}} 'f' 'float' +// CHECK-NEXT: | `-FloatingLiteral {{.*}} <col:47> 'float' 3.141500e+00 + constexpr S1 arr_s1[2] = {}; +// CHECK: `-VarDecl {{.*}} <col:3, col:29> col:16 arr_s1 'S1 const[2]' constexpr cinit +// CHECK-NEXT: |-value: Array size=2 +// CHECK-NEXT: | |-element: Struct +// CHECK-NEXT: | | |-field: Struct +// CHECK-NEXT: | | | `-field: Array size=2 +// CHECK-NEXT: | | | `-elements: Int 1, Int 2 +// CHECK-NEXT: | | `-field: Union .i Int 42 +// CHECK-NEXT: | `-element: Struct +// CHECK-NEXT: | |-field: Struct +// CHECK-NEXT: | | `-field: Array size=2 +// CHECK-NEXT: | | `-elements: Int 1, Int 2 +// CHECK-NEXT: | `-field: Union .i Int 42 +// CHECK-NEXT: `-InitListExpr {{.*}} <col:28, col:29> 'S1 const[2]' +// CHECK-NEXT: `-array_filler: InitListExpr {{.*}} <col:29> 'const S1' +// CHECK-NEXT: |-CXXDefaultInitExpr {{.*}} <col:29> 'S0' +// CHECK-NEXT: `-CXXDefaultInitExpr {{.*}} <col:29> 'U0' +} Index: clang/test/AST/ast-dump-APValue-arithmetic.cpp =================================================================== --- /dev/null +++ clang/test/AST/ast-dump-APValue-arithmetic.cpp @@ -0,0 +1,71 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +void Test() { + constexpr int Int = 42; +// CHECK: | `-VarDecl {{.*}} <col:3, col:23> col:17 Int 'const int' constexpr cinit +// CHECK-NEXT: | |-value: Int 42 +// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:23> 'int' 42 + constexpr __int128 Int128 = (__int128)0xFFFFFFFFFFFFFFFF + (__int128)1; +// CHECK: | `-VarDecl {{.*}} <col:3, col:72> col:22 Int128 'const __int128' constexpr cinit +// CHECK-NEXT: | |-value: Int 18446744073709551616 + constexpr float Float = 3.1415f; +// CHECK: | `-VarDecl {{.*}} <col:3, col:27> col:19 Float 'const float' constexpr cinit +// CHECK-NEXT: | |-value: Float 3.141500e+00 +// CHECK-NEXT: | `-FloatingLiteral {{.*}} <col:27> 'float' 3.141500e+00 + constexpr double Double = 3.1415f; +// CHECK: | `-VarDecl {{.*}} <col:3, col:29> col:20 Double 'const double' constexpr cinit +// CHECK-NEXT: | |-value: Float 3.141500e+00 +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <col:29> 'const double' <FloatingCast> +// CHECK-NEXT: | `-FloatingLiteral {{.*}} <col:29> 'float' 3.141500e+00 + constexpr _Complex int ComplexInt = 42 + 24i; +// CHECK: | `-VarDecl {{.*}} <col:3, col:44> col:26 referenced ComplexInt 'const _Complex int' constexpr cinit +// CHECK-NEXT: | |-value: ComplexInt 42 + 24i +// CHECK-NEXT: | `-BinaryOperator {{.*}} <col:39, col:44> '_Complex int' '+' +// CHECK-NEXT: | |-ImplicitCastExpr {{.*}} <col:39> '_Complex int' <IntegralRealToComplex> +// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:39> 'int' 42 +// CHECK-NEXT: | `-ImaginaryLiteral {{.*}} <col:44> '_Complex int' +// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:44> 'int' 24 + constexpr _Complex float ComplexFloat = 3.1415f + 42i; +// CHECK: | `-VarDecl {{.*}} <col:3, col:53> col:28 referenced ComplexFloat 'const _Complex float' constexpr cinit +// CHECK-NEXT: | |-value: ComplexFloat 3.141500e+00 + 4.200000e+01i +// CHECK-NEXT: | `-BinaryOperator {{.*}} <col:43, col:53> '_Complex float' '+' +// CHECK-NEXT: | |-ImplicitCastExpr {{.*}} <col:43> '_Complex float' <FloatingRealToComplex> +// CHECK-NEXT: | | `-FloatingLiteral {{.*}} <col:43> 'float' 3.141500e+00 +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <col:53> '_Complex float' <IntegralComplexToFloatingComplex> +// CHECK-NEXT: | `-ImaginaryLiteral {{.*}} <col:53> '_Complex int' +// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:53> 'int' 42 + constexpr _Complex int ArrayOfComplexInt[10] = {ComplexInt, ComplexInt, ComplexInt, ComplexInt}; +// CHECK: | `-VarDecl {{.*}} <col:2, col:96> col:25 ArrayOfComplexInt '_Complex int const[10]' constexpr cinit +// CHECK-NEXT: | |-value: Array size=10 +// CHECK-NEXT: | | |-elements: ComplexInt 42 + 24i, ComplexInt 42 + 24i, ComplexInt 42 + 24i, ComplexInt 42 + 24i +// CHECK-NEXT: | | `-filler: 6 x ComplexInt 0 + 0i +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:49, col:96> '_Complex int const[10]' +// CHECK-NEXT: | |-array_filler: ImplicitValueInitExpr {{.*}} <<invalid sloc>> 'const _Complex int' +// CHECK-NEXT: | |-ImplicitCastExpr {{.*}} <col:50> '_Complex int' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:50> 'const _Complex int' lvalue Var {{.*}} 'ComplexInt' 'const _Complex int' non_odr_use_constant +// CHECK-NEXT: | |-ImplicitCastExpr {{.*}} <col:62> '_Complex int' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:62> 'const _Complex int' lvalue Var {{.*}} 'ComplexInt' 'const _Complex int' non_odr_use_constant +// CHECK-NEXT: | |-ImplicitCastExpr {{.*}} <col:74> '_Complex int' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:74> 'const _Complex int' lvalue Var {{.*}} 'ComplexInt' 'const _Complex int' non_odr_use_constant +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <col:86> '_Complex int' <LValueToRValue> +// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:86> 'const _Complex int' lvalue Var {{.*}} 'ComplexInt' 'const _Complex int' non_odr_use_constant + constexpr _Complex float ArrayOfComplexFloat[10] = {ComplexFloat, ComplexFloat, ComplexInt, ComplexInt}; +// CHECK: `-VarDecl {{.*}} <col:3, col:105> col:28 ArrayOfComplexFloat '_Complex float const[10]' constexpr cinit +// CHECK-NEXT: |-value: Array size=10 +// CHECK-NEXT: | |-elements: ComplexFloat 3.141500e+00 + 4.200000e+01i, ComplexFloat 3.141500e+00 + 4.200000e+01i, ComplexFloat 4.200000e+01 + 2.400000e+01i, ComplexFloat 4.200000e+01 + 2.400000e+01i +// CHECK-NEXT: | `-filler: 6 x ComplexFloat 0.000000e+00 + 0.000000e+00i +// CHECK-NEXT: `-InitListExpr {{.*}} <col:54, col:105> '_Complex float const[10]' +// CHECK-NEXT: |-array_filler: ImplicitValueInitExpr {{.*}} <<invalid sloc>> 'const _Complex float' +// CHECK-NEXT: |-ImplicitCastExpr {{.*}} <col:55> '_Complex float' <LValueToRValue> +// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:55> 'const _Complex float' lvalue Var {{.*}} 'ComplexFloat' 'const _Complex float' non_odr_use_constant +// CHECK-NEXT: |-ImplicitCastExpr {{.*}} <col:69> '_Complex float' <LValueToRValue> +// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:69> 'const _Complex float' lvalue Var {{.*}} 'ComplexFloat' 'const _Complex float' non_odr_use_constant +// CHECK-NEXT: |-ImplicitCastExpr {{.*}} <col:83> 'const _Complex float' <IntegralComplexToFloatingComplex> +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <col:83> '_Complex int' <LValueToRValue> +// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:83> 'const _Complex int' lvalue Var {{.*}} 'ComplexInt' 'const _Complex int' non_odr_use_constant +// CHECK-NEXT: `-ImplicitCastExpr {{.*}} <col:95> 'const _Complex float' <IntegralComplexToFloatingComplex> +// CHECK-NEXT: `-ImplicitCastExpr {{.*}} <col:95> '_Complex int' <LValueToRValue> +// CHECK-NEXT: `-DeclRefExpr {{.*}} <col:95> 'const _Complex int' lvalue Var {{.*}} 'ComplexInt' 'const _Complex int' non_odr_use_constant +} Index: clang/test/AST/ast-dump-APValue-anon-union.cpp =================================================================== --- /dev/null +++ clang/test/AST/ast-dump-APValue-anon-union.cpp @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +struct S0 { + union { + int i = 42; + }; +}; + +union U0 { + union { + float f = 3.1415f; + }; +}; + +union U1 { + union { + float f; + }; +}; + +void Test() { + constexpr S0 s0{}; +// CHECK: | `-VarDecl {{.*}} <col:3, col:19> col:16 s0 'const S0' constexpr listinit +// CHECK-NEXT: | |-value: Struct +// CHECK-NEXT: | | `-field: Union .i Int 42 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:18, col:19> 'const S0' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19> 'S0::(anonymous union at {{.*}}ast-dump-APValue-anon-union.cpp:6:3)' field Field {{.*}} 'i' 'int' +// CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} <col:19> 'int' + constexpr U0 u0a{}; +// CHECK: | `-VarDecl {{.*}} <col:3, col:20> col:16 u0a 'const U0' constexpr listinit +// CHECK-NEXT: | |-value: Union None +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19, col:20> 'const U0' + constexpr U0 u0b{3.1415f}; +// CHECK: | `-VarDecl {{.*}} <col:3, col:27> col:16 u0b 'const U0' constexpr listinit +// CHECK-NEXT: | |-value: Union . Union .f Float 3.141500e+00 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19, col:27> 'const U0' field Field {{.*}} '' 'U0::(anonymous union at {{.*}}ast-dump-APValue-anon-union.cpp:12:3)' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:20> 'U0::(anonymous union at {{.*}}ast-dump-APValue-anon-union.cpp:12:3)' field Field {{.*}} 'f' 'float' +// CHECK-NEXT: | `-FloatingLiteral {{.*}} <col:20> 'float' 3.141500e+00 + constexpr U1 u1a{}; +// CHECK: | `-VarDecl {{.*}} <col:3, col:20> col:16 u1a 'const U1' constexpr listinit +// CHECK-NEXT: | |-value: Union . Union .f Float 0.000000e+00 +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:19, col:20> 'const U1' field Field {{.*}} '' 'U1::(anonymous union at {{.*}}ast-dump-APValue-anon-union.cpp:18:3)' +// CHECK-NEXT: | `-InitListExpr {{.*}} <col:20> 'U1::(anonymous union at {{.*}}ast-dump-APValue-anon-union.cpp:18:3)' field Field {{.*}} 'f' 'float' + constexpr U1 u1b{3.1415f}; +// CHECK: `-VarDecl {{.*}} <col:3, col:27> col:16 u1b 'const U1' constexpr listinit +// CHECK-NEXT: |-value: Union . Union .f Float 3.141500e+00 +// CHECK-NEXT: `-InitListExpr {{.*}} <col:19, col:27> 'const U1' field Field {{.*}} '' 'U1::(anonymous union at {{.*}}ast-dump-APValue-anon-union.cpp:18:3)' +// CHECK-NEXT: `-InitListExpr {{.*}} <col:20> 'U1::(anonymous union at {{.*}}ast-dump-APValue-anon-union.cpp:18:3)' field Field {{.*}} 'f' 'float' +// CHECK-NEXT: `-FloatingLiteral {{.*}} <col:20> 'float' 3.141500e+00 +} Index: clang/test/AST/alignas_maybe_odr_cleanup.cpp =================================================================== --- clang/test/AST/alignas_maybe_odr_cleanup.cpp +++ clang/test/AST/alignas_maybe_odr_cleanup.cpp @@ -15,8 +15,9 @@ } }; -// CHECK: AlignedAttr {{.*}} alignas -// CHECK: ConstantExpr {{.+}} 'int' Int: 32 -// CHECK: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> -// CHECK: DeclRefExpr {{.*}} 'const int' lvalue Var {{.*}} 'vec_align_bytes' 'const int' non_odr_use_constant -// CHECK: NullStmt +// CHECK: | `-AlignedAttr {{.*}} <col:14> alignas +// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:22> 'int' +// CHECK-NEXT: | |-value: Int 32 +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <col:22> 'int' <LValueToRValue> +// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:22> 'const int' lvalue Var {{.*}} 'vec_align_bytes' 'const int' non_odr_use_constant +// CHECK-NEXT: `-NullStmt {{.*}} <line:14:5> Index: clang/lib/AST/TextNodeDumper.cpp =================================================================== --- clang/lib/AST/TextNodeDumper.cpp +++ clang/lib/AST/TextNodeDumper.cpp @@ -11,10 +11,12 @@ //===----------------------------------------------------------------------===// #include "clang/AST/TextNodeDumper.h" +#include "clang/AST/APValue.h" #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/LocInfoType.h" +#include "clang/AST/Type.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/Specifiers.h" @@ -350,6 +352,220 @@ OS << " selected"; } +static double GetApproxValue(const llvm::APFloat &F) { + llvm::APFloat V = F; + bool ignored; + V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven, + &ignored); + return V.convertToDouble(); +} + +/// True if the \p APValue \p Value can be folded onto the current line. +static bool isSimpleAPValue(const APValue &Value) { + switch (Value.getKind()) { + case APValue::None: + case APValue::Indeterminate: + case APValue::Int: + case APValue::Float: + case APValue::FixedPoint: + case APValue::ComplexInt: + case APValue::ComplexFloat: + case APValue::LValue: + case APValue::MemberPointer: + case APValue::AddrLabelDiff: + return true; + case APValue::Vector: + case APValue::Array: + case APValue::Struct: + return false; + case APValue::Union: + return isSimpleAPValue(Value.getUnionValue()); + } + llvm_unreachable("unexpected APValue kind!"); +} + +/// Dump the children of the \p APValue \p Value. +/// +/// \param[in] Dumper The \p TextNodeDumper +/// \param[in] Value The \p APValue to visit +/// \param[in] Ty The \p QualType passed to \p Visit +/// +/// \param[in] IdxToChildFun A function mapping an \p APValue and an index +/// to one of the child of the \p APValue +/// +/// \param[in] NumChildren \p IdxToChildFun will be called on \p Value with +/// the indices in the range \p [0,NumChildren( +/// +/// \param[in] LabelSingular The label to use on a line with a single child +/// \param[in] LabelPlurial The label to use on a line with multiple children +static void +dumpAPValueChildren(TextNodeDumper &Dumper, const APValue &Value, QualType Ty, + const APValue &(*IdxToChildFun)(const APValue &, unsigned), + unsigned NumChildren, StringRef LabelSingular, + StringRef LabelPlurial) { + // To save some vertical space we print up to MaxChildrenPerLine APValues + // considered to be simple (by isSimpleAPValue) on a single line. + constexpr unsigned MaxChildrenPerLine = 4; + unsigned I = 0; + while (I < NumChildren) { + unsigned J = I; + while (J < NumChildren) { + if (isSimpleAPValue(IdxToChildFun(Value, J)) && + (J - I < MaxChildrenPerLine)) { + ++J; + continue; + } + break; + } + + J = std::max(I + 1, J); + + // Print [I,J) on a single line. + Dumper.AddChild(J - I > 1 ? LabelPlurial : LabelSingular, [=, &Dumper]() { + for (unsigned X = I; X < J; ++X) { + Dumper.Visit(IdxToChildFun(Value, X), Ty); + if (X + 1 != J) + Dumper.getOS() << ", "; + } + }); + I = J; + } +} + +void TextNodeDumper::Visit(const APValue &Value, QualType Ty) { + ColorScope Color(OS, ShowColors, ValueKindColor); + switch (Value.getKind()) { + case APValue::None: + OS << "None"; + return; + case APValue::Indeterminate: + OS << "Indeterminate"; + return; + case APValue::Int: + OS << "Int "; + { + ColorScope Color(OS, ShowColors, ValueColor); + OS << Value.getInt(); + } + return; + case APValue::Float: + OS << "Float "; + { + ColorScope Color(OS, ShowColors, ValueColor); + OS << GetApproxValue(Value.getFloat()); + } + return; + case APValue::FixedPoint: + OS << "FixedPoint "; + { + ColorScope Color(OS, ShowColors, ValueColor); + OS << Value.getFixedPoint(); + } + return; + case APValue::Vector: { + unsigned VectorLength = Value.getVectorLength(); + OS << "Vector length=" << VectorLength; + + dumpAPValueChildren( + *this, Value, Ty, + [](const APValue &Value, unsigned Index) -> const APValue & { + return Value.getVectorElt(Index); + }, + VectorLength, "element", "elements"); + return; + } + case APValue::ComplexInt: + OS << "ComplexInt "; + { + ColorScope Color(OS, ShowColors, ValueColor); + OS << Value.getComplexIntReal() << " + " << Value.getComplexIntImag() + << 'i'; + } + return; + case APValue::ComplexFloat: + OS << "ComplexFloat "; + { + ColorScope Color(OS, ShowColors, ValueColor); + OS << GetApproxValue(Value.getComplexFloatReal()) << " + " + << GetApproxValue(Value.getComplexFloatImag()) << 'i'; + } + return; + case APValue::LValue: + (void)Context; + OS << "LValue <todo>"; + return; + case APValue::Array: { + unsigned ArraySize = Value.getArraySize(); + unsigned NumInitializedElements = Value.getArrayInitializedElts(); + OS << "Array size=" << ArraySize; + + dumpAPValueChildren( + *this, Value, Ty, + [](const APValue &Value, unsigned Index) -> const APValue & { + return Value.getArrayInitializedElt(Index); + }, + NumInitializedElements, "element", "elements"); + + if (Value.hasArrayFiller()) { + AddChild("filler", [=] { + { + ColorScope Color(OS, ShowColors, ValueColor); + OS << ArraySize - NumInitializedElements << " x "; + } + Visit(Value.getArrayFiller(), Ty); + }); + } + + return; + } + case APValue::Struct: { + OS << "Struct"; + + dumpAPValueChildren( + *this, Value, Ty, + [](const APValue &Value, unsigned Index) -> const APValue & { + return Value.getStructBase(Index); + }, + Value.getStructNumBases(), "base", "bases"); + + dumpAPValueChildren( + *this, Value, Ty, + [](const APValue &Value, unsigned Index) -> const APValue & { + return Value.getStructField(Index); + }, + Value.getStructNumFields(), "field", "fields"); + + return; + } + case APValue::Union: { + OS << "Union"; + { + ColorScope Color(OS, ShowColors, ValueColor); + if (const FieldDecl *FD = Value.getUnionField()) + OS << " ." << *cast<NamedDecl>(FD); + } + // If the union value is considered to be simple, fold it into the + // current line to save some vertical space. + const APValue &UnionValue = Value.getUnionValue(); + if (isSimpleAPValue(UnionValue)) { + OS << ' '; + Visit(UnionValue, Ty); + } else { + AddChild([=] { Visit(UnionValue, Ty); }); + } + + return; + } + case APValue::MemberPointer: + OS << "MemberPointer <todo>"; + return; + case APValue::AddrLabelDiff: + OS << "AddrLabelDiff <todo>"; + return; + } + llvm_unreachable("Unknown APValue kind!"); +} + void TextNodeDumper::dumpPointer(const void *Ptr) { ColorScope Color(OS, ShowColors, AddressColor); OS << ' ' << Ptr; @@ -712,11 +928,9 @@ } void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) { - if (Node->getResultAPValueKind() != APValue::None) { - ColorScope Color(OS, ShowColors, ValueColor); - OS << " "; - Node->getAPValueResult().dump(OS, Context); - } + if (Node->hasAPValueResult()) + AddChild("value", + [=] { Visit(Node->getAPValueResult(), Node->getType()); }); } void TextNodeDumper::VisitCallExpr(const CallExpr *Node) { @@ -1454,6 +1668,16 @@ OS << " destroyed"; if (D->isParameterPack()) OS << " pack"; + + if (D->hasInit()) { + const Expr *E = D->getInit(); + // Only dump the value of constexpr VarDecls for now. + if (E && !E->isValueDependent() && D->isConstexpr()) { + const APValue *Value = D->evaluateValue(); + if (Value) + AddChild("value", [=] { Visit(*Value, E->getType()); }); + } + } } void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) { Index: clang/lib/AST/JSONNodeDumper.cpp =================================================================== --- clang/lib/AST/JSONNodeDumper.cpp +++ clang/lib/AST/JSONNodeDumper.cpp @@ -183,6 +183,13 @@ attributeOnlyIfTrue("selected", A.isSelected()); } +void JSONNodeDumper::Visit(const APValue &Value, QualType Ty) { + std::string Str; + llvm::raw_string_ostream OS(Str); + Value.printPretty(OS, Ctx, Ty); + JOS.attribute("value", OS.str()); +} + void JSONNodeDumper::writeIncludeStack(PresumedLoc Loc, bool JustFirst) { if (Loc.isInvalid()) return; @@ -1272,12 +1279,8 @@ } void JSONNodeDumper::VisitConstantExpr(const ConstantExpr *CE) { - if (CE->getResultAPValueKind() != APValue::None) { - std::string Str; - llvm::raw_string_ostream OS(Str); - CE->getAPValueResult().printPretty(OS, Ctx, CE->getType()); - JOS.attribute("value", OS.str()); - } + if (CE->getResultAPValueKind() != APValue::None) + Visit(CE->getAPValueResult(), CE->getType()); } void JSONNodeDumper::VisitInitListExpr(const InitListExpr *ILE) { Index: clang/lib/AST/ASTDumper.cpp =================================================================== --- clang/lib/AST/ASTDumper.cpp +++ clang/lib/AST/ASTDumper.cpp @@ -270,3 +270,19 @@ ASTDumper Dumper(llvm::errs(), /*ShowColors=*/true); Dumper.Visit(FC, FC); } + +//===----------------------------------------------------------------------===// +// APValue method implementations +//===----------------------------------------------------------------------===// + +LLVM_DUMP_METHOD void APValue::dump() const { + ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false); + Dumper.Visit(*this, /*Ty=*/QualType()); +} + +LLVM_DUMP_METHOD void APValue::dump(raw_ostream &OS, + const ASTContext &Context) const { + ASTDumper Dumper(llvm::errs(), Context, + Context.getDiagnostics().getShowColors()); + Dumper.Visit(*this, /*Ty=*/Context.getPointerType(Context.CharTy)); +} Index: clang/lib/AST/APValue.cpp =================================================================== --- clang/lib/AST/APValue.cpp +++ clang/lib/AST/APValue.cpp @@ -386,92 +386,6 @@ return V.convertToDouble(); } -LLVM_DUMP_METHOD void APValue::dump() const { - dump(llvm::errs(), /*Context=*/nullptr); - llvm::errs() << '\n'; -} - -LLVM_DUMP_METHOD void APValue::dump(raw_ostream &OS, - const ASTContext *Context) const { - switch (getKind()) { - case None: - OS << "None"; - return; - case Indeterminate: - OS << "Indeterminate"; - return; - case Int: - OS << "Int: " << getInt(); - return; - case Float: - OS << "Float: " << GetApproxValue(getFloat()); - return; - case FixedPoint: - OS << "FixedPoint : " << getFixedPoint(); - return; - case Vector: - OS << "Vector: "; - getVectorElt(0).dump(OS, Context); - for (unsigned i = 1; i != getVectorLength(); ++i) { - OS << ", "; - getVectorElt(i).dump(OS, Context); - } - return; - case ComplexInt: - OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag(); - return; - case ComplexFloat: - OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal()) - << ", " << GetApproxValue(getComplexFloatImag()); - return; - case LValue: - OS << "LValue: <todo>"; - return; - case Array: - OS << "Array: "; - for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) { - getArrayInitializedElt(I).dump(OS, Context); - if (I != getArraySize() - 1) - OS << ", "; - } - if (hasArrayFiller()) { - OS << getArraySize() - getArrayInitializedElts() << " x "; - getArrayFiller().dump(OS, Context); - } - return; - case Struct: - OS << "Struct "; - if (unsigned N = getStructNumBases()) { - OS << " bases: "; - getStructBase(0).dump(OS, Context); - for (unsigned I = 1; I != N; ++I) { - OS << ", "; - getStructBase(I).dump(OS, Context); - } - } - if (unsigned N = getStructNumFields()) { - OS << " fields: "; - getStructField(0).dump(OS, Context); - for (unsigned I = 1; I != N; ++I) { - OS << ", "; - getStructField(I).dump(OS, Context); - } - } - return; - case Union: - OS << "Union: "; - getUnionValue().dump(OS, Context); - return; - case MemberPointer: - OS << "MemberPointer: <todo>"; - return; - case AddrLabelDiff: - OS << "AddrLabelDiff: <todo>"; - return; - } - llvm_unreachable("Unknown APValue kind!"); -} - void APValue::printPretty(raw_ostream &Out, const ASTContext &Ctx, QualType Ty) const { switch (getKind()) { Index: clang/include/clang/AST/TextNodeDumper.h =================================================================== --- clang/include/clang/AST/TextNodeDumper.h +++ clang/include/clang/AST/TextNodeDumper.h @@ -22,10 +22,13 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TemplateArgumentVisitor.h" +#include "clang/AST/Type.h" #include "clang/AST/TypeVisitor.h" namespace clang { +class APValue; + class TextTreeStructure { raw_ostream &OS; const bool ShowColors; @@ -157,6 +160,8 @@ TextNodeDumper(raw_ostream &OS, const ASTContext &Context, bool ShowColors); TextNodeDumper(raw_ostream &OS, bool ShowColors); + raw_ostream &getOS() { return OS; } + void Visit(const comments::Comment *C, const comments::FullComment *FC); void Visit(const Attr *A); @@ -180,6 +185,8 @@ void Visit(const GenericSelectionExpr::ConstAssociation &A); + void Visit(const APValue &Value, QualType Ty); + void dumpPointer(const void *Ptr); void dumpLocation(SourceLocation Loc); void dumpSourceRange(SourceRange R); Index: clang/include/clang/AST/JSONNodeDumper.h =================================================================== --- clang/include/clang/AST/JSONNodeDumper.h +++ clang/include/clang/AST/JSONNodeDumper.h @@ -23,10 +23,13 @@ #include "clang/AST/CommentVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/Mangle.h" +#include "clang/AST/Type.h" #include "llvm/Support/JSON.h" namespace clang { +class APValue; + class NodeStreamer { bool FirstChild = true; bool TopLevel = true; @@ -201,6 +204,7 @@ void Visit(const OMPClause *C); void Visit(const BlockDecl::Capture &C); void Visit(const GenericSelectionExpr::ConstAssociation &A); + void Visit(const APValue &Value, QualType Ty); void VisitTypedefType(const TypedefType *TT); void VisitFunctionType(const FunctionType *T); Index: clang/include/clang/AST/ASTNodeTraverser.h =================================================================== --- clang/include/clang/AST/ASTNodeTraverser.h +++ clang/include/clang/AST/ASTNodeTraverser.h @@ -22,10 +22,13 @@ #include "clang/AST/LocInfoType.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TemplateArgumentVisitor.h" +#include "clang/AST/Type.h" #include "clang/AST/TypeVisitor.h" namespace clang { +class APValue; + /** ASTNodeTraverser traverses the Clang AST for dumping purposes. @@ -50,6 +53,7 @@ void Visit(const OMPClause *C); void Visit(const BlockDecl::Capture &C); void Visit(const GenericSelectionExpr::ConstAssociation &A); + void Visit(const APValue &Value, QualType Ty); }; */ template <typename Derived, typename NodeDelegateType> @@ -211,6 +215,10 @@ }); } + void Visit(const APValue &Value, QualType Ty) { + getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(Value, Ty); }); + } + void Visit(const comments::Comment *C, const comments::FullComment *FC) { getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(C, FC); Index: clang/include/clang/AST/APValue.h =================================================================== --- clang/include/clang/AST/APValue.h +++ clang/include/clang/AST/APValue.h @@ -372,7 +372,7 @@ bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; } void dump() const; - void dump(raw_ostream &OS, const ASTContext *Context) const; + void dump(raw_ostream &OS, const ASTContext &Context) const; void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const; std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits