This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rGf63e3ea558bb: [clang] Rework how and when APValues are 
dumped (authored by riccibruno).

Changed prior to commit:
  https://reviews.llvm.org/D83183?vs=275575&id=275633#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83183/new/

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,35 @@
+// 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:  |-DeclStmt {{.*}} <line:{{.*}}, col:{{.*}}>
+  // CHECK-NEXT:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} v1i '__attribute__((__vector_size__(1 * sizeof(int)))) int const' constexpr cinit
+  // CHECK-NEXT:  |   |-value: Vector length=1
+  // CHECK-NEXT:  |   | `-element: Int 1
+
+  constexpr int __attribute__((vector_size(sizeof(int) * 4))) v4i = {1, 2, 3, 4};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+
+  constexpr int __attribute__((vector_size(sizeof(int) * 5))) v5i = {1, 2, 3, 4};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+
+  constexpr int __attribute__((vector_size(sizeof(int) * 8))) v8i = {1, 2, 3, 4};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+
+  constexpr int __attribute__((vector_size(sizeof(int) * 9))) v9i = {1, 2, 3, 4};
+  // CHECK:    `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+}
Index: clang/test/AST/ast-dump-APValue-union.cpp
===================================================================
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-union.cpp
@@ -0,0 +1,55 @@
+// 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:{{.*}}, col:{{.*}}> col:{{.*}} u0 'const U0' constexpr listinit
+  // CHECK-NEXT:  |   |-value: Union .i Int 42
+
+  constexpr U1 u1{};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} u1 'const U1' constexpr listinit
+  // CHECK-NEXT:  |   |-value: Union .uinner Union .f Float 3.141500e+00
+
+  constexpr U2 u2{};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+
+  constexpr U3 u3a = {.f = 3.1415};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} u3a 'const U3' constexpr cinit
+  // CHECK-NEXT:  |   |-value: Union .f Float 3.141500e+00
+
+  constexpr U3 u3b = {.uinner = {}};
+  // CHECK:    `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} u3b 'const U3' constexpr cinit
+  // CHECK-NEXT:      |-value: Union .uinner Union .d Float 3.141500e+00
+}
Index: clang/test/AST/ast-dump-APValue-todo.cpp
===================================================================
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-todo.cpp
@@ -0,0 +1,18 @@
+// 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:{{.*}}, col:{{.*}}> col:{{.*}} pi 'int *const' constexpr cinit
+  // CHECK-NEXT:  |   |-value: LValue <todo>
+
+  constexpr int(S::*pmi) = &S::i;
+  // CHECK:    `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pmi 'int (S::*const)' constexpr cinit
+  // CHECK-NEXT:      |-value: MemberPointer <todo>
+}
Index: clang/test/AST/ast-dump-APValue-struct.cpp
===================================================================
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-struct.cpp
@@ -0,0 +1,105 @@
+// 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:{{.*}}, col:{{.*}}> col:{{.*}} s0 'const S0' constexpr listinit
+  // CHECK-NEXT:  |   |-value: Struct
+  // CHECK-NEXT:  |   | `-fields: Int 0, Union .j Int 0
+
+  constexpr S1 s1{};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+
+  constexpr S2 s2{};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} s2 'const S2' constexpr listinit
+  // CHECK-NEXT:  |   |-value: Struct
+  // CHECK-NEXT:  |   | `-fields: Int 0, Union .u Union .j Int 0
+
+  constexpr S3 s3{};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+
+  constexpr S4 s4{};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+
+  constexpr S5 s5{};
+  // CHECK:    `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+}
Index: clang/test/AST/ast-dump-APValue-array.cpp
===================================================================
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-array.cpp
@@ -0,0 +1,74 @@
+// 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:{{.*}}, line:{{.*}}> line:{{.*}} 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
+
+  constexpr float arr_f[3][5] = {
+      {1, 2, 3, 4, 5},
+  };
+  // CHECK:  | `-VarDecl {{.*}} <line:{{.*}}, line:{{.*}}> line:{{.*}} 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
+
+  constexpr S0 arr_s0[2] = {{1, 2}, {3, 4}};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+
+  constexpr U0 arr_u0[2] = {{.i = 42}, {.f = 3.1415f}};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+
+  constexpr S1 arr_s1[2] = {};
+  // CHECK:    `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+}
Index: clang/test/AST/ast-dump-APValue-arithmetic.cpp
===================================================================
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-arithmetic.cpp
@@ -0,0 +1,41 @@
+// 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:{{.*}}, col:{{.*}}> col:{{.*}} Int 'const int' constexpr cinit
+  // CHECK-NEXT:  |   |-value: Int 42
+
+  constexpr __int128 Int128 = (__int128)0xFFFFFFFFFFFFFFFF + (__int128)1;
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} Int128 'const __int128' constexpr cinit
+  // CHECK-NEXT:  |   |-value: Int 18446744073709551616
+
+  constexpr float Float = 3.1415f;
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} Float 'const float' constexpr cinit
+  // CHECK-NEXT:  |   |-value: Float 3.141500e+00
+
+  constexpr double Double = 3.1415f;
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} Double 'const double' constexpr cinit
+  // CHECK-NEXT:  |   |-value: Float 3.141500e+00
+
+  constexpr _Complex int ComplexInt = 42 + 24i;
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} referenced ComplexInt 'const _Complex int' constexpr cinit
+  // CHECK-NEXT:  |   |-value: ComplexInt 42 + 24i
+
+  constexpr _Complex float ComplexFloat = 3.1415f + 42i;
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} referenced ComplexFloat 'const _Complex float' constexpr cinit
+  // CHECK-NEXT:  |   |-value: ComplexFloat 3.141500e+00 + 4.200000e+01i
+
+  constexpr _Complex int ArrayOfComplexInt[10] = {ComplexInt, ComplexInt, ComplexInt, ComplexInt};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+
+  constexpr _Complex float ArrayOfComplexFloat[10] = {ComplexFloat, ComplexFloat, ComplexInt, ComplexInt};
+  // CHECK:    `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} 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
+}
Index: clang/test/AST/ast-dump-APValue-anon-union.cpp
===================================================================
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-anon-union.cpp
@@ -0,0 +1,44 @@
+// 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:{{.*}}, col:{{.*}}> col:{{.*}} s0 'const S0' constexpr listinit
+  // CHECK-NEXT:  |   |-value: Struct
+  // CHECK-NEXT:  |   | `-field: Union .i Int 42
+
+  constexpr U0 u0a{};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} u0a 'const U0' constexpr listinit
+  // CHECK-NEXT:  |   |-value: Union None
+
+  constexpr U0 u0b{3.1415f};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} u0b 'const U0' constexpr listinit
+  // CHECK-NEXT:  |   |-value: Union . Union .f Float 3.141500e+00
+
+  constexpr U1 u1a{};
+  // CHECK:  | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} u1a 'const U1' constexpr listinit
+  // CHECK-NEXT:  |   |-value: Union . Union .f Float 0.000000e+00
+
+  constexpr U1 u1b{3.1415f};
+  // CHECK:    `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} u1b 'const U1' constexpr listinit
+  // CHECK-NEXT:      |-value: Union . Union .f 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,15 +11,20 @@
 //===----------------------------------------------------------------------===//
 
 #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"
 #include "clang/Basic/TypeTraits.h"
 
+#include <algorithm>
+#include <utility>
+
 using namespace clang;
 
 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
@@ -350,6 +355,218 @@
     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] 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
+void TextNodeDumper::dumpAPValueChildren(
+    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.
+    AddChild(J - I > 1 ? LabelPlurial : LabelSingular, [=]() {
+      for (unsigned X = I; X < J; ++X) {
+        Visit(IdxToChildFun(Value, X), Ty);
+        if (X + 1 != J)
+          OS << ", ";
+      }
+    });
+    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(
+        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(
+        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(
+        Value, Ty,
+        [](const APValue &Value, unsigned Index) -> const APValue & {
+          return Value.getStructBase(Index);
+        },
+        Value.getStructNumBases(), "base", "bases");
+
+    dumpAPValueChildren(
+        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 +929,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 +1669,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;
@@ -153,6 +156,12 @@
 
   const char *getCommandName(unsigned CommandID);
 
+  void dumpAPValueChildren(const APValue &Value, QualType Ty,
+                           const APValue &(*IdxToChildFun)(const APValue &,
+                                                           unsigned),
+                           unsigned NumChildren, StringRef LabelSingular,
+                           StringRef LabelPlurial);
+
 public:
   TextNodeDumper(raw_ostream &OS, const ASTContext &Context, bool ShowColors);
   TextNodeDumper(raw_ostream &OS, bool ShowColors);
@@ -180,6 +189,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

Reply via email to