Author: Nico Weber
Date: 2020-03-18T12:57:55-04:00
New Revision: 881f5b5a7b294047815bf81780f933d14f281c86

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

LOG: Revert "[Syntax] Build template declaration nodes"

This reverts commit dd12826808f9079e164b82e64b0697a077379241.
Breaks tests on Windows, see https://reviews.llvm.org/D76346#1929208

Added: 
    

Modified: 
    clang/include/clang/Tooling/Syntax/Nodes.h
    clang/lib/Tooling/Syntax/BuildTree.cpp
    clang/lib/Tooling/Syntax/Nodes.cpp
    clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h 
b/clang/include/clang/Tooling/Syntax/Nodes.h
index f4d482bb848c..82fcac33f99b 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -64,8 +64,6 @@ enum class NodeKind : uint16_t {
   StaticAssertDeclaration,
   LinkageSpecificationDeclaration,
   SimpleDeclaration,
-  TemplateDeclaration,
-  ExplicitTemplateInstantiation,
   NamespaceDefinition,
   NamespaceAliasDefinition,
   UsingNamespaceDirective,
@@ -114,9 +112,6 @@ enum class NodeRole : uint8_t {
   StaticAssertDeclaration_condition,
   StaticAssertDeclaration_message,
   SimpleDeclaration_declarator,
-  TemplateDeclaration_declaration,
-  ExplicitTemplateInstantiation_externKeyword,
-  ExplicitTemplateInstantiation_declaration,
   ArraySubscript_sizeExpression,
   TrailingReturnType_arrow,
   TrailingReturnType_declarator,
@@ -401,34 +396,6 @@ class SimpleDeclaration final : public Declaration {
   std::vector<syntax::SimpleDeclarator *> declarators();
 };
 
-/// template <template-parameters> <declaration>
-class TemplateDeclaration final : public Declaration {
-public:
-  TemplateDeclaration() : Declaration(NodeKind::TemplateDeclaration) {}
-  static bool classof(const Node *N) {
-    return N->kind() == NodeKind::TemplateDeclaration;
-  }
-  syntax::Leaf *templateKeyword();
-  syntax::Declaration *declaration();
-};
-
-/// template <declaration>
-/// Examples:
-///     template struct X<int>
-///     template void foo<int>()
-///     template int var<double>
-class ExplicitTemplateInstantiation final : public Declaration {
-public:
-  ExplicitTemplateInstantiation()
-      : Declaration(NodeKind::ExplicitTemplateInstantiation) {}
-  static bool classof(const Node *N) {
-    return N->kind() == NodeKind::ExplicitTemplateInstantiation;
-  }
-  syntax::Leaf *templateKeyword();
-  syntax::Leaf *externKeyword();
-  syntax::Declaration *declaration();
-};
-
 /// namespace <name> { <decls> }
 class NamespaceDefinition final : public Declaration {
 public:

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp 
b/clang/lib/Tooling/Syntax/BuildTree.cpp
index a09ac1c53e34..9ebf7d29d8ed 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -18,7 +18,6 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
-#include "clang/Basic/Specifiers.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Tooling/Syntax/Nodes.h"
@@ -190,6 +189,7 @@ class syntax::TreeBuilder {
   /// Should be called for expressions in non-statement position to avoid
   /// wrapping into expression statement.
   void markExprChild(Expr *Child, NodeRole Role);
+
   /// Set role for a token starting at \p Loc.
   void markChildToken(SourceLocation Loc, NodeRole R);
   /// Set role for \p T.
@@ -199,9 +199,6 @@ class syntax::TreeBuilder {
   void markChild(llvm::ArrayRef<syntax::Token> Range, NodeRole R);
   /// Set role for the delayed node that spans exactly \p Range.
   void markDelayedChild(llvm::ArrayRef<syntax::Token> Range, NodeRole R);
-  /// Set role for the node that may or may not be delayed. Node must span
-  /// exactly \p Range.
-  void markMaybeDelayedChild(llvm::ArrayRef<syntax::Token> Range, NodeRole R);
 
   /// Finish building the tree and consume the root node.
   syntax::TranslationUnit *finalize() && {
@@ -218,9 +215,6 @@ class syntax::TreeBuilder {
     return TU;
   }
 
-  /// Finds a token starting at \p L. The token must exist if \p L is valid.
-  const syntax::Token *findToken(SourceLocation L) const;
-
   /// getRange() finds the syntax tokens corresponding to the passed source
   /// locations.
   /// \p First is the start position of the first token and \p Last is the 
start
@@ -233,22 +227,15 @@ class syntax::TreeBuilder {
            Arena.sourceManager().isBeforeInTranslationUnit(First, Last));
     return llvm::makeArrayRef(findToken(First), std::next(findToken(Last)));
   }
-
-  llvm::ArrayRef<syntax::Token>
-  getTemplateRange(const ClassTemplateSpecializationDecl *D) const {
-    auto R = D->getSourceRange();
-    auto Tokens = getRange(R.getBegin(), R.getEnd());
-    return maybeAppendSemicolon(Tokens, D);
-  }
-
-  llvm::ArrayRef<syntax::Token> getDeclRange(const Decl *D) const {
-    llvm::ArrayRef<clang::syntax::Token> Tokens;
-    // We want to drop the template parameters for specializations.
-    if (const auto *S = llvm::dyn_cast<TagDecl>(D))
-      Tokens = getRange(S->TypeDecl::getBeginLoc(), S->getEndLoc());
-    else
-      Tokens = getRange(D->getBeginLoc(), D->getEndLoc());
-    return maybeAppendSemicolon(Tokens, D);
+  llvm::ArrayRef<syntax::Token> getRange(const Decl *D) const {
+    auto Tokens = getRange(D->getBeginLoc(), D->getEndLoc());
+    if (llvm::isa<NamespaceDecl>(D))
+      return Tokens;
+    if (DeclsWithoutSemicolons.count(D))
+      return Tokens;
+    // FIXME: do not consume trailing semicolon on function definitions.
+    // Most declarations own a semicolon in syntax trees, but not in clang AST.
+    return withTrailingSemicolon(Tokens);
   }
   llvm::ArrayRef<syntax::Token> getExprRange(const Expr *E) const {
     return getRange(E->getBeginLoc(), E->getEndLoc());
@@ -268,18 +255,6 @@ class syntax::TreeBuilder {
   }
 
 private:
-  llvm::ArrayRef<syntax::Token>
-  maybeAppendSemicolon(llvm::ArrayRef<syntax::Token> Tokens,
-                       const Decl *D) const {
-    if (llvm::isa<NamespaceDecl>(D))
-      return Tokens;
-    if (DeclsWithoutSemicolons.count(D))
-      return Tokens;
-    // FIXME: do not consume trailing semicolon on function definitions.
-    // Most declarations own a semicolon in syntax trees, but not in clang AST.
-    return withTrailingSemicolon(Tokens);
-  }
-
   llvm::ArrayRef<syntax::Token>
   withTrailingSemicolon(llvm::ArrayRef<syntax::Token> Tokens) const {
     assert(!Tokens.empty());
@@ -290,6 +265,9 @@ class syntax::TreeBuilder {
     return Tokens;
   }
 
+  /// Finds a token starting at \p L. The token must exist.
+  const syntax::Token *findToken(SourceLocation L) const;
+
   /// A collection of trees covering the input tokens.
   /// When created, each tree corresponds to a single token in the file.
   /// Clients call 'foldChildren' to attach one or more subtrees to a parent
@@ -320,15 +298,6 @@ class syntax::TreeBuilder {
       It->second.Role = Role;
     }
 
-    void assignRoleMaybeDelayed(llvm::ArrayRef<syntax::Token> Range,
-                                syntax::NodeRole Role) {
-      auto It = DelayedFolds.find(Range.begin());
-      if (It == DelayedFolds.end())
-        return assignRole(Range, Role);
-      assert(It->second.End == Range.end());
-      It->second.Role = Role;
-    }
-
     void assignRole(llvm::ArrayRef<syntax::Token> Range,
                     syntax::NodeRole Role) {
       assert(!Range.empty());
@@ -491,7 +460,7 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor<BuildTreeVisitor> {
 
   bool WalkUpFromDeclaratorDecl(DeclaratorDecl *DD) {
     // Ensure declarators are covered by SimpleDeclaration.
-    Builder.noticeDeclRange(Builder.getDeclRange(DD));
+    Builder.noticeDeclRange(Builder.getRange(DD));
 
     // Build the declarator node.
     SourceRange Initializer;
@@ -516,7 +485,7 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor<BuildTreeVisitor> {
 
   bool WalkUpFromTypedefNameDecl(TypedefNameDecl *D) {
     // Ensure declarators are covered by SimpleDeclaration.
-    Builder.noticeDeclRange(Builder.getDeclRange(D));
+    Builder.noticeDeclRange(Builder.getRange(D));
 
     auto R = getDeclaratorRange(
         Builder.sourceManager(), D->getTypeSourceInfo()->getTypeLoc(),
@@ -531,59 +500,19 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor<BuildTreeVisitor> {
 
   bool VisitDecl(Decl *D) {
     assert(!D->isImplicit());
-    Builder.foldNode(Builder.getDeclRange(D),
+    Builder.foldNode(Builder.getRange(D),
                      new (allocator()) syntax::UnknownDeclaration());
     return true;
   }
 
-  // RAV does not call WalkUpFrom* on explicit instantiations, so we have to
-  // override Traverse.
-  // FIXME: make RAV call WalkUpFrom* instead.
-  bool
-  TraverseClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *C) {
-    if (!RecursiveASTVisitor::TraverseClassTemplateSpecializationDecl(C))
-      return false;
-    if (C->isExplicitSpecialization())
-      return true; // we are only interested in explicit instantiations.
-    if (!WalkUpFromClassTemplateSpecializationDecl(C))
-      return false;
-    foldExplicitTemplateInstantiation(
-        Builder.getTemplateRange(C), Builder.findToken(C->getExternLoc()),
-        Builder.findToken(C->getTemplateKeywordLoc()), 
Builder.getDeclRange(C));
-    return true;
-  }
-
-  bool WalkUpFromTemplateDecl(TemplateDecl *S) {
-    foldTemplateDeclaration(
-        Builder.getDeclRange(S),
-        Builder.findToken(S->getTemplateParameters()->getTemplateLoc()),
-        Builder.getDeclRange(S->getTemplatedDecl()));
-    return true;
-  }
-
   bool WalkUpFromTagDecl(TagDecl *C) {
     // FIXME: build the ClassSpecifier node.
-    if (!C->isFreeStanding()) {
-      assert(C->getNumTemplateParameterLists() == 0);
+    if (C->isFreeStanding()) {
+      // Class is a declaration specifier and needs a spanning declaration 
node.
+      Builder.foldNode(Builder.getRange(C),
+                       new (allocator()) syntax::SimpleDeclaration);
       return true;
     }
-    // Class is a declaration specifier and needs a spanning declaration node.
-    auto DeclarationRange = Builder.getDeclRange(C);
-    Builder.foldNode(DeclarationRange,
-                     new (allocator()) syntax::SimpleDeclaration);
-
-    // Build TemplateDeclaration nodes if we had template parameters.
-    auto ConsumeTemplateParameters = [&](const TemplateParameterList &L) {
-      const auto *TemplateKW = Builder.findToken(L.getTemplateLoc());
-      auto R = llvm::makeArrayRef(TemplateKW, DeclarationRange.end());
-      foldTemplateDeclaration(R, TemplateKW, DeclarationRange);
-
-      DeclarationRange = R;
-    };
-    if (auto *S = llvm::dyn_cast<ClassTemplatePartialSpecializationDecl>(C))
-      ConsumeTemplateParameters(*S->getTemplateParameters());
-    for (unsigned I = C->getNumTemplateParameterLists(); 0 < I; --I)
-      ConsumeTemplateParameters(*C->getTemplateParameterList(I - 1));
     return true;
   }
 
@@ -652,7 +581,7 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor<BuildTreeVisitor> {
   }
 
   bool WalkUpFromNamespaceDecl(NamespaceDecl *S) {
-    auto Tokens = Builder.getDeclRange(S);
+    auto Tokens = Builder.getRange(S);
     if (Tokens.front().kind() == tok::coloncolon) {
       // Handle nested namespace definitions. Those start at '::' token, e.g.
       // namespace a^::b {}
@@ -693,7 +622,7 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor<BuildTreeVisitor> {
     Builder.markChildToken(L.getLParenLoc(), syntax::NodeRole::OpenParen);
     for (auto *P : L.getParams())
       Builder.markDelayedChild(
-          Builder.getDeclRange(P),
+          Builder.getRange(P),
           syntax::NodeRole::ParametersAndQualifiers_parameter);
     Builder.markChildToken(L.getRParenLoc(), syntax::NodeRole::CloseParen);
     Builder.foldNode(Builder.getRange(L.getLParenLoc(), L.getEndLoc()),
@@ -827,7 +756,7 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor<BuildTreeVisitor> {
   }
 
   bool WalkUpFromEmptyDecl(EmptyDecl *S) {
-    Builder.foldNode(Builder.getDeclRange(S),
+    Builder.foldNode(Builder.getRange(S),
                      new (allocator()) syntax::EmptyDeclaration);
     return true;
   }
@@ -837,49 +766,49 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor<BuildTreeVisitor> {
                           syntax::NodeRole::StaticAssertDeclaration_condition);
     Builder.markExprChild(S->getMessage(),
                           syntax::NodeRole::StaticAssertDeclaration_message);
-    Builder.foldNode(Builder.getDeclRange(S),
+    Builder.foldNode(Builder.getRange(S),
                      new (allocator()) syntax::StaticAssertDeclaration);
     return true;
   }
 
   bool WalkUpFromLinkageSpecDecl(LinkageSpecDecl *S) {
-    Builder.foldNode(Builder.getDeclRange(S),
+    Builder.foldNode(Builder.getRange(S),
                      new (allocator()) 
syntax::LinkageSpecificationDeclaration);
     return true;
   }
 
   bool WalkUpFromNamespaceAliasDecl(NamespaceAliasDecl *S) {
-    Builder.foldNode(Builder.getDeclRange(S),
+    Builder.foldNode(Builder.getRange(S),
                      new (allocator()) syntax::NamespaceAliasDefinition);
     return true;
   }
 
   bool WalkUpFromUsingDirectiveDecl(UsingDirectiveDecl *S) {
-    Builder.foldNode(Builder.getDeclRange(S),
+    Builder.foldNode(Builder.getRange(S),
                      new (allocator()) syntax::UsingNamespaceDirective);
     return true;
   }
 
   bool WalkUpFromUsingDecl(UsingDecl *S) {
-    Builder.foldNode(Builder.getDeclRange(S),
+    Builder.foldNode(Builder.getRange(S),
                      new (allocator()) syntax::UsingDeclaration);
     return true;
   }
 
   bool WalkUpFromUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *S) {
-    Builder.foldNode(Builder.getDeclRange(S),
+    Builder.foldNode(Builder.getRange(S),
                      new (allocator()) syntax::UsingDeclaration);
     return true;
   }
 
   bool WalkUpFromUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *S) {
-    Builder.foldNode(Builder.getDeclRange(S),
+    Builder.foldNode(Builder.getRange(S),
                      new (allocator()) syntax::UsingDeclaration);
     return true;
   }
 
   bool WalkUpFromTypeAliasDecl(TypeAliasDecl *S) {
-    Builder.foldNode(Builder.getDeclRange(S),
+    Builder.foldNode(Builder.getRange(S),
                      new (allocator()) syntax::TypeAliasDeclaration);
     return true;
   }
@@ -916,36 +845,6 @@ class BuildTreeVisitor : public 
RecursiveASTVisitor<BuildTreeVisitor> {
     Builder.foldNode(Tokens, new (allocator()) syntax::TrailingReturnType);
     return Tokens;
   }
-
-  void
-  foldExplicitTemplateInstantiation(ArrayRef<syntax::Token> Range,
-                                    const syntax::Token *ExternKW,
-                                    const syntax::Token *TemplateKW,
-                                    ArrayRef<syntax::Token> InnerDeclaration) {
-    assert(!ExternKW || ExternKW->kind() == tok::kw_extern);
-    assert(TemplateKW && TemplateKW->kind() == tok::kw_template);
-    Builder.markChildToken(
-        ExternKW,
-        syntax::NodeRole::ExplicitTemplateInstantiation_externKeyword);
-    Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
-    Builder.markChild(
-        InnerDeclaration,
-        syntax::NodeRole::ExplicitTemplateInstantiation_declaration);
-    Builder.foldNode(Range,
-                     new (allocator()) syntax::ExplicitTemplateInstantiation);
-  }
-
-  void foldTemplateDeclaration(ArrayRef<syntax::Token> Range,
-                               const syntax::Token *TemplateKW,
-                               ArrayRef<syntax::Token> TemplatedDeclaration) {
-    assert(TemplateKW && TemplateKW->kind() == tok::kw_template);
-    Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword);
-    Builder.markMaybeDelayedChild(
-        TemplatedDeclaration,
-        syntax::NodeRole::TemplateDeclaration_declaration);
-    Builder.foldNode(Range, new (allocator()) syntax::TemplateDeclaration);
-  }
-
   /// A small helper to save some typing.
   llvm::BumpPtrAllocator &allocator() { return Builder.allocator(); }
 
@@ -992,11 +891,6 @@ void 
syntax::TreeBuilder::markDelayedChild(llvm::ArrayRef<syntax::Token> Range,
   Pending.assignRoleDelayed(Range, R);
 }
 
-void syntax::TreeBuilder::markMaybeDelayedChild(
-    llvm::ArrayRef<syntax::Token> Range, NodeRole R) {
-  Pending.assignRoleMaybeDelayed(Range, R);
-}
-
 void syntax::TreeBuilder::markStmtChild(Stmt *Child, NodeRole Role) {
   if (!Child)
     return;
@@ -1022,8 +916,6 @@ void syntax::TreeBuilder::markExprChild(Expr *Child, 
NodeRole Role) {
 }
 
 const syntax::Token *syntax::TreeBuilder::findToken(SourceLocation L) const {
-  if (L.isInvalid())
-    return nullptr;
   auto It = LocationToToken.find(L.getRawEncoding());
   assert(It != LocationToToken.end());
   return It->second;

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp 
b/clang/lib/Tooling/Syntax/Nodes.cpp
index 75f025e5f853..4f86007e39bb 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -58,10 +58,6 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream &OS, 
NodeKind K) {
     return OS << "LinkageSpecificationDeclaration";
   case NodeKind::SimpleDeclaration:
     return OS << "SimpleDeclaration";
-  case NodeKind::TemplateDeclaration:
-    return OS << "TemplateDeclaration";
-  case NodeKind::ExplicitTemplateInstantiation:
-    return OS << "ExplicitTemplateInstantiation";
   case NodeKind::NamespaceDefinition:
     return OS << "NamespaceDefinition";
   case NodeKind::NamespaceAliasDefinition:
@@ -122,12 +118,6 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream 
&OS, NodeRole R) {
     return OS << "StaticAssertDeclaration_message";
   case syntax::NodeRole::SimpleDeclaration_declarator:
     return OS << "SimpleDeclaration_declarator";
-  case syntax::NodeRole::TemplateDeclaration_declaration:
-    return OS << "TemplateDeclaration_declaration";
-  case syntax::NodeRole::ExplicitTemplateInstantiation_externKeyword:
-    return OS << "ExplicitTemplateInstantiation_externKeyword";
-  case syntax::NodeRole::ExplicitTemplateInstantiation_declaration:
-    return OS << "ExplicitTemplateInstantiation_declaration";
   case syntax::NodeRole::ArraySubscript_sizeExpression:
     return OS << "ArraySubscript_sizeExpression";
   case syntax::NodeRole::TrailingReturnType_arrow:
@@ -291,31 +281,6 @@ syntax::SimpleDeclaration::declarators() {
   return Children;
 }
 
-syntax::Leaf *syntax::TemplateDeclaration::templateKeyword() {
-  return llvm::cast_or_null<syntax::Leaf>(
-      findChild(syntax::NodeRole::IntroducerKeyword));
-}
-
-syntax::Declaration *syntax::TemplateDeclaration::declaration() {
-  return llvm::cast_or_null<syntax::Declaration>(
-      findChild(syntax::NodeRole::TemplateDeclaration_declaration));
-}
-
-syntax::Leaf *syntax::ExplicitTemplateInstantiation::templateKeyword() {
-  return llvm::cast_or_null<syntax::Leaf>(
-      findChild(syntax::NodeRole::IntroducerKeyword));
-}
-
-syntax::Leaf *syntax::ExplicitTemplateInstantiation::externKeyword() {
-  return llvm::cast_or_null<syntax::Leaf>(
-      
findChild(syntax::NodeRole::ExplicitTemplateInstantiation_externKeyword));
-}
-
-syntax::Declaration *syntax::ExplicitTemplateInstantiation::declaration() {
-  return llvm::cast_or_null<syntax::Declaration>(
-      findChild(syntax::NodeRole::ExplicitTemplateInstantiation_declaration));
-}
-
 syntax::Leaf *syntax::ParenDeclarator::lparen() {
   return llvm::cast_or_null<syntax::Leaf>(
       findChild(syntax::NodeRole::OpenParen));

diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp 
b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index 3bb3a88e4367..6e914b6378c8 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -678,212 +678,6 @@ struct {} *a1;
   `-;
 )txt"},
       {R"cpp(
-template <class T> struct cls {};
-template <class T> int var = 10;
-template <class T> int fun() {}
-    )cpp",
-       R"txt(
-*: TranslationUnit
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-UnknownDeclaration
-| | |-class
-| | `-T
-| |->
-| `-SimpleDeclaration
-|   |-struct
-|   |-cls
-|   |-{
-|   |-}
-|   `-;
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-UnknownDeclaration
-| | |-class
-| | `-T
-| |->
-| `-SimpleDeclaration
-|   |-int
-|   |-SimpleDeclarator
-|   | |-var
-|   | |-=
-|   | `-UnknownExpression
-|   |   `-10
-|   `-;
-`-TemplateDeclaration
-  |-template
-  |-<
-  |-UnknownDeclaration
-  | |-class
-  | `-T
-  |->
-  `-SimpleDeclaration
-    |-int
-    |-SimpleDeclarator
-    | |-fun
-    | `-ParametersAndQualifiers
-    |   |-(
-    |   `-)
-    `-CompoundStatement
-      |-{
-      `-}
-)txt"},
-      {R"cpp(
-template <class T>
-struct X {
-  template <class U>
-  U foo();
-};
-    )cpp",
-       R"txt(
-*: TranslationUnit
-`-TemplateDeclaration
-  |-template
-  |-<
-  |-UnknownDeclaration
-  | |-class
-  | `-T
-  |->
-  `-SimpleDeclaration
-    |-struct
-    |-X
-    |-{
-    |-TemplateDeclaration
-    | |-template
-    | |-<
-    | |-UnknownDeclaration
-    | | |-class
-    | | `-U
-    | |->
-    | `-SimpleDeclaration
-    |   |-U
-    |   |-SimpleDeclarator
-    |   | |-foo
-    |   | `-ParametersAndQualifiers
-    |   |   |-(
-    |   |   `-)
-    |   `-;
-    |-}
-    `-;
-)txt"},
-      {R"cpp(
-template <class T> struct X {};
-template <class T> struct X<T*> {};
-template <> struct X<int> {};
-
-template struct X<double>;
-extern template struct X<float>;
-)cpp",
-       R"txt(
-*: TranslationUnit
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-UnknownDeclaration
-| | |-class
-| | `-T
-| |->
-| `-SimpleDeclaration
-|   |-struct
-|   |-X
-|   |-{
-|   |-}
-|   `-;
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-UnknownDeclaration
-| | |-class
-| | `-T
-| |->
-| `-SimpleDeclaration
-|   |-struct
-|   |-X
-|   |-<
-|   |-T
-|   |-*
-|   |->
-|   |-{
-|   |-}
-|   `-;
-|-TemplateDeclaration
-| |-template
-| |-<
-| |->
-| `-SimpleDeclaration
-|   |-struct
-|   |-X
-|   |-<
-|   |-int
-|   |->
-|   |-{
-|   |-}
-|   `-;
-|-ExplicitTemplateInstantiation
-| |-template
-| `-SimpleDeclaration
-|   |-struct
-|   |-X
-|   |-<
-|   |-double
-|   |->
-|   `-;
-`-ExplicitTemplateInstantiation
-  |-extern
-  |-template
-  `-SimpleDeclaration
-    |-struct
-    |-X
-    |-<
-    |-float
-    |->
-    `-;
-)txt"},
-      {R"cpp(
-template <class T> struct X { struct Y; };
-template <class T> struct X<T>::Y {};
-    )cpp",
-       R"txt(
-*: TranslationUnit
-|-TemplateDeclaration
-| |-template
-| |-<
-| |-UnknownDeclaration
-| | |-class
-| | `-T
-| |->
-| `-SimpleDeclaration
-|   |-struct
-|   |-X
-|   |-{
-|   |-SimpleDeclaration
-|   | |-struct
-|   | |-Y
-|   | `-;
-|   |-}
-|   `-;
-`-TemplateDeclaration
-  |-template
-  |-<
-  |-UnknownDeclaration
-  | |-class
-  | `-T
-  |->
-  `-SimpleDeclaration
-    |-struct
-    |-X
-    |-<
-    |-T
-    |->
-    |-::
-    |-Y
-    |-{
-    |-}
-    `-;
-       )txt"},
-      {R"cpp(
 namespace ns {}
 using namespace ::ns;
     )cpp",
@@ -932,7 +726,7 @@ template <class T> struct X {
     )cpp",
        R"txt(
 *: TranslationUnit
-`-TemplateDeclaration
+`-UnknownDeclaration
   |-template
   |-<
   |-UnknownDeclaration


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to