[clang] c8c92b5 - [SyntaxTree] Use Annotations based tests for expressions

Eduardo Caldas via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 18 06:01:13 PDT 2020


Author: Eduardo Caldas
Date: 2020-08-18T13:00:56Z
New Revision: c8c92b54d74c1b9256f9aed6ba89d66fbd1d01ae

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

LOG: [SyntaxTree] Use Annotations based tests for expressions

In this process we also create some other tests, in order to not lose
coverage when focusing on the annotated code

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

Added: 
    

Modified: 
    clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
    clang/unittests/Tooling/Syntax/TreeTestBase.cpp

Removed: 
    


################################################################################
diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index 211e8b1ae901..fd858dfba91f 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -437,672 +437,355 @@ void test() {
 }
 
 TEST_P(SyntaxTreeTest, UnqualifiedId_Identifier) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test(int a) {
-  a;
+  [[a]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   `-a
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-IdExpression
-    | | `-UnqualifiedId
-    | |   `-a
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+IdExpression
+`-UnqualifiedId
+  `-a
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UnqualifiedId_OperatorFunctionId) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X {
   friend X operator+(const X&, const X&);
 };
 void test(X x) {
-  operator+(x, x);
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-UnknownDeclaration
-| | `-SimpleDeclaration
-| |   |-friend
-| |   |-X
-| |   |-SimpleDeclarator
-| |   | |-operator
-| |   | |-+
-| |   | `-ParametersAndQualifiers
-| |   |   |-(
-| |   |   |-SimpleDeclaration
-| |   |   | |-const
-| |   |   | |-X
-| |   |   | `-SimpleDeclarator
-| |   |   |   `-&
-| |   |   |-,
-| |   |   |-SimpleDeclaration
-| |   |   | |-const
-| |   |   | |-X
-| |   |   | `-SimpleDeclarator
-| |   |   |   `-&
-| |   |   `-)
-| |   `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-UnknownExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   |-operator
-    | | |   `-+
-    | | |-(
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-x
-    | | |-,
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-x
-    | | `-)
-    | `-;
-    `-}
-)txt"));
+  [[operator+(x, x)]];
+}
+)cpp",
+      {R"txt(
+UnknownExpression
+|-IdExpression
+| `-UnqualifiedId
+|   |-operator
+|   `-+
+|-(
+|-IdExpression
+| `-UnqualifiedId
+|   `-x
+|-,
+|-IdExpression
+| `-UnqualifiedId
+|   `-x
+`-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UnqualifiedId_ConversionFunctionId) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X {
   operator int();
 };
 void test(X x) {
   // TODO: Expose `id-expression` from `MemberExpr`
-  x.operator int();
+  [[x.operator int()]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-SimpleDeclaration
-| | |-SimpleDeclarator
-| | | |-operator
-| | | |-int
-| | | `-ParametersAndQualifiers
-| | |   |-(
-| | |   `-)
-| | `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-UnknownExpression
-    | | |-UnknownExpression
-    | | | |-IdExpression
-    | | | | `-UnqualifiedId
-    | | | |   `-x
-    | | | |-.
-    | | | |-operator
-    | | | `-int
-    | | |-(
-    | | `-)
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+UnknownExpression
+|-UnknownExpression
+| |-IdExpression
+| | `-UnqualifiedId
+| |   `-x
+| |-.
+| |-operator
+| `-int
+|-(
+`-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UnqualifiedId_LiteralOperatorId) {
   if (!GetParam().isCXX11OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 unsigned operator "" _w(char);
 void test() {
-  operator "" _w('1');
+  [[operator "" _w('1')]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-unsigned
-| |-SimpleDeclarator
-| | |-operator
-| | |-""
-| | |-_w
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-SimpleDeclaration
-| |   | `-char
-| |   `-)
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-UnknownExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   |-operator
-    | | |   |-""
-    | | |   `-_w
-    | | |-(
-    | | |-CharacterLiteralExpression
-    | | | `-'1'
-    | | `-)
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+UnknownExpression
+|-IdExpression
+| `-UnqualifiedId
+|   |-operator
+|   |-""
+|   `-_w
+|-(
+|-CharacterLiteralExpression
+| `-'1'
+`-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UnqualifiedId_Destructor) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X { };
 void test(X x) {
   // TODO: Expose `id-expression` from `MemberExpr`
-  x.~X();
+  [[x.~X()]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-UnknownExpression
-    | | |-UnknownExpression
-    | | | |-IdExpression
-    | | | | `-UnqualifiedId
-    | | | |   `-x
-    | | | |-.
-    | | | |-~
-    | | | `-X
-    | | |-(
-    | | `-)
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+UnknownExpression
+|-UnknownExpression
+| |-IdExpression
+| | `-UnqualifiedId
+| |   `-x
+| |-.
+| |-~
+| `-X
+|-(
+`-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UnqualifiedId_DecltypeDestructor) {
   if (!GetParam().isCXX11OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X { };
 void test(X x) {
   // TODO: Expose `id-expression` from `MemberExpr`
-  x.~decltype(x)();
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-UnknownExpression
-    | | |-UnknownExpression
-    | | | |-IdExpression
-    | | | | `-UnqualifiedId
-    | | | |   `-x
-    | | | |-.
-    | | | `-~
-    | | |-decltype
-    | | |-(
-    | | |-x
-    | | |-)
-    | | |-(
-    | | `-)
-    | `-;
-    `-}
-)txt"));
+  [[x.~decltype(x)()]];
+}
+)cpp",
+      {R"txt(
+UnknownExpression
+|-UnknownExpression
+| |-IdExpression
+| | `-UnqualifiedId
+| |   `-x
+| |-.
+| `-~
+|-decltype
+|-(
+|-x
+|-)
+|-(
+`-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UnqualifiedId_TemplateId) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 template<typename T>
 T f();
 void test() {
-  f<int>();
+  [[f<int>()]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-UnknownDeclaration
-| | |-typename
-| | `-T
-| |->
-| `-SimpleDeclaration
-|   |-T
-|   |-SimpleDeclarator
-|   | |-f
-|   | `-ParametersAndQualifiers
-|   |   |-(
-|   |   `-)
-|   `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-UnknownExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   |-f
-    | | |   |-<
-    | | |   |-int
-    | | |   `->
-    | | |-(
-    | | `-)
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+UnknownExpression
+|-IdExpression
+| `-UnqualifiedId
+|   |-f
+|   |-<
+|   |-int
+|   `->
+|-(
+`-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, QualifiedId_NamespaceSpecifier) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 namespace n {
   struct S { };
 }
 void test() {
-  ::n::S s1;
-  n::S s2;
+  [[::n::S s1]];
+  [[n::S s2]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-NamespaceDefinition
-| |-namespace
-| |-n
-| |-{
-| |-SimpleDeclaration
-| | |-struct
-| | |-S
-| | |-{
-| | |-}
-| | `-;
-| `-}
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-DeclarationStatement
-    | |-SimpleDeclaration
-    | | |-NestedNameSpecifier
-    | | | |-::
-    | | | |-IdentifierNameSpecifier
-    | | | | `-n
-    | | | `-::
-    | | |-S
-    | | `-SimpleDeclarator
-    | |   `-UnknownExpression
-    | |     `-s1
-    | `-;
-    |-DeclarationStatement
-    | |-SimpleDeclaration
-    | | |-NestedNameSpecifier
-    | | | |-IdentifierNameSpecifier
-    | | | | `-n
-    | | | `-::
-    | | |-S
-    | | `-SimpleDeclarator
-    | |   `-UnknownExpression
-    | |     `-s2
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+SimpleDeclaration
+|-NestedNameSpecifier
+| |-::
+| |-IdentifierNameSpecifier
+| | `-n
+| `-::
+|-S
+`-SimpleDeclarator
+  `-UnknownExpression
+    `-s1
+)txt",
+       R"txt(
+SimpleDeclaration
+|-NestedNameSpecifier
+| |-IdentifierNameSpecifier
+| | `-n
+| `-::
+|-S
+`-SimpleDeclarator
+  `-UnknownExpression
+    `-s2
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, QualifiedId_TemplateSpecifier) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 template<typename T>
 struct ST {
   struct S { };
 };
 void test() {
-  ::template ST<int>::S s1;
-  ::ST<int>::S s2;
+  [[::template ST<int>::S s1]];
+  [[::ST<int>::S s2]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-UnknownDeclaration
-| | |-typename
-| | `-T
-| |->
-| `-SimpleDeclaration
-|   |-struct
-|   |-ST
-|   |-{
-|   |-SimpleDeclaration
-|   | |-struct
-|   | |-S
-|   | |-{
-|   | |-}
-|   | `-;
-|   |-}
-|   `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-DeclarationStatement
-    | |-SimpleDeclaration
-    | | |-NestedNameSpecifier
-    | | | |-::
-    | | | |-SimpleTemplateNameSpecifier
-    | | | | |-template
-    | | | | |-ST
-    | | | | |-<
-    | | | | |-int
-    | | | | `->
-    | | | `-::
-    | | |-S
-    | | `-SimpleDeclarator
-    | |   `-UnknownExpression
-    | |     `-s1
-    | `-;
-    |-DeclarationStatement
-    | |-SimpleDeclaration
-    | | |-NestedNameSpecifier
-    | | | |-::
-    | | | |-SimpleTemplateNameSpecifier
-    | | | | |-ST
-    | | | | |-<
-    | | | | |-int
-    | | | | `->
-    | | | `-::
-    | | |-S
-    | | `-SimpleDeclarator
-    | |   `-UnknownExpression
-    | |     `-s2
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+SimpleDeclaration
+|-NestedNameSpecifier
+| |-::
+| |-SimpleTemplateNameSpecifier
+| | |-template
+| | |-ST
+| | |-<
+| | |-int
+| | `->
+| `-::
+|-S
+`-SimpleDeclarator
+  `-UnknownExpression
+    `-s1
+)txt",
+       R"txt(
+SimpleDeclaration
+|-NestedNameSpecifier
+| |-::
+| |-SimpleTemplateNameSpecifier
+| | |-ST
+| | |-<
+| | |-int
+| | `->
+| `-::
+|-S
+`-SimpleDeclarator
+  `-UnknownExpression
+    `-s2
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, QualifiedId_DecltypeSpecifier) {
   if (!GetParam().isCXX11OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct S {
   static void f(){}
 };
 void test(S s) {
-  decltype(s)::f();
+  [[decltype(s)::f()]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-S
-| |-{
-| |-SimpleDeclaration
-| | |-static
-| | |-void
-| | |-SimpleDeclarator
-| | | |-f
-| | | `-ParametersAndQualifiers
-| | |   |-(
-| | |   `-)
-| | `-CompoundStatement
-| |   |-{
-| |   `-}
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-S
-  |   | `-SimpleDeclarator
-  |   |   `-s
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-UnknownExpression
-    | | |-IdExpression
-    | | | |-NestedNameSpecifier
-    | | | | |-DecltypeNameSpecifier
-    | | | | | |-decltype
-    | | | | | |-(
-    | | | | | |-IdExpression
-    | | | | | | `-UnqualifiedId
-    | | | | | |   `-s
-    | | | | | `-)
-    | | | | `-::
-    | | | `-UnqualifiedId
-    | | |   `-f
-    | | |-(
-    | | `-)
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+UnknownExpression
+|-IdExpression
+| |-NestedNameSpecifier
+| | |-DecltypeNameSpecifier
+| | | |-decltype
+| | | |-(
+| | | |-IdExpression
+| | | | `-UnqualifiedId
+| | | |   `-s
+| | | `-)
+| | `-::
+| `-UnqualifiedId
+|   `-f
+|-(
+`-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, QualifiedId_OptionalTemplateKw) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct S {
   template<typename U>
   static U f();
 };
 void test() {
-  S::f<int>();
-  S::template f<int>();
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-S
-| |-{
-| |-TemplateDeclaration
-| | |-template
-| | |-<
-| | |-UnknownDeclaration
-| | | |-typename
-| | | `-U
-| | |->
-| | `-SimpleDeclaration
-| |   |-static
-| |   |-U
-| |   |-SimpleDeclarator
-| |   | |-f
-| |   | `-ParametersAndQualifiers
-| |   |   |-(
-| |   |   `-)
-| |   `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-UnknownExpression
-    | | |-IdExpression
-    | | | |-NestedNameSpecifier
-    | | | | |-IdentifierNameSpecifier
-    | | | | | `-S
-    | | | | `-::
-    | | | `-UnqualifiedId
-    | | |   |-f
-    | | |   |-<
-    | | |   |-int
-    | | |   `->
-    | | |-(
-    | | `-)
-    | `-;
-    |-ExpressionStatement
-    | |-UnknownExpression
-    | | |-IdExpression
-    | | | |-NestedNameSpecifier
-    | | | | |-IdentifierNameSpecifier
-    | | | | | `-S
-    | | | | `-::
-    | | | |-template
-    | | | `-UnqualifiedId
-    | | |   |-f
-    | | |   |-<
-    | | |   |-int
-    | | |   `->
-    | | |-(
-    | | `-)
-    | `-;
-    `-}
-)txt"));
+  [[S::f<int>()]];
+  [[S::template f<int>()]];
+}
+)cpp",
+      {R"txt(
+UnknownExpression
+|-IdExpression
+| |-NestedNameSpecifier
+| | |-IdentifierNameSpecifier
+| | | `-S
+| | `-::
+| `-UnqualifiedId
+|   |-f
+|   |-<
+|   |-int
+|   `->
+|-(
+`-)
+)txt",
+       R"txt(
+UnknownExpression
+|-IdExpression
+| |-NestedNameSpecifier
+| | |-IdentifierNameSpecifier
+| | | `-S
+| | `-::
+| |-template
+| `-UnqualifiedId
+|   |-f
+|   |-<
+|   |-int
+|   `->
+|-(
+`-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, QualifiedId_Complex) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 namespace n {
   template<typename T>
@@ -1112,80 +795,33 @@ namespace n {
   };
 }
 void test() {
-  ::n::template ST<int>::template f<int>();
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-|-NamespaceDefinition
-| |-namespace
-| |-n
-| |-{
-| |-TemplateDeclaration
-| | |-template
-| | |-<
-| | |-UnknownDeclaration
-| | | |-typename
-| | | `-T
-| | |->
-| | `-SimpleDeclaration
-| |   |-struct
-| |   |-ST
-| |   |-{
-| |   |-TemplateDeclaration
-| |   | |-template
-| |   | |-<
-| |   | |-UnknownDeclaration
-| |   | | |-typename
-| |   | | `-U
-| |   | |->
-| |   | `-SimpleDeclaration
-| |   |   |-static
-| |   |   |-U
-| |   |   |-SimpleDeclarator
-| |   |   | |-f
-| |   |   | `-ParametersAndQualifiers
-| |   |   |   |-(
-| |   |   |   `-)
-| |   |   `-;
-| |   |-}
-| |   `-;
-| `-}
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-UnknownExpression
-    | | |-IdExpression
-    | | | |-NestedNameSpecifier
-    | | | | |-::
-    | | | | |-IdentifierNameSpecifier
-    | | | | | `-n
-    | | | | |-::
-    | | | | |-SimpleTemplateNameSpecifier
-    | | | | | |-template
-    | | | | | |-ST
-    | | | | | |-<
-    | | | | | |-int
-    | | | | | `->
-    | | | | `-::
-    | | | |-template
-    | | | `-UnqualifiedId
-    | | |   |-f
-    | | |   |-<
-    | | |   |-int
-    | | |   `->
-    | | |-(
-    | | `-)
-    | `-;
-    `-}
-)txt"));
+  [[::n::template ST<int>::template f<int>()]];
+}
+)cpp",
+      {R"txt(
+UnknownExpression
+|-IdExpression
+| |-NestedNameSpecifier
+| | |-::
+| | |-IdentifierNameSpecifier
+| | | `-n
+| | |-::
+| | |-SimpleTemplateNameSpecifier
+| | | |-template
+| | | |-ST
+| | | |-<
+| | | |-int
+| | | `->
+| | `-::
+| |-template
+| `-UnqualifiedId
+|   |-f
+|   |-<
+|   |-int
+|   `->
+|-(
+`-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, QualifiedId_DependentType) {
@@ -1197,255 +833,152 @@ TEST_P(SyntaxTreeTest, QualifiedId_DependentType) {
     // tree when `-fdelayed-template-parsing` is active.
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 template <typename T>
 void test() {
-  T::template U<int>::f();
-  T::U::f();
-  T::template f<0>();
+  [[T::template U<int>::f()]];
+  [[T::U::f()]];
+  [[T::template f<0>()]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-`-TemplateDeclaration
-  |-template
-  |-<
-  |-UnknownDeclaration
-  | |-typename
-  | `-T
-  |->
-  `-SimpleDeclaration
-    |-void
-    |-SimpleDeclarator
-    | |-test
-    | `-ParametersAndQualifiers
-    |   |-(
-    |   `-)
-    `-CompoundStatement
-      |-{
-      |-ExpressionStatement
-      | |-UnknownExpression
-      | | |-IdExpression
-      | | | |-NestedNameSpecifier
-      | | | | |-IdentifierNameSpecifier
-      | | | | | `-T
-      | | | | |-::
-      | | | | |-SimpleTemplateNameSpecifier
-      | | | | | |-template
-      | | | | | |-U
-      | | | | | |-<
-      | | | | | |-int
-      | | | | | `->
-      | | | | `-::
-      | | | `-UnqualifiedId
-      | | |   `-f
-      | | |-(
-      | | `-)
-      | `-;
-      |-ExpressionStatement
-      | |-UnknownExpression
-      | | |-IdExpression
-      | | | |-NestedNameSpecifier
-      | | | | |-IdentifierNameSpecifier
-      | | | | | `-T
-      | | | | |-::
-      | | | | |-IdentifierNameSpecifier
-      | | | | | `-U
-      | | | | `-::
-      | | | `-UnqualifiedId
-      | | |   `-f
-      | | |-(
-      | | `-)
-      | `-;
-      |-ExpressionStatement
-      | |-UnknownExpression
-      | | |-IdExpression
-      | | | |-NestedNameSpecifier
-      | | | | |-IdentifierNameSpecifier
-      | | | | | `-T
-      | | | | `-::
-      | | | |-template
-      | | | `-UnqualifiedId
-      | | |   |-f
-      | | |   |-<
-      | | |   |-IntegerLiteralExpression
-      | | |   | `-0
-      | | |   `->
-      | | |-(
-      | | `-)
-      | `-;
-      `-}
-)txt"));
+      {R"txt(
+UnknownExpression
+|-IdExpression
+| |-NestedNameSpecifier
+| | |-IdentifierNameSpecifier
+| | | `-T
+| | |-::
+| | |-SimpleTemplateNameSpecifier
+| | | |-template
+| | | |-U
+| | | |-<
+| | | |-int
+| | | `->
+| | `-::
+| `-UnqualifiedId
+|   `-f
+|-(
+`-)
+)txt",
+       R"txt(
+UnknownExpression
+|-IdExpression
+| |-NestedNameSpecifier
+| | |-IdentifierNameSpecifier
+| | | `-T
+| | |-::
+| | |-IdentifierNameSpecifier
+| | | `-U
+| | `-::
+| `-UnqualifiedId
+|   `-f
+|-(
+`-)
+)txt",
+       R"txt(
+UnknownExpression
+|-IdExpression
+| |-NestedNameSpecifier
+| | |-IdentifierNameSpecifier
+| | | `-T
+| | `-::
+| |-template
+| `-UnqualifiedId
+|   |-f
+|   |-<
+|   |-IntegerLiteralExpression
+|   | `-0
+|   `->
+|-(
+`-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, ParenExpr) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  (1);
-  ((1));
-  (1 + (2));
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-ParenExpression
-    | | |-(
-    | | |-IntegerLiteralExpression
-    | | | `-1
-    | | `-)
-    | `-;
-    |-ExpressionStatement
-    | |-ParenExpression
-    | | |-(
-    | | |-ParenExpression
-    | | | |-(
-    | | | |-IntegerLiteralExpression
-    | | | | `-1
-    | | | `-)
-    | | `-)
-    | `-;
-    |-ExpressionStatement
-    | |-ParenExpression
-    | | |-(
-    | | |-BinaryOperatorExpression
-    | | | |-IntegerLiteralExpression
-    | | | | `-1
-    | | | |-+
-    | | | `-ParenExpression
-    | | |   |-(
-    | | |   |-IntegerLiteralExpression
-    | | |   | `-2
-    | | |   `-)
-    | | `-)
-    | `-;
-    `-}
-)txt"));
+  [[(1)]];
+  [[((1))]];
+  [[(1 + (2))]];
+}
+)cpp",
+      {R"txt(
+ParenExpression
+|-(
+|-IntegerLiteralExpression
+| `-1
+`-)
+)txt",
+       R"txt(
+ParenExpression
+|-(
+|-ParenExpression
+| |-(
+| |-IntegerLiteralExpression
+| | `-1
+| `-)
+`-)
+)txt",
+       R"txt(
+ParenExpression
+|-(
+|-BinaryOperatorExpression
+| |-IntegerLiteralExpression
+| | `-1
+| |-+
+| `-ParenExpression
+|   |-(
+|   |-IntegerLiteralExpression
+|   | `-2
+|   `-)
+`-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UserDefinedLiteral_Char) {
   if (!GetParam().isCXX11OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 unsigned operator "" _c(char);
 void test() {
-  '2'_c;
+  [['2'_c]];
 }
     )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-unsigned
-| |-SimpleDeclarator
-| | |-operator
-| | |-""
-| | |-_c
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-SimpleDeclaration
-| |   | `-char
-| |   `-)
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-CharUserDefinedLiteralExpression
-    | | `-'2'_c
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+CharUserDefinedLiteralExpression
+`-'2'_c
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UserDefinedLiteral_String) {
   if (!GetParam().isCXX11OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 typedef decltype(sizeof(void *)) size_t;
 
 unsigned operator "" _s(const char*, size_t);
 
 void test() {
-  "12"_s;
+  [["12"_s]];
 }
     )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-typedef
-| |-decltype
-| |-(
-| |-UnknownExpression
-| | |-sizeof
-| | |-(
-| | |-void
-| | |-*
-| | `-)
-| |-)
-| |-SimpleDeclarator
-| | `-size_t
-| `-;
-|-SimpleDeclaration
-| |-unsigned
-| |-SimpleDeclarator
-| | |-operator
-| | |-""
-| | |-_s
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-SimpleDeclaration
-| |   | |-const
-| |   | |-char
-| |   | `-SimpleDeclarator
-| |   |   `-*
-| |   |-,
-| |   |-SimpleDeclaration
-| |   | `-size_t
-| |   `-)
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-StringUserDefinedLiteralExpression
-    | | `-"12"_s
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+StringUserDefinedLiteralExpression
+`-"12"_s
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UserDefinedLiteral_Integer) {
   if (!GetParam().isCXX11OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 unsigned operator "" _i(unsigned long long);
 unsigned operator "" _r(const char*);
@@ -1453,89 +986,30 @@ template <char...>
 unsigned operator "" _t();
 
 void test() {
-  12_i;
-  12_r;
-  12_t;
+  [[12_i]];
+  [[12_r]];
+  [[12_t]];
 }
     )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-unsigned
-| |-SimpleDeclarator
-| | |-operator
-| | |-""
-| | |-_i
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-SimpleDeclaration
-| |   | |-unsigned
-| |   | |-long
-| |   | `-long
-| |   `-)
-| `-;
-|-SimpleDeclaration
-| |-unsigned
-| |-SimpleDeclarator
-| | |-operator
-| | |-""
-| | |-_r
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-SimpleDeclaration
-| |   | |-const
-| |   | |-char
-| |   | `-SimpleDeclarator
-| |   |   `-*
-| |   `-)
-| `-;
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-SimpleDeclaration
-| | `-char
-| |-...
-| |->
-| `-SimpleDeclaration
-|   |-unsigned
-|   |-SimpleDeclarator
-|   | |-operator
-|   | |-""
-|   | |-_t
-|   | `-ParametersAndQualifiers
-|   |   |-(
-|   |   `-)
-|   `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-IntegerUserDefinedLiteralExpression
-    | | `-12_i
-    | `-;
-    |-ExpressionStatement
-    | |-IntegerUserDefinedLiteralExpression
-    | | `-12_r
-    | `-;
-    |-ExpressionStatement
-    | |-IntegerUserDefinedLiteralExpression
-    | | `-12_t
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+IntegerUserDefinedLiteralExpression
+`-12_i
+)txt",
+       R"txt(
+IntegerUserDefinedLiteralExpression
+`-12_r
+)txt",
+       R"txt(
+IntegerUserDefinedLiteralExpression
+`-12_t
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, UserDefinedLiteral_Float) {
   if (!GetParam().isCXX11OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 unsigned operator "" _f(long double);
 unsigned operator "" _r(const char*);
@@ -1543,457 +1017,269 @@ template <char...>
 unsigned operator "" _t();
 
 void test() {
-  1.2_f;  // call: operator "" _f(1.2L)       | kind: float
-  1.2_r;  // call: operator "" _i("1.2")      | kind: float
-  1.2_t;  // call: operator<'1', '2'> "" _x() | kind: float
+  [[1.2_f]];
+  [[1.2_r]];
+  [[1.2_t]];
 }
     )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-unsigned
-| |-SimpleDeclarator
-| | |-operator
-| | |-""
-| | |-_f
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-SimpleDeclaration
-| |   | |-long
-| |   | `-double
-| |   `-)
-| `-;
-|-SimpleDeclaration
-| |-unsigned
-| |-SimpleDeclarator
-| | |-operator
-| | |-""
-| | |-_r
-| | `-ParametersAndQualifiers
-| |   |-(
-| |   |-SimpleDeclaration
-| |   | |-const
-| |   | |-char
-| |   | `-SimpleDeclarator
-| |   |   `-*
-| |   `-)
-| `-;
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-SimpleDeclaration
-| | `-char
-| |-...
-| |->
-| `-SimpleDeclaration
-|   |-unsigned
-|   |-SimpleDeclarator
-|   | |-operator
-|   | |-""
-|   | |-_t
-|   | `-ParametersAndQualifiers
-|   |   |-(
-|   |   `-)
-|   `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-FloatUserDefinedLiteralExpression
-    | | `-1.2_f
-    | `-;
-    |-ExpressionStatement
-    | |-FloatUserDefinedLiteralExpression
-    | | `-1.2_r
-    | `-;
-    |-ExpressionStatement
-    | |-FloatUserDefinedLiteralExpression
-    | | `-1.2_t
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+FloatUserDefinedLiteralExpression
+`-1.2_f
+)txt",
+       R"txt(
+FloatUserDefinedLiteralExpression
+`-1.2_r
+)txt",
+       R"txt(
+FloatUserDefinedLiteralExpression
+`-1.2_t
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, IntegerLiteral_LongLong) {
   if (!GetParam().isCXX11OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  12ll;
-  12ull;
+  [[12ll]];
+  [[12ull]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-IntegerLiteralExpression
-    | | `-12ll
-    | `-;
-    |-ExpressionStatement
-    | |-IntegerLiteralExpression
-    | | `-12ull
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+IntegerLiteralExpression
+`-12ll
+)txt",
+       R"txt(
+IntegerLiteralExpression
+`-12ull
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, IntegerLiteral_Binary) {
   if (!GetParam().isCXX14OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  0b1100;
+  [[0b1100]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-IntegerLiteralExpression
-    | | `-0b1100
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+IntegerLiteralExpression
+`-0b1100
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, IntegerLiteral_WithDigitSeparators) {
   if (!GetParam().isCXX14OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  1'2'0ull;
+  [[1'2'0ull]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-IntegerLiteralExpression
-    | | `-1'2'0ull
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+IntegerLiteralExpression
+`-1'2'0ull
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, CharacterLiteral) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  'a';
-  '\n';
-  '\x20';
-  '\0';
-  L'a';
-  L'α';
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-CharacterLiteralExpression
-    | | `-'a'
-    | `-;
-    |-ExpressionStatement
-    | |-CharacterLiteralExpression
-    | | `-'\n'
-    | `-;
-    |-ExpressionStatement
-    | |-CharacterLiteralExpression
-    | | `-'\x20'
-    | `-;
-    |-ExpressionStatement
-    | |-CharacterLiteralExpression
-    | | `-'\0'
-    | `-;
-    |-ExpressionStatement
-    | |-CharacterLiteralExpression
-    | | `-L'a'
-    | `-;
-    |-ExpressionStatement
-    | |-CharacterLiteralExpression
-    | | `-L'α'
-    | `-;
-    `-}
-)txt"));
+  [['a']];
+  [['\n']];
+  [['\x20']];
+  [['\0']];
+  [[L'a']];
+  [[L'α']];
+}
+)cpp",
+      {R"txt(
+CharacterLiteralExpression
+`-'a'
+)txt",
+       R"txt(
+CharacterLiteralExpression
+`-'\n'
+)txt",
+       R"txt(
+CharacterLiteralExpression
+`-'\x20'
+)txt",
+       R"txt(
+CharacterLiteralExpression
+`-'\0'
+)txt",
+       R"txt(
+CharacterLiteralExpression
+`-L'a'
+)txt",
+       R"txt(
+CharacterLiteralExpression
+`-L'α'
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, CharacterLiteral_Utf) {
   if (!GetParam().isCXX11OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  u'a';
-  u'構';
-  U'a';
-  U'🌲';
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-CharacterLiteralExpression
-    | | `-u'a'
-    | `-;
-    |-ExpressionStatement
-    | |-CharacterLiteralExpression
-    | | `-u'構'
-    | `-;
-    |-ExpressionStatement
-    | |-CharacterLiteralExpression
-    | | `-U'a'
-    | `-;
-    |-ExpressionStatement
-    | |-CharacterLiteralExpression
-    | | `-U'🌲'
-    | `-;
-    `-}
-)txt"));
+  [[u'a']];
+  [[u'構']];
+  [[U'a']];
+  [[U'🌲']];
+}
+)cpp",
+      {R"txt(
+CharacterLiteralExpression
+`-u'a'
+)txt",
+       R"txt(
+CharacterLiteralExpression
+`-u'構'
+)txt",
+       R"txt(
+CharacterLiteralExpression
+`-U'a'
+)txt",
+       R"txt(
+CharacterLiteralExpression
+`-U'🌲'
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, CharacterLiteral_Utf8) {
   if (!GetParam().isCXX17OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  u8'a';
-  u8'\x7f';
+  [[u8'a']];
+  [[u8'\x7f']];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-CharacterLiteralExpression
-    | | `-u8'a'
-    | `-;
-    |-ExpressionStatement
-    | |-CharacterLiteralExpression
-    | | `-u8'\x7f'
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+CharacterLiteralExpression
+`-u8'a'
+)txt",
+       R"txt(
+CharacterLiteralExpression
+`-u8'\x7f'
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, FloatingLiteral) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  1e-2;
-  2.;
-  .2;
-  2.f;
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-FloatingLiteralExpression
-    | | `-1e-2
-    | `-;
-    |-ExpressionStatement
-    | |-FloatingLiteralExpression
-    | | `-2.
-    | `-;
-    |-ExpressionStatement
-    | |-FloatingLiteralExpression
-    | | `-.2
-    | `-;
-    |-ExpressionStatement
-    | |-FloatingLiteralExpression
-    | | `-2.f
-    | `-;
-    `-}
-)txt"));
+  [[1e-2]];
+  [[2.]];
+  [[.2]];
+  [[2.f]];
+}
+)cpp",
+      {R"txt(
+FloatingLiteralExpression
+`-1e-2
+)txt",
+       R"txt(
+FloatingLiteralExpression
+`-2.
+)txt",
+       R"txt(
+FloatingLiteralExpression
+`-.2
+)txt",
+       R"txt(
+FloatingLiteralExpression
+`-2.f
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, FloatingLiteral_Hexadecimal) {
   if (!GetParam().isCXX17OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+      R"cpp(
+void test() {
+  [[0xfp1]];
+  [[0xf.p1]];
+  [[0x.fp1]];
+  [[0xf.fp1f]];
+}
+)cpp",
+      {R"txt(
+FloatingLiteralExpression
+`-0xfp1
+)txt",
+       R"txt(
+FloatingLiteralExpression
+`-0xf.p1
+)txt",
+       R"txt(
+FloatingLiteralExpression
+`-0x.fp1
+)txt",
+       R"txt(
+FloatingLiteralExpression
+`-0xf.fp1f
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, StringLiteral) {
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  0xfp1;
-  0xf.p1;
-  0x.fp1;
-  0xf.fp1f;
+  [["a\n\0\x20"]];
+  [[L"αβ"]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-FloatingLiteralExpression
-    | | `-0xfp1
-    | `-;
-    |-ExpressionStatement
-    | |-FloatingLiteralExpression
-    | | `-0xf.p1
-    | `-;
-    |-ExpressionStatement
-    | |-FloatingLiteralExpression
-    | | `-0x.fp1
-    | `-;
-    |-ExpressionStatement
-    | |-FloatingLiteralExpression
-    | | `-0xf.fp1f
-    | `-;
-    `-}
-)txt"));
-}
-
-TEST_P(SyntaxTreeTest, StringLiteral) {
-  EXPECT_TRUE(treeDumpEqual(
-      R"cpp(
-void test() {
-  "a\n\0\x20";
-  L"αβ";
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-StringLiteralExpression
-    | | `-"a\n\0\x20"
-    | `-;
-    |-ExpressionStatement
-    | |-StringLiteralExpression
-    | | `-L"αβ"
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+StringLiteralExpression
+`-"a\n\0\x20"
+)txt",
+       R"txt(
+StringLiteralExpression
+`-L"αβ"
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, StringLiteral_Utf) {
   if (!GetParam().isCXX11OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  u8"a\x1f\x05";
-  u"C++抽象構文木";
-  U"📖🌲\n";
+  [[u8"a\x1f\x05"]];
+  [[u"C++抽象構文木"]];
+  [[U"📖🌲\n"]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-StringLiteralExpression
-    | | `-u8"a\x1f\x05"
-    | `-;
-    |-ExpressionStatement
-    | |-StringLiteralExpression
-    | | `-u"C++抽象構文木"
-    | `-;
-    |-ExpressionStatement
-    | |-StringLiteralExpression
-    | | `-U"📖🌲\n"
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+StringLiteralExpression
+`-u8"a\x1f\x05"
+)txt",
+       R"txt(
+StringLiteralExpression
+`-u"C++抽象構文木"
+)txt",
+       R"txt(
+StringLiteralExpression
+`-U"📖🌲\n"
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, StringLiteral_Raw) {
@@ -2033,1221 +1319,646 @@ TEST_P(SyntaxTreeTest, BoolLiteral) {
   if (GetParam().isC()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  true;
-  false;
+  [[true]];
+  [[false]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-BoolLiteralExpression
-    | | `-true
-    | `-;
-    |-ExpressionStatement
-    | |-BoolLiteralExpression
-    | | `-false
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+BoolLiteralExpression
+`-true
+)txt",
+       R"txt(
+BoolLiteralExpression
+`-false
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, CxxNullPtrLiteral) {
   if (!GetParam().isCXX11OrLater()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  nullptr;
+  [[nullptr]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-CxxNullPtrExpression
-    | | `-nullptr
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+CxxNullPtrExpression
+`-nullptr
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, PostfixUnaryOperator) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test(int a) {
-  a++;
-  a--;
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   `-a
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-PostfixUnaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-a
-    | | `-++
-    | `-;
-    |-ExpressionStatement
-    | |-PostfixUnaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-a
-    | | `---
-    | `-;
-    `-}
-)txt"));
+  [[a++]];
+  [[a--]];
+}
+)cpp",
+      {R"txt(
+PostfixUnaryOperatorExpression
+|-IdExpression
+| `-UnqualifiedId
+|   `-a
+`-++
+)txt",
+       R"txt(
+PostfixUnaryOperatorExpression
+|-IdExpression
+| `-UnqualifiedId
+|   `-a
+`---
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, PrefixUnaryOperator) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test(int a, int *ap) {
-  --a; ++a;
-  ~a;
-  -a;
-  +a;
-  &a;
-  *ap;
-  !a;
-  __real a; __imag a;
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   `-a
-  |   |-,
-  |   |-SimpleDeclaration
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   |-*
-  |   |   `-ap
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |---
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-a
-    | `-;
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |-++
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-a
-    | `-;
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |-~
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-a
-    | `-;
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |--
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-a
-    | `-;
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |-+
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-a
-    | `-;
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |-&
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-a
-    | `-;
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |-*
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-ap
-    | `-;
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |-!
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-a
-    | `-;
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |-__real
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-a
-    | `-;
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |-__imag
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-a
-    | `-;
-    `-}
-)txt"));
+  [[--a]]; [[++a]];
+  [[~a]];
+  [[-a]];
+  [[+a]];
+  [[&a]];
+  [[*ap]];
+  [[!a]];
+  [[__real a]]; [[__imag a]];
+}
+)cpp",
+      {R"txt(
+PrefixUnaryOperatorExpression
+|---
+`-IdExpression
+  `-UnqualifiedId
+    `-a
+)txt",
+       R"txt(
+PrefixUnaryOperatorExpression
+|-++
+`-IdExpression
+  `-UnqualifiedId
+    `-a
+)txt",
+       R"txt(
+PrefixUnaryOperatorExpression
+|-~
+`-IdExpression
+  `-UnqualifiedId
+    `-a
+)txt",
+       R"txt(
+PrefixUnaryOperatorExpression
+|--
+`-IdExpression
+  `-UnqualifiedId
+    `-a
+)txt",
+       R"txt(
+PrefixUnaryOperatorExpression
+|-+
+`-IdExpression
+  `-UnqualifiedId
+    `-a
+)txt",
+       R"txt(
+PrefixUnaryOperatorExpression
+|-&
+`-IdExpression
+  `-UnqualifiedId
+    `-a
+)txt",
+       R"txt(
+PrefixUnaryOperatorExpression
+|-*
+`-IdExpression
+  `-UnqualifiedId
+    `-ap
+)txt",
+       R"txt(
+PrefixUnaryOperatorExpression
+|-!
+`-IdExpression
+  `-UnqualifiedId
+    `-a
+)txt",
+       R"txt(
+PrefixUnaryOperatorExpression
+|-__real
+`-IdExpression
+  `-UnqualifiedId
+    `-a
+)txt",
+       R"txt(
+PrefixUnaryOperatorExpression
+|-__imag
+`-IdExpression
+  `-UnqualifiedId
+    `-a
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, PrefixUnaryOperatorCxx) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test(int a, bool b) {
-  compl a;
-  not b;
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   `-a
-  |   |-,
-  |   |-SimpleDeclaration
-  |   | |-bool
-  |   | `-SimpleDeclarator
-  |   |   `-b
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |-compl
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-a
-    | `-;
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |-not
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-b
-    | `-;
-    `-}
-)txt"));
+  [[compl a]];
+  [[not b]];
+}
+)cpp",
+      {R"txt(
+PrefixUnaryOperatorExpression
+|-compl
+`-IdExpression
+  `-UnqualifiedId
+    `-a
+)txt",
+       R"txt(
+PrefixUnaryOperatorExpression
+|-not
+`-IdExpression
+  `-UnqualifiedId
+    `-b
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, BinaryOperator) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test(int a) {
-  1 - 2;
-  1 == 2;
-  a = 1;
-  a <<= 1;
-  1 || 0;
-  1 & 2;
-  a ^= 3;
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   `-a
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IntegerLiteralExpression
-    | | | `-1
-    | | |--
-    | | `-IntegerLiteralExpression
-    | |   `-2
-    | `-;
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IntegerLiteralExpression
-    | | | `-1
-    | | |-==
-    | | `-IntegerLiteralExpression
-    | |   `-2
-    | `-;
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-a
-    | | |-=
-    | | `-IntegerLiteralExpression
-    | |   `-1
-    | `-;
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-a
-    | | |-<<=
-    | | `-IntegerLiteralExpression
-    | |   `-1
-    | `-;
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IntegerLiteralExpression
-    | | | `-1
-    | | |-||
-    | | `-IntegerLiteralExpression
-    | |   `-0
-    | `-;
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IntegerLiteralExpression
-    | | | `-1
-    | | |-&
-    | | `-IntegerLiteralExpression
-    | |   `-2
-    | `-;
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-a
-    | | |-^=
-    | | `-IntegerLiteralExpression
-    | |   `-3
-    | `-;
-    `-}
-)txt"));
+  [[1 - 2]];
+  [[1 == 2]];
+  [[a = 1]];
+  [[a <<= 1]];
+  [[1 || 0]];
+  [[1 & 2]];
+  [[a != 3]];
+}
+)cpp",
+      {R"txt(
+BinaryOperatorExpression
+|-IntegerLiteralExpression
+| `-1
+|--
+`-IntegerLiteralExpression
+  `-2
+)txt",
+       R"txt(
+BinaryOperatorExpression
+|-IntegerLiteralExpression
+| `-1
+|-==
+`-IntegerLiteralExpression
+  `-2
+)txt",
+       R"txt(
+BinaryOperatorExpression
+|-IdExpression
+| `-UnqualifiedId
+|   `-a
+|-=
+`-IntegerLiteralExpression
+  `-1
+)txt",
+       R"txt(
+BinaryOperatorExpression
+|-IdExpression
+| `-UnqualifiedId
+|   `-a
+|-<<=
+`-IntegerLiteralExpression
+  `-1
+)txt",
+       R"txt(
+BinaryOperatorExpression
+|-IntegerLiteralExpression
+| `-1
+|-||
+`-IntegerLiteralExpression
+  `-0
+)txt",
+       R"txt(
+BinaryOperatorExpression
+|-IntegerLiteralExpression
+| `-1
+|-&
+`-IntegerLiteralExpression
+  `-2
+)txt",
+       R"txt(
+BinaryOperatorExpression
+|-IdExpression
+| `-UnqualifiedId
+|   `-a
+|-!=
+`-IntegerLiteralExpression
+  `-3
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, BinaryOperatorCxx) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test(int a) {
-  true || false;
-  true or false;
-  1 bitand 2;
-  a xor_eq 3;
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   `-a
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-BoolLiteralExpression
-    | | | `-true
-    | | |-||
-    | | `-BoolLiteralExpression
-    | |   `-false
-    | `-;
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-BoolLiteralExpression
-    | | | `-true
-    | | |-or
-    | | `-BoolLiteralExpression
-    | |   `-false
-    | `-;
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IntegerLiteralExpression
-    | | | `-1
-    | | |-bitand
-    | | `-IntegerLiteralExpression
-    | |   `-2
-    | `-;
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-a
-    | | |-xor_eq
-    | | `-IntegerLiteralExpression
-    | |   `-3
-    | `-;
-    `-}
-)txt"));
+  [[true || false]];
+  [[true or false]];
+  [[1 bitand 2]];
+  [[a xor_eq 3]];
+}
+)cpp",
+      {R"txt(
+BinaryOperatorExpression
+|-BoolLiteralExpression
+| `-true
+|-||
+`-BoolLiteralExpression
+  `-false
+)txt",
+       R"txt(
+BinaryOperatorExpression
+|-BoolLiteralExpression
+| `-true
+|-or
+`-BoolLiteralExpression
+  `-false
+)txt",
+       R"txt(
+BinaryOperatorExpression
+|-IntegerLiteralExpression
+| `-1
+|-bitand
+`-IntegerLiteralExpression
+  `-2
+)txt",
+       R"txt(
+BinaryOperatorExpression
+|-IdExpression
+| `-UnqualifiedId
+|   `-a
+|-xor_eq
+`-IntegerLiteralExpression
+  `-3
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, BinaryOperator_NestedWithParenthesis) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  (1 + 2) * (4 / 2);
+  [[(1 + 2) * (4 / 2)]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-ParenExpression
-    | | | |-(
-    | | | |-BinaryOperatorExpression
-    | | | | |-IntegerLiteralExpression
-    | | | | | `-1
-    | | | | |-+
-    | | | | `-IntegerLiteralExpression
-    | | | |   `-2
-    | | | `-)
-    | | |-*
-    | | `-ParenExpression
-    | |   |-(
-    | |   |-BinaryOperatorExpression
-    | |   | |-IntegerLiteralExpression
-    | |   | | `-4
-    | |   | |-/
-    | |   | `-IntegerLiteralExpression
-    | |   |   `-2
-    | |   `-)
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+BinaryOperatorExpression
+|-ParenExpression
+| |-(
+| |-BinaryOperatorExpression
+| | |-IntegerLiteralExpression
+| | | `-1
+| | |-+
+| | `-IntegerLiteralExpression
+| |   `-2
+| `-)
+|-*
+`-ParenExpression
+  |-(
+  |-BinaryOperatorExpression
+  | |-IntegerLiteralExpression
+  | | `-4
+  | |-/
+  | `-IntegerLiteralExpression
+  |   `-2
+  `-)
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, BinaryOperator_Associativity) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test(int a, int b) {
-  a + b + 42;
-  a = b = 42;
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   `-a
-  |   |-,
-  |   |-SimpleDeclaration
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   `-b
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-BinaryOperatorExpression
-    | | | |-IdExpression
-    | | | | `-UnqualifiedId
-    | | | |   `-a
-    | | | |-+
-    | | | `-IdExpression
-    | | |   `-UnqualifiedId
-    | | |     `-b
-    | | |-+
-    | | `-IntegerLiteralExpression
-    | |   `-42
-    | `-;
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-a
-    | | |-=
-    | | `-BinaryOperatorExpression
-    | |   |-IdExpression
-    | |   | `-UnqualifiedId
-    | |   |   `-b
-    | |   |-=
-    | |   `-IntegerLiteralExpression
-    | |     `-42
-    | `-;
-    `-}
-)txt"));
+  [[a + b + 42]];
+  [[a = b = 42]];
+}
+)cpp",
+      {R"txt(
+BinaryOperatorExpression
+|-BinaryOperatorExpression
+| |-IdExpression
+| | `-UnqualifiedId
+| |   `-a
+| |-+
+| `-IdExpression
+|   `-UnqualifiedId
+|     `-b
+|-+
+`-IntegerLiteralExpression
+  `-42
+)txt",
+       R"txt(
+BinaryOperatorExpression
+|-IdExpression
+| `-UnqualifiedId
+|   `-a
+|-=
+`-BinaryOperatorExpression
+  |-IdExpression
+  | `-UnqualifiedId
+  |   `-b
+  |-=
+  `-IntegerLiteralExpression
+    `-42
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, BinaryOperator_Precedence) {
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 void test() {
-  1 + 2 * 3 + 4;
-  1 % 2 + 3 * 4;
-}
-)cpp",
-      R"txt(
-*: TranslationUnit
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-BinaryOperatorExpression
-    | | | |-IntegerLiteralExpression
-    | | | | `-1
-    | | | |-+
-    | | | `-BinaryOperatorExpression
-    | | |   |-IntegerLiteralExpression
-    | | |   | `-2
-    | | |   |-*
-    | | |   `-IntegerLiteralExpression
-    | | |     `-3
-    | | |-+
-    | | `-IntegerLiteralExpression
-    | |   `-4
-    | `-;
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-BinaryOperatorExpression
-    | | | |-IntegerLiteralExpression
-    | | | | `-1
-    | | | |-%
-    | | | `-IntegerLiteralExpression
-    | | |   `-2
-    | | |-+
-    | | `-BinaryOperatorExpression
-    | |   |-IntegerLiteralExpression
-    | |   | `-3
-    | |   |-*
-    | |   `-IntegerLiteralExpression
-    | |     `-4
-    | `-;
-    `-}
-)txt"));
+  [[1 + 2 * 3 + 4]];
+  [[1 % 2 + 3 * 4]];
+}
+)cpp",
+      {R"txt(
+BinaryOperatorExpression
+|-BinaryOperatorExpression
+| |-IntegerLiteralExpression
+| | `-1
+| |-+
+| `-BinaryOperatorExpression
+|   |-IntegerLiteralExpression
+|   | `-2
+|   |-*
+|   `-IntegerLiteralExpression
+|     `-3
+|-+
+`-IntegerLiteralExpression
+  `-4
+)txt",
+       R"txt(
+BinaryOperatorExpression
+|-BinaryOperatorExpression
+| |-IntegerLiteralExpression
+| | `-1
+| |-%
+| `-IntegerLiteralExpression
+|   `-2
+|-+
+`-BinaryOperatorExpression
+  |-IntegerLiteralExpression
+  | `-3
+  |-*
+  `-IntegerLiteralExpression
+    `-4
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, OverloadedOperator_Assignment) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X {
   X& operator=(const X&);
 };
 void test(X x, X y) {
-  x = y;
+  [[x = y]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-SimpleDeclaration
-| | |-X
-| | |-SimpleDeclarator
-| | | |-&
-| | | |-operator
-| | | |-=
-| | | `-ParametersAndQualifiers
-| | |   |-(
-| | |   |-SimpleDeclaration
-| | |   | |-const
-| | |   | |-X
-| | |   | `-SimpleDeclarator
-| | |   |   `-&
-| | |   `-)
-| | `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   |-,
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-y
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-x
-    | | |-=
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-y
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+BinaryOperatorExpression
+|-IdExpression
+| `-UnqualifiedId
+|   `-x
+|-=
+`-IdExpression
+  `-UnqualifiedId
+    `-y
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, OverloadedOperator_Plus) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X {
   friend X operator+(X, const X&);
 };
 void test(X x, X y) {
-  x + y;
+  [[x + y]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-UnknownDeclaration
-| | `-SimpleDeclaration
-| |   |-friend
-| |   |-X
-| |   |-SimpleDeclarator
-| |   | |-operator
-| |   | |-+
-| |   | `-ParametersAndQualifiers
-| |   |   |-(
-| |   |   |-SimpleDeclaration
-| |   |   | `-X
-| |   |   |-,
-| |   |   |-SimpleDeclaration
-| |   |   | |-const
-| |   |   | |-X
-| |   |   | `-SimpleDeclarator
-| |   |   |   `-&
-| |   |   `-)
-| |   `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   |-,
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-y
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-UnknownExpression
-    | | | `-IdExpression
-    | | |   `-UnqualifiedId
-    | | |     `-x
-    | | |-+
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-y
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+BinaryOperatorExpression
+|-UnknownExpression
+| `-IdExpression
+|   `-UnqualifiedId
+|     `-x
+|-+
+`-IdExpression
+  `-UnqualifiedId
+    `-y
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, OverloadedOperator_Less) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X {
   friend bool operator<(const X&, const X&);
 };
 void test(X x, X y) {
-  x < y;
+  [[x < y]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-UnknownDeclaration
-| | `-SimpleDeclaration
-| |   |-friend
-| |   |-bool
-| |   |-SimpleDeclarator
-| |   | |-operator
-| |   | |-<
-| |   | `-ParametersAndQualifiers
-| |   |   |-(
-| |   |   |-SimpleDeclaration
-| |   |   | |-const
-| |   |   | |-X
-| |   |   | `-SimpleDeclarator
-| |   |   |   `-&
-| |   |   |-,
-| |   |   |-SimpleDeclaration
-| |   |   | |-const
-| |   |   | |-X
-| |   |   | `-SimpleDeclarator
-| |   |   |   `-&
-| |   |   `-)
-| |   `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   |-,
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-y
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-x
-    | | |-<
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-y
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+BinaryOperatorExpression
+|-IdExpression
+| `-UnqualifiedId
+|   `-x
+|-<
+`-IdExpression
+  `-UnqualifiedId
+    `-y
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, OverloadedOperator_LeftShift) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X {
   friend X operator<<(X&, const X&);
 };
 void test(X x, X y) {
-  x << y;
+  [[x << y]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-UnknownDeclaration
-| | `-SimpleDeclaration
-| |   |-friend
-| |   |-X
-| |   |-SimpleDeclarator
-| |   | |-operator
-| |   | |-<<
-| |   | `-ParametersAndQualifiers
-| |   |   |-(
-| |   |   |-SimpleDeclaration
-| |   |   | |-X
-| |   |   | `-SimpleDeclarator
-| |   |   |   `-&
-| |   |   |-,
-| |   |   |-SimpleDeclaration
-| |   |   | |-const
-| |   |   | |-X
-| |   |   | `-SimpleDeclarator
-| |   |   |   `-&
-| |   |   `-)
-| |   `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   |-,
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-y
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-x
-    | | |-<<
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-y
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+BinaryOperatorExpression
+|-IdExpression
+| `-UnqualifiedId
+|   `-x
+|-<<
+`-IdExpression
+  `-UnqualifiedId
+    `-y
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, OverloadedOperator_Comma) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X {
   X operator,(X&);
 };
 void test(X x, X y) {
-  x, y;
+  [[x, y]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-SimpleDeclaration
-| | |-X
-| | |-SimpleDeclarator
-| | | |-operator
-| | | |-,
-| | | `-ParametersAndQualifiers
-| | |   |-(
-| | |   |-SimpleDeclaration
-| | |   | |-X
-| | |   | `-SimpleDeclarator
-| | |   |   `-&
-| | |   `-)
-| | `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   |-,
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-y
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-x
-    | | |-,
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-y
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+BinaryOperatorExpression
+|-IdExpression
+| `-UnqualifiedId
+|   `-x
+|-,
+`-IdExpression
+  `-UnqualifiedId
+    `-y
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, OverloadedOperator_PointerToMember) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X {
   X operator->*(int);
 };
 void test(X* xp, int X::* pmi) {
-  xp->*pmi;
+  [[xp->*pmi]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-SimpleDeclaration
-| | |-X
-| | |-SimpleDeclarator
-| | | |-operator
-| | | |-->*
-| | | `-ParametersAndQualifiers
-| | |   |-(
-| | |   |-SimpleDeclaration
-| | |   | `-int
-| | |   `-)
-| | `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   |-*
-  |   |   `-xp
-  |   |-,
-  |   |-SimpleDeclaration
-  |   | |-int
-  |   | `-SimpleDeclarator
-  |   |   |-MemberPointer
-  |   |   | |-X
-  |   |   | |-::
-  |   |   | `-*
-  |   |   `-pmi
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-BinaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-xp
-    | | |-->*
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-pmi
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+BinaryOperatorExpression
+|-IdExpression
+| `-UnqualifiedId
+|   `-xp
+|-->*
+`-IdExpression
+  `-UnqualifiedId
+    `-pmi
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, OverloadedOperator_Negation) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X {
   bool operator!();
 };
 void test(X x) {
-  !x;
+  [[!x]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-SimpleDeclaration
-| | |-bool
-| | |-SimpleDeclarator
-| | | |-operator
-| | | |-!
-| | | `-ParametersAndQualifiers
-| | |   |-(
-| | |   `-)
-| | `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |-!
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-x
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+PrefixUnaryOperatorExpression
+|-!
+`-IdExpression
+  `-UnqualifiedId
+    `-x
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, OverloadedOperator_AddressOf) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X {
   X* operator&();
 };
 void test(X x) {
-  &x;
+  [[&x]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-SimpleDeclaration
-| | |-X
-| | |-SimpleDeclarator
-| | | |-*
-| | | |-operator
-| | | |-&
-| | | `-ParametersAndQualifiers
-| | |   |-(
-| | |   `-)
-| | `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |-&
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-x
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+PrefixUnaryOperatorExpression
+|-&
+`-IdExpression
+  `-UnqualifiedId
+    `-x
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, OverloadedOperator_PrefixIncrement) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X {
   X operator++();
 };
 void test(X x) {
-  ++x;
+  [[++x]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-SimpleDeclaration
-| | |-X
-| | |-SimpleDeclarator
-| | | |-operator
-| | | |-++
-| | | `-ParametersAndQualifiers
-| | |   |-(
-| | |   `-)
-| | `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-PrefixUnaryOperatorExpression
-    | | |-++
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-x
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+PrefixUnaryOperatorExpression
+|-++
+`-IdExpression
+  `-UnqualifiedId
+    `-x
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, OverloadedOperator_PostfixIncrement) {
   if (!GetParam().isCXX()) {
     return;
   }
-  EXPECT_TRUE(treeDumpEqual(
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
 struct X {
   X operator++(int);
 };
 void test(X x) {
-  x++;
+  [[x++]];
 }
 )cpp",
-      R"txt(
-*: TranslationUnit
-|-SimpleDeclaration
-| |-struct
-| |-X
-| |-{
-| |-SimpleDeclaration
-| | |-X
-| | |-SimpleDeclarator
-| | | |-operator
-| | | |-++
-| | | `-ParametersAndQualifiers
-| | |   |-(
-| | |   |-SimpleDeclaration
-| | |   | `-int
-| | |   `-)
-| | `-;
-| |-}
-| `-;
-`-SimpleDeclaration
-  |-void
-  |-SimpleDeclarator
-  | |-test
-  | `-ParametersAndQualifiers
-  |   |-(
-  |   |-SimpleDeclaration
-  |   | |-X
-  |   | `-SimpleDeclarator
-  |   |   `-x
-  |   `-)
-  `-CompoundStatement
-    |-{
-    |-ExpressionStatement
-    | |-PostfixUnaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-x
-    | | `-++
-    | `-;
-    `-}
-)txt"));
+      {R"txt(
+PostfixUnaryOperatorExpression
+|-IdExpression
+| `-UnqualifiedId
+|   `-x
+`-++
+)txt"}));
 }
 
 TEST_P(SyntaxTreeTest, MultipleDeclaratorsGrouping) {
@@ -3343,6 +2054,33 @@ void foo() {
 )txt"));
 }
 
+TEST_P(SyntaxTreeTest, SizeTTypedef) {
+  if (!GetParam().isCXX11OrLater()) {
+    return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+      R"cpp(
+typedef decltype(sizeof(void *)) size_t;
+    )cpp",
+      R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-typedef
+  |-decltype
+  |-(
+  |-UnknownExpression
+  | |-sizeof
+  | |-(
+  | |-void
+  | |-*
+  | `-)
+  |-)
+  |-SimpleDeclarator
+  | `-size_t
+  `-;
+)txt"));
+}
+
 TEST_P(SyntaxTreeTest, Namespaces) {
   if (!GetParam().isCXX()) {
     return;
@@ -3496,68 +2234,318 @@ struct {} *a1;
 )txt"));
 }
 
-TEST_P(SyntaxTreeTest, Templates) {
+TEST_P(SyntaxTreeTest, StaticMemberFunction) {
+  if (!GetParam().isCXX11OrLater()) {
+    return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+      R"cpp(
+struct S {
+  static void f(){}
+};
+)cpp",
+      R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-struct
+  |-S
+  |-{
+  |-SimpleDeclaration
+  | |-static
+  | |-void
+  | |-SimpleDeclarator
+  | | |-f
+  | | `-ParametersAndQualifiers
+  | |   |-(
+  | |   `-)
+  | `-CompoundStatement
+  |   |-{
+  |   `-}
+  |-}
+  `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, ConversionMemberFunction) {
   if (!GetParam().isCXX()) {
     return;
   }
-  if (GetParam().hasDelayedTemplateParsing()) {
-    // FIXME: Make this test work on Windows by generating the expected syntax
-    // tree when `-fdelayed-template-parsing` is active.
+  EXPECT_TRUE(treeDumpEqual(
+      R"cpp(
+struct X {
+  operator int();
+};
+)cpp",
+      R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-struct
+  |-X
+  |-{
+  |-SimpleDeclaration
+  | |-SimpleDeclarator
+  | | |-operator
+  | | |-int
+  | | `-ParametersAndQualifiers
+  | |   |-(
+  | |   `-)
+  | `-;
+  |-}
+  `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, LiteralOperatorDeclaration) {
+  if (!GetParam().isCXX11OrLater()) {
+    return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+      R"cpp(
+unsigned operator "" _c(char);
+    )cpp",
+      R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-unsigned
+  |-SimpleDeclarator
+  | |-operator
+  | |-""
+  | |-_c
+  | `-ParametersAndQualifiers
+  |   |-(
+  |   |-SimpleDeclaration
+  |   | `-char
+  |   `-)
+  `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, NumericLiteralOperatorTemplateDeclaration) {
+  if (!GetParam().isCXX11OrLater()) {
+    return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+      R"cpp(
+template <char...>
+unsigned operator "" _t();
+    )cpp",
+      R"txt(
+*: TranslationUnit
+`-TemplateDeclaration
+  |-template
+  |-<
+  |-SimpleDeclaration
+  | `-char
+  |-...
+  |->
+  `-SimpleDeclaration
+    |-unsigned
+    |-SimpleDeclarator
+    | |-operator
+    | |-""
+    | |-_t
+    | `-ParametersAndQualifiers
+    |   |-(
+    |   `-)
+    `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, OverloadedOperatorDeclaration) {
+  if (!GetParam().isCXX()) {
     return;
   }
   EXPECT_TRUE(treeDumpEqual(
       R"cpp(
-template <class T> struct cls {};
-template <class T> int var = 10;
-template <class T> int fun() {}
+struct X {
+  X& operator=(const X&);
+};
+)cpp",
+      R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-struct
+  |-X
+  |-{
+  |-SimpleDeclaration
+  | |-X
+  | |-SimpleDeclarator
+  | | |-&
+  | | |-operator
+  | | |-=
+  | | `-ParametersAndQualifiers
+  | |   |-(
+  | |   |-SimpleDeclaration
+  | |   | |-const
+  | |   | |-X
+  | |   | `-SimpleDeclarator
+  | |   |   `-&
+  | |   `-)
+  | `-;
+  |-}
+  `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, OverloadedOperatorFriendDeclarataion) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+      R"cpp(
+struct X {
+  friend X operator+(X, const X&);
+};
+)cpp",
+      R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-struct
+  |-X
+  |-{
+  |-UnknownDeclaration
+  | `-SimpleDeclaration
+  |   |-friend
+  |   |-X
+  |   |-SimpleDeclarator
+  |   | |-operator
+  |   | |-+
+  |   | `-ParametersAndQualifiers
+  |   |   |-(
+  |   |   |-SimpleDeclaration
+  |   |   | `-X
+  |   |   |-,
+  |   |   |-SimpleDeclaration
+  |   |   | |-const
+  |   |   | |-X
+  |   |   | `-SimpleDeclarator
+  |   |   |   `-&
+  |   |   `-)
+  |   `-;
+  |-}
+  `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, ClassTemplateDeclaration) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+      R"cpp(
+template<typename T>
+struct ST {};
 )cpp",
       R"txt(
 *: TranslationUnit
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-UnknownDeclaration
-| | |-class
-| | `-T
-| |->
-| `-SimpleDeclaration
-|   |-struct
-|   |-cls
-|   |-{
-|   |-}
-|   `-;
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-UnknownDeclaration
-| | |-class
-| | `-T
-| |->
-| `-SimpleDeclaration
-|   |-int
-|   |-SimpleDeclarator
-|   | |-var
-|   | |-=
-|   | `-IntegerLiteralExpression
-|   |   `-10
-|   `-;
 `-TemplateDeclaration
   |-template
   |-<
   |-UnknownDeclaration
-  | |-class
+  | |-typename
+  | `-T
+  |->
+  `-SimpleDeclaration
+    |-struct
+    |-ST
+    |-{
+    |-}
+    `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, FunctionTemplateDeclaration) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+      R"cpp(
+template<typename T>
+T f();
+)cpp",
+      R"txt(
+*: TranslationUnit
+`-TemplateDeclaration
+  |-template
+  |-<
+  |-UnknownDeclaration
+  | |-typename
   | `-T
   |->
   `-SimpleDeclaration
-    |-int
+    |-T
     |-SimpleDeclarator
-    | |-fun
+    | |-f
     | `-ParametersAndQualifiers
     |   |-(
     |   `-)
-    `-CompoundStatement
-      |-{
-      `-}
+    `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, VariableTemplateDeclaration) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+      R"cpp(
+template <class T> T var = 10;
+)cpp",
+      R"txt(
+*: TranslationUnit
+`-TemplateDeclaration
+  |-template
+  |-<
+  |-UnknownDeclaration
+  | |-class
+  | `-T
+  |->
+  `-SimpleDeclaration
+    |-T
+    |-SimpleDeclarator
+    | |-var
+    | |-=
+    | `-IntegerLiteralExpression
+    |   `-10
+    `-;
+)txt"));
+}
+
+TEST_P(SyntaxTreeTest, StaticMemberFunctionTemplate) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+      R"cpp(
+struct S {
+  template<typename U>
+  static U f();
+};
+)cpp",
+      R"txt(
+*: TranslationUnit
+`-SimpleDeclaration
+  |-struct
+  |-S
+  |-{
+  |-TemplateDeclaration
+  | |-template
+  | |-<
+  | |-UnknownDeclaration
+  | | |-typename
+  | | `-U
+  | |->
+  | `-SimpleDeclaration
+  |   |-static
+  |   |-U
+  |   |-SimpleDeclarator
+  |   | |-f
+  |   | `-ParametersAndQualifiers
+  |   |   |-(
+  |   |   `-)
+  |   `-;
+  |-}
+  `-;
 )txt"));
 }
 
@@ -3606,6 +2594,59 @@ struct X {
 )txt"));
 }
 
+TEST_P(SyntaxTreeTest, NestedTemplatesInNamespace) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  EXPECT_TRUE(treeDumpEqual(
+      R"cpp(
+namespace n {
+  template<typename T>
+  struct ST {
+    template<typename U>
+    static U f();
+  };
+}
+)cpp",
+      R"txt(
+*: TranslationUnit
+`-NamespaceDefinition
+  |-namespace
+  |-n
+  |-{
+  |-TemplateDeclaration
+  | |-template
+  | |-<
+  | |-UnknownDeclaration
+  | | |-typename
+  | | `-T
+  | |->
+  | `-SimpleDeclaration
+  |   |-struct
+  |   |-ST
+  |   |-{
+  |   |-TemplateDeclaration
+  |   | |-template
+  |   | |-<
+  |   | |-UnknownDeclaration
+  |   | | |-typename
+  |   | | `-U
+  |   | |->
+  |   | `-SimpleDeclaration
+  |   |   |-static
+  |   |   |-U
+  |   |   |-SimpleDeclarator
+  |   |   | |-f
+  |   |   | `-ParametersAndQualifiers
+  |   |   |   |-(
+  |   |   |   `-)
+  |   |   `-;
+  |   |-}
+  |   `-;
+  `-}
+)txt"));
+}
+
 TEST_P(SyntaxTreeTest, Templates2) {
   if (!GetParam().isCXX()) {
     return;

diff  --git a/clang/unittests/Tooling/Syntax/TreeTestBase.cpp b/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
index 05fbac4f47e1..c5dbb770c538 100644
--- a/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
@@ -171,7 +171,7 @@ ::testing::AssertionResult SyntaxTreeTest::treeDumpEqual(StringRef Code,
            << "Source file has syntax errors, they were printed to the test "
               "log";
   }
-  std::string Actual = std::string(StringRef(Root->dump(*Arena)).trim());
+  auto Actual = StringRef(Root->dump(*Arena)).trim().str();
   // EXPECT_EQ shows the 
diff  between the two strings if they are 
diff erent.
   EXPECT_EQ(Tree.trim().str(), Actual);
   if (Actual != Tree.trim().str()) {
@@ -194,21 +194,29 @@ SyntaxTreeTest::treeDumpEqualOnAnnotations(StringRef CodeWithAnnotations,
               "log";
   }
 
-  bool failed = false;
   auto AnnotatedRanges = AnnotatedCode.ranges();
-  assert(AnnotatedRanges.size() == TreeDumps.size());
-  for (auto i = 0ul; i < AnnotatedRanges.size(); i++) {
+  if (AnnotatedRanges.size() != TreeDumps.size()) {
+    return ::testing::AssertionFailure()
+           << "The number of annotated ranges in the source code is 
diff erent "
+              "to the number of their corresponding tree dumps.";
+  }
+  bool Failed = false;
+  for (unsigned i = 0; i < AnnotatedRanges.size(); i++) {
     auto *AnnotatedNode = nodeByRange(AnnotatedRanges[i], Root);
     assert(AnnotatedNode);
     auto AnnotatedNodeDump =
-        std::string(StringRef(AnnotatedNode->dump(*Arena)).trim());
+        StringRef(AnnotatedNode->dump(*Arena)).trim().str();
     // EXPECT_EQ shows the 
diff  between the two strings if they are 
diff erent.
-    EXPECT_EQ(TreeDumps[i].trim().str(), AnnotatedNodeDump);
+    EXPECT_EQ(TreeDumps[i].trim().str(), AnnotatedNodeDump)
+        << "Dumps diverged for the code:\n"
+        << AnnotatedCode.code().slice(AnnotatedRanges[i].Begin,
+                                      AnnotatedRanges[i].End);
     if (AnnotatedNodeDump != TreeDumps[i].trim().str())
-      failed = true;
+      Failed = true;
   }
-  return failed ? ::testing::AssertionFailure() : ::testing::AssertionSuccess();
+  return Failed ? ::testing::AssertionFailure() : ::testing::AssertionSuccess();
 }
+
 syntax::Node *SyntaxTreeTest::nodeByRange(llvm::Annotations::Range R,
                                           syntax::Node *Root) {
   ArrayRef<syntax::Token> Toks = tokens(Root);


        


More information about the cfe-commits mailing list