forked from OSchip/llvm-project
[clang][Syntax] syntax::Arena doesnt own TokenBuffer
Currently an Arena can only be built while consuming a TokenBuffer, some users (like clangd) might want to share a TokenBuffer with multiple compenents. This patch changes Arena's TokenBuffer member to be a reference so that it can be created with read-only token buffers. Differential Revision: https://reviews.llvm.org/D84973
This commit is contained in:
parent
fb5588b0ad
commit
1618828165
|
@ -39,7 +39,7 @@ namespace syntax {
|
|||
class Arena {
|
||||
public:
|
||||
Arena(SourceManager &SourceMgr, const LangOptions &LangOpts,
|
||||
TokenBuffer Tokens);
|
||||
const TokenBuffer &Tokens);
|
||||
|
||||
const SourceManager &sourceManager() const { return SourceMgr; }
|
||||
const LangOptions &langOptions() const { return LangOpts; }
|
||||
|
@ -56,7 +56,7 @@ public:
|
|||
private:
|
||||
SourceManager &SourceMgr;
|
||||
const LangOptions &LangOpts;
|
||||
TokenBuffer Tokens;
|
||||
const TokenBuffer &Tokens;
|
||||
/// IDs and storage for additional tokenized files.
|
||||
llvm::DenseMap<FileID, std::vector<syntax::Token>> ExtraTokens;
|
||||
/// Keeps all the allocated nodes and their intermediate data structures.
|
||||
|
|
|
@ -33,8 +33,8 @@ static void traverse(syntax::Node *N,
|
|||
} // namespace
|
||||
|
||||
syntax::Arena::Arena(SourceManager &SourceMgr, const LangOptions &LangOpts,
|
||||
TokenBuffer Tokens)
|
||||
: SourceMgr(SourceMgr), LangOpts(LangOpts), Tokens(std::move(Tokens)) {}
|
||||
const TokenBuffer &Tokens)
|
||||
: SourceMgr(SourceMgr), LangOpts(LangOpts), Tokens(Tokens) {}
|
||||
|
||||
const clang::syntax::TokenBuffer &syntax::Arena::tokenBuffer() const {
|
||||
return Tokens;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
|
||||
using namespace clang;
|
||||
|
||||
|
@ -59,22 +60,25 @@ protected:
|
|||
class BuildSyntaxTree : public ASTConsumer {
|
||||
public:
|
||||
BuildSyntaxTree(syntax::TranslationUnit *&Root,
|
||||
std::unique_ptr<syntax::TokenBuffer> &TB,
|
||||
std::unique_ptr<syntax::Arena> &Arena,
|
||||
std::unique_ptr<syntax::TokenCollector> Tokens)
|
||||
: Root(Root), Arena(Arena), Tokens(std::move(Tokens)) {
|
||||
: Root(Root), TB(TB), Arena(Arena), Tokens(std::move(Tokens)) {
|
||||
assert(this->Tokens);
|
||||
}
|
||||
|
||||
void HandleTranslationUnit(ASTContext &Ctx) override {
|
||||
Arena = std::make_unique<syntax::Arena>(Ctx.getSourceManager(),
|
||||
Ctx.getLangOpts(),
|
||||
std::move(*Tokens).consume());
|
||||
TB =
|
||||
std::make_unique<syntax::TokenBuffer>(std::move(*Tokens).consume());
|
||||
Tokens = nullptr; // make sure we fail if this gets called twice.
|
||||
Arena = std::make_unique<syntax::Arena>(Ctx.getSourceManager(),
|
||||
Ctx.getLangOpts(), *TB);
|
||||
Root = syntax::buildSyntaxTree(*Arena, *Ctx.getTranslationUnitDecl());
|
||||
}
|
||||
|
||||
private:
|
||||
syntax::TranslationUnit *&Root;
|
||||
std::unique_ptr<syntax::TokenBuffer> &TB;
|
||||
std::unique_ptr<syntax::Arena> &Arena;
|
||||
std::unique_ptr<syntax::TokenCollector> Tokens;
|
||||
};
|
||||
|
@ -82,20 +86,22 @@ protected:
|
|||
class BuildSyntaxTreeAction : public ASTFrontendAction {
|
||||
public:
|
||||
BuildSyntaxTreeAction(syntax::TranslationUnit *&Root,
|
||||
std::unique_ptr<syntax::TokenBuffer> &TB,
|
||||
std::unique_ptr<syntax::Arena> &Arena)
|
||||
: Root(Root), Arena(Arena) {}
|
||||
: Root(Root), TB(TB), Arena(Arena) {}
|
||||
|
||||
std::unique_ptr<ASTConsumer>
|
||||
CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override {
|
||||
// We start recording the tokens, ast consumer will take on the result.
|
||||
auto Tokens =
|
||||
std::make_unique<syntax::TokenCollector>(CI.getPreprocessor());
|
||||
return std::make_unique<BuildSyntaxTree>(Root, Arena,
|
||||
return std::make_unique<BuildSyntaxTree>(Root, TB, Arena,
|
||||
std::move(Tokens));
|
||||
}
|
||||
|
||||
private:
|
||||
syntax::TranslationUnit *&Root;
|
||||
std::unique_ptr<syntax::TokenBuffer> &TB;
|
||||
std::unique_ptr<syntax::Arena> &Arena;
|
||||
};
|
||||
|
||||
|
@ -132,7 +138,7 @@ protected:
|
|||
Compiler.setSourceManager(SourceMgr.get());
|
||||
|
||||
syntax::TranslationUnit *Root = nullptr;
|
||||
BuildSyntaxTreeAction Recorder(Root, this->Arena);
|
||||
BuildSyntaxTreeAction Recorder(Root, this->TB, this->Arena);
|
||||
|
||||
// Action could not be executed but the frontend didn't identify any errors
|
||||
// in the code ==> problem in setting up the action.
|
||||
|
@ -204,6 +210,7 @@ protected:
|
|||
new SourceManager(*Diags, *FileMgr);
|
||||
std::shared_ptr<CompilerInvocation> Invocation;
|
||||
// Set after calling buildTree().
|
||||
std::unique_ptr<syntax::TokenBuffer> TB;
|
||||
std::unique_ptr<syntax::Arena> Arena;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue