[Syntax] Use a hash table to search for tokens by their location

This is both more efficient and avoids corner cases in
`SourceManager::isBeforeInTranslationUnit`.

The change is trivial and clearly a performance improvement on the hot
path of building the syntax tree, so sending without review.
This commit is contained in:
Ilya Biryukov 2019-12-18 11:44:06 +01:00
parent 038f53882e
commit c1bbefef9d
2 changed files with 50 additions and 9 deletions

View File

@ -51,7 +51,10 @@ static bool isImplicitExpr(clang::Expr *E) { return E->IgnoreImplicit() != E; }
/// Call finalize() to finish building the tree and consume the root node.
class syntax::TreeBuilder {
public:
TreeBuilder(syntax::Arena &Arena) : Arena(Arena), Pending(Arena) {}
TreeBuilder(syntax::Arena &Arena) : Arena(Arena), Pending(Arena) {
for (const auto &T : Arena.tokenBuffer().expandedTokens())
LocationToToken.insert({T.location().getRawEncoding(), &T});
}
llvm::BumpPtrAllocator &allocator() { return Arena.allocator(); }
@ -304,6 +307,9 @@ private:
std::string str() { return Pending.str(Arena); }
syntax::Arena &Arena;
/// To quickly find tokens by their start location.
llvm::DenseMap</*SourceLocation*/ unsigned, const syntax::Token *>
LocationToToken;
Forest Pending;
llvm::DenseSet<Decl *> DeclsWithoutSemicolons;
};
@ -641,14 +647,9 @@ void syntax::TreeBuilder::markExprChild(Expr *Child, NodeRole Role) {
}
const syntax::Token *syntax::TreeBuilder::findToken(SourceLocation L) const {
auto Tokens = Arena.tokenBuffer().expandedTokens();
auto &SM = Arena.sourceManager();
auto It = llvm::partition_point(Tokens, [&](const syntax::Token &T) {
return SM.isBeforeInTranslationUnit(T.location(), L);
});
assert(It != Tokens.end());
assert(It->location() == L);
return &*It;
auto It = LocationToToken.find(L.getRawEncoding());
assert(It != LocationToToken.end());
return It->second;
}
syntax::TranslationUnit *

View File

@ -767,6 +767,46 @@ void test() {
| `-CompoundStatement
| |-{
| `-}
`-}
)txt"},
// All nodes can be mutated.
{R"cpp(
#define OPEN {
#define CLOSE }
void test() {
OPEN
1;
CLOSE
OPEN
2;
}
}
)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
|-void
|-test
|-(
|-)
`-CompoundStatement
|-{
|-CompoundStatement
| |-{
| |-ExpressionStatement
| | |-UnknownExpression
| | | `-1
| | `-;
| `-}
|-CompoundStatement
| |-{
| |-ExpressionStatement
| | |-UnknownExpression
| | | `-2
| | `-;
| `-}
`-}
)txt"},
};