diff options
Diffstat (limited to 'clang/lib/Tooling')
| -rw-r--r-- | clang/lib/Tooling/Syntax/BuildTree.cpp | 75 | ||||
| -rw-r--r-- | clang/lib/Tooling/Syntax/Nodes.cpp | 30 |
2 files changed, 104 insertions, 1 deletions
diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp index 67081497d04..e13bb2d0699 100644 --- a/clang/lib/Tooling/Syntax/BuildTree.cpp +++ b/clang/lib/Tooling/Syntax/BuildTree.cpp @@ -295,7 +295,7 @@ private: syntax::Arena &Arena; Forest Pending; - llvm::DenseSet<Decl*> DeclsWithoutSemicolons; + llvm::DenseSet<Decl *> DeclsWithoutSemicolons; }; namespace { @@ -397,6 +397,18 @@ public: return true; } + bool WalkUpFromNamespaceDecl(NamespaceDecl *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 {} + // FIXME: build corresponding nodes for the name of this namespace. + return true; + } + Builder.foldNode(Tokens, new (allocator()) syntax::NamespaceDefinition); + return true; + } + // The code below is very regular, it could even be generated with some // preprocessor magic. We merely assign roles to the corresponding children // and fold resulting nodes. @@ -504,6 +516,64 @@ public: return true; } + bool WalkUpFromEmptyDecl(EmptyDecl *S) { + Builder.foldNode(Builder.getRange(S), + new (allocator()) syntax::EmptyDeclaration); + return true; + } + + bool WalkUpFromStaticAssertDecl(StaticAssertDecl *S) { + Builder.markExprChild(S->getAssertExpr(), + syntax::NodeRole::StaticAssertDeclaration_condition); + Builder.markExprChild(S->getMessage(), + syntax::NodeRole::StaticAssertDeclaration_message); + Builder.foldNode(Builder.getRange(S), + new (allocator()) syntax::StaticAssertDeclaration); + return true; + } + + bool WalkUpFromLinkageSpecDecl(LinkageSpecDecl *S) { + Builder.foldNode(Builder.getRange(S), + new (allocator()) syntax::LinkageSpecificationDeclaration); + return true; + } + + bool WalkUpFromNamespaceAliasDecl(NamespaceAliasDecl *S) { + Builder.foldNode(Builder.getRange(S), + new (allocator()) syntax::NamespaceAliasDefinition); + return true; + } + + bool WalkUpFromUsingDirectiveDecl(UsingDirectiveDecl *S) { + Builder.foldNode(Builder.getRange(S), + new (allocator()) syntax::UsingNamespaceDirective); + return true; + } + + bool WalkUpFromUsingDecl(UsingDecl *S) { + Builder.foldNode(Builder.getRange(S), + new (allocator()) syntax::UsingDeclaration); + return true; + } + + bool WalkUpFromUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *S) { + Builder.foldNode(Builder.getRange(S), + new (allocator()) syntax::UsingDeclaration); + return true; + } + + bool WalkUpFromUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *S) { + Builder.foldNode(Builder.getRange(S), + new (allocator()) syntax::UsingDeclaration); + return true; + } + + bool WalkUpFromTypeAliasDecl(TypeAliasDecl *S) { + Builder.foldNode(Builder.getRange(S), + new (allocator()) syntax::TypeAliasDeclaration); + return true; + } + private: /// A small helper to save some typing. llvm::BumpPtrAllocator &allocator() { return Builder.allocator(); } @@ -553,6 +623,9 @@ void syntax::TreeBuilder::markStmtChild(Stmt *Child, NodeRole Role) { } void syntax::TreeBuilder::markExprChild(Expr *Child, NodeRole Role) { + if (!Child) + return; + Pending.assignRole(getExprRange(Child), Role); } diff --git a/clang/lib/Tooling/Syntax/Nodes.cpp b/clang/lib/Tooling/Syntax/Nodes.cpp index b2ed4ffa22c..5b0c5107c13 100644 --- a/clang/lib/Tooling/Syntax/Nodes.cpp +++ b/clang/lib/Tooling/Syntax/Nodes.cpp @@ -50,8 +50,24 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream &OS, NodeKind K) { return OS << "CompoundStatement"; case NodeKind::UnknownDeclaration: return OS << "UnknownDeclaration"; + case NodeKind::EmptyDeclaration: + return OS << "EmptyDeclaration"; + case NodeKind::StaticAssertDeclaration: + return OS << "StaticAssertDeclaration"; + case NodeKind::LinkageSpecificationDeclaration: + return OS << "LinkageSpecificationDeclaration"; case NodeKind::SimpleDeclaration: return OS << "SimpleDeclaration"; + case NodeKind::NamespaceDefinition: + return OS << "NamespaceDefinition"; + case NodeKind::NamespaceAliasDefinition: + return OS << "NamespaceAliasDefinition"; + case NodeKind::UsingNamespaceDirective: + return OS << "UsingNamespaceDirective"; + case NodeKind::UsingDeclaration: + return OS << "UsingDeclaration"; + case NodeKind::TypeAliasDeclaration: + return OS << "TypeAliasDeclaration"; } llvm_unreachable("unknown node kind"); } @@ -84,6 +100,10 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream &OS, NodeRole R) { return OS << "ExpressionStatement_expression"; case syntax::NodeRole::CompoundStatement_statement: return OS << "CompoundStatement_statement"; + case syntax::NodeRole::StaticAssertDeclaration_condition: + return OS << "StaticAssertDeclaration_condition"; + case syntax::NodeRole::StaticAssertDeclaration_message: + return OS << "StaticAssertDeclaration_message"; } llvm_unreachable("invalid role"); } @@ -216,3 +236,13 @@ syntax::Leaf *syntax::CompoundStatement::rbrace() { return llvm::cast_or_null<syntax::Leaf>( findChild(syntax::NodeRole::CloseParen)); } + +syntax::Expression *syntax::StaticAssertDeclaration::condition() { + return llvm::cast_or_null<syntax::Expression>( + findChild(syntax::NodeRole::StaticAssertDeclaration_condition)); +} + +syntax::Expression *syntax::StaticAssertDeclaration::message() { + return llvm::cast_or_null<syntax::Expression>( + findChild(syntax::NodeRole::StaticAssertDeclaration_message)); +} |

