[clang] 881f5b5 - Revert "[Syntax] Build template declaration nodes"
Nico Weber via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 18 09:58:14 PDT 2020
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
More information about the cfe-commits
mailing list