Revert "[Syntax] Build template declaration nodes"

This reverts commit dd12826808.
Breaks tests on Windows, see https://reviews.llvm.org/D76346#1929208
This commit is contained in:
Nico Weber 2020-03-18 12:57:55 -04:00
parent 04a309dd0b
commit 881f5b5a7b
4 changed files with 32 additions and 414 deletions

View File

@ -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 @@ public:
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:

View File

@ -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 @@ public:
/// 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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
}
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 @@ private:
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 @@ private:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
}
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 @@ public:
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 @@ public:
}
bool WalkUpFromEmptyDecl(EmptyDecl *S) {
Builder.foldNode(Builder.getDeclRange(S),
Builder.foldNode(Builder.getRange(S),
new (allocator()) syntax::EmptyDeclaration);
return true;
}
@ -837,49 +766,49 @@ public:
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 @@ private:
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;

View File

@ -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));

View File

@ -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