[clang] f63e3ea - [clang] Rework how and when APValues are dumped

Bruno Ricci via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 6 14:03:50 PDT 2020


Author: Bruno Ricci
Date: 2020-07-06T22:03:08+01:00
New Revision: f63e3ea558bbe14826b5b775367eac617b35e041

URL: https://github.com/llvm/llvm-project/commit/f63e3ea558bbe14826b5b775367eac617b35e041
DIFF: https://github.com/llvm/llvm-project/commit/f63e3ea558bbe14826b5b775367eac617b35e041.diff

LOG: [clang] Rework how and when APValues are dumped

Currently APValues 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 APValues are currently only dumped as part of visiting a
ConstantExpr. This patch also dump the value of the initializer 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

Differential Revision: https://reviews.llvm.org/D83183

Reviewed By: aaron.ballman

Added: 
    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

Modified: 
    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-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

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h
index c69974c63c71..cca92b5f8235 100644
--- a/clang/include/clang/AST/APValue.h
+++ b/clang/include/clang/AST/APValue.h
@@ -372,7 +372,7 @@ class APValue {
   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;

diff  --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index f1c98193df6c..26656b7162b6 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/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 @@ struct {
   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 @@ class ASTNodeTraverser
     });
   }
 
+  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);

diff  --git a/clang/include/clang/AST/JSONNodeDumper.h b/clang/include/clang/AST/JSONNodeDumper.h
index ae7b4c9a17ea..4e7162992418 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/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 @@ class JSONNodeDumper
   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);

diff  --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h
index d2ec153ce67c..b4cfb5a380d1 100644
--- a/clang/include/clang/AST/TextNodeDumper.h
+++ b/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 @@ class TextNodeDumper
 
   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 @@ class TextNodeDumper
 
   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);

diff  --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index 417916241d79..f3828bb54c1d 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -386,92 +386,6 @@ static double GetApproxValue(const llvm::APFloat &F) {
   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()) {

diff  --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp
index 08a6d0cbd261..284e5bdbc6b0 100644
--- a/clang/lib/AST/ASTDumper.cpp
+++ b/clang/lib/AST/ASTDumper.cpp
@@ -270,3 +270,19 @@ LLVM_DUMP_METHOD void Comment::dumpColor() const {
   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));
+}

diff  --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index c9a84a2b7d57..4bd00ece86ab 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -183,6 +183,13 @@ void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
   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::VisitCXXTypeidExpr(const CXXTypeidExpr *CTE) {
 }
 
 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) {

diff  --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 74966f804fe3..5b0a0ac392c0 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/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 @@ void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
     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::VisitCaseStmt(const CaseStmt *Node) {
 }
 
 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 @@ void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
     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) {

diff  --git a/clang/test/AST/alignas_maybe_odr_cleanup.cpp b/clang/test/AST/alignas_maybe_odr_cleanup.cpp
index cdff1bfe8b80..3adef4cba144 100644
--- a/clang/test/AST/alignas_maybe_odr_cleanup.cpp
+++ b/clang/test/AST/alignas_maybe_odr_cleanup.cpp
@@ -15,8 +15,9 @@ struct FOO {
   }
 };
 
-// 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>

diff  --git a/clang/test/AST/ast-dump-APValue-anon-union.cpp b/clang/test/AST/ast-dump-APValue-anon-union.cpp
new file mode 100644
index 000000000000..c50fe70be911
--- /dev/null
+++ b/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
+}

diff  --git a/clang/test/AST/ast-dump-APValue-arithmetic.cpp b/clang/test/AST/ast-dump-APValue-arithmetic.cpp
new file mode 100644
index 000000000000..a4e1d82eeb37
--- /dev/null
+++ b/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
+}

diff  --git a/clang/test/AST/ast-dump-APValue-array.cpp b/clang/test/AST/ast-dump-APValue-array.cpp
new file mode 100644
index 000000000000..4b7dfab09eaf
--- /dev/null
+++ b/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
+}

diff  --git a/clang/test/AST/ast-dump-APValue-struct.cpp b/clang/test/AST/ast-dump-APValue-struct.cpp
new file mode 100644
index 000000000000..d69ddffda031
--- /dev/null
+++ b/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
+}

diff  --git a/clang/test/AST/ast-dump-APValue-todo.cpp b/clang/test/AST/ast-dump-APValue-todo.cpp
new file mode 100644
index 000000000000..5de8146910f7
--- /dev/null
+++ b/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>
+}

diff  --git a/clang/test/AST/ast-dump-APValue-union.cpp b/clang/test/AST/ast-dump-APValue-union.cpp
new file mode 100644
index 000000000000..afb69de9f587
--- /dev/null
+++ b/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
+}

diff  --git a/clang/test/AST/ast-dump-APValue-vector.cpp b/clang/test/AST/ast-dump-APValue-vector.cpp
new file mode 100644
index 000000000000..fe2dcd934056
--- /dev/null
+++ b/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
+}

diff  --git a/clang/test/AST/ast-dump-attr.cpp b/clang/test/AST/ast-dump-attr.cpp
index 50eef3e0d97a..95491a02f8b2 100644
--- a/clang/test/AST/ast-dump-attr.cpp
+++ b/clang/test/AST/ast-dump-attr.cpp
@@ -45,6 +45,7 @@ int TestAlignedExpr __attribute__((aligned(4)));
 // CHECK:      VarDecl{{.*}}TestAlignedExpr
 // CHECK-NEXT:   AlignedAttr {{.*}} aligned
 // CHECK-NEXT:     ConstantExpr
+// CHECK-NEXT:       value: Int 4
 // CHECK-NEXT:       IntegerLiteral
 
 int TestEnum __attribute__((visibility("default")));

diff  --git a/clang/test/AST/ast-dump-color.cpp b/clang/test/AST/ast-dump-color.cpp
index 6651ef2652e0..baaf9729c7ce 100644
--- a/clang/test/AST/ast-dump-color.cpp
+++ b/clang/test/AST/ast-dump-color.cpp
@@ -49,13 +49,15 @@ struct Invalid {
 //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]]>{{$}}

diff  --git a/clang/test/AST/ast-dump-constant-expr.cpp b/clang/test/AST/ast-dump-constant-expr.cpp
index c9ddb245ef64..43f68cac7206 100644
--- a/clang/test/AST/ast-dump-constant-expr.cpp
+++ b/clang/test/AST/ast-dump-constant-expr.cpp
@@ -54,27 +54,32 @@ void Test() {
 // 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 ()'

diff  --git a/clang/test/AST/ast-dump-decl.cpp b/clang/test/AST/ast-dump-decl.cpp
index b9b7cba394f5..97bb7964c47b 100644
--- a/clang/test/AST/ast-dump-decl.cpp
+++ b/clang/test/AST/ast-dump-decl.cpp
@@ -439,6 +439,7 @@ namespace testClassTemplateDecl {
 // 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 @@ namespace TestNonTypeTemplateParmDecl {
 // 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
 

diff  --git a/clang/test/AST/ast-dump-records.cpp b/clang/test/AST/ast-dump-records.cpp
index f379b2dba529..cb7ac8320431 100644
--- a/clang/test/AST/ast-dump-records.cpp
+++ b/clang/test/AST/ast-dump-records.cpp
@@ -15,7 +15,7 @@ struct B;
 // 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 @@ struct A {
   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 @@ union F;
 // 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 @@ union E {
   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 *'

diff  --git a/clang/test/AST/ast-dump-stmt.cpp b/clang/test/AST/ast-dump-stmt.cpp
index e4d8d8218b4e..585a94bd1920 100644
--- a/clang/test/AST/ast-dump-stmt.cpp
+++ b/clang/test/AST/ast-dump-stmt.cpp
@@ -130,6 +130,7 @@ void TestIf(bool b) {
     ;
   // 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 @@ void TestIf(bool b) {
     ;
   // 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

diff  --git a/clang/test/AST/pr43983.cpp b/clang/test/AST/pr43983.cpp
index dd7ce76a38bc..c27d825dbb1b 100644
--- a/clang/test/AST/pr43983.cpp
+++ b/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

diff  --git a/clang/test/Import/switch-stmt/test.cpp b/clang/test/Import/switch-stmt/test.cpp
index e274e895c444..fcd8263727ea 100644
--- a/clang/test/Import/switch-stmt/test.cpp
+++ b/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
 

diff  --git a/clang/test/Tooling/clang-check-ast-dump.cpp b/clang/test/Tooling/clang-check-ast-dump.cpp
index 496d489fd609..bd9ae5fcc2a5 100644
--- a/clang/test/Tooling/clang-check-ast-dump.cpp
+++ b/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


        


More information about the cfe-commits mailing list