diff --git a/clang/include/clang/Tooling/Syntax/Tree.h b/clang/include/clang/Tooling/Syntax/Tree.h --- a/clang/include/clang/Tooling/Syntax/Tree.h +++ b/clang/include/clang/Tooling/Syntax/Tree.h @@ -39,7 +39,7 @@ 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 @@ private: SourceManager &SourceMgr; const LangOptions &LangOpts; - TokenBuffer Tokens; + const TokenBuffer &Tokens; /// IDs and storage for additional tokenized files. llvm::DenseMap> ExtraTokens; /// Keeps all the allocated nodes and their intermediate data structures. diff --git a/clang/lib/Tooling/Syntax/Tree.cpp b/clang/lib/Tooling/Syntax/Tree.cpp --- a/clang/lib/Tooling/Syntax/Tree.cpp +++ b/clang/lib/Tooling/Syntax/Tree.cpp @@ -33,8 +33,8 @@ } // 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; diff --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp b/clang/unittests/Tooling/Syntax/TreeTest.cpp --- a/clang/unittests/Tooling/Syntax/TreeTest.cpp +++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp @@ -35,6 +35,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" #include +#include using namespace clang; @@ -59,22 +60,25 @@ class BuildSyntaxTree : public ASTConsumer { public: BuildSyntaxTree(syntax::TranslationUnit *&Root, + std::unique_ptr &TB, std::unique_ptr &Arena, std::unique_ptr 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(Ctx.getSourceManager(), - Ctx.getLangOpts(), - std::move(*Tokens).consume()); + TB = + std::make_unique(std::move(*Tokens).consume()); Tokens = nullptr; // make sure we fail if this gets called twice. + Arena = std::make_unique(Ctx.getSourceManager(), + Ctx.getLangOpts(), *TB); Root = syntax::buildSyntaxTree(*Arena, *Ctx.getTranslationUnitDecl()); } private: syntax::TranslationUnit *&Root; + std::unique_ptr &TB; std::unique_ptr &Arena; std::unique_ptr Tokens; }; @@ -82,20 +86,22 @@ class BuildSyntaxTreeAction : public ASTFrontendAction { public: BuildSyntaxTreeAction(syntax::TranslationUnit *&Root, + std::unique_ptr &TB, std::unique_ptr &Arena) - : Root(Root), Arena(Arena) {} + : Root(Root), TB(TB), Arena(Arena) {} std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override { // We start recording the tokens, ast consumer will take on the result. auto Tokens = std::make_unique(CI.getPreprocessor()); - return std::make_unique(Root, Arena, + return std::make_unique(Root, TB, Arena, std::move(Tokens)); } private: syntax::TranslationUnit *&Root; + std::unique_ptr &TB; std::unique_ptr &Arena; }; @@ -132,7 +138,7 @@ 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 @@ new SourceManager(*Diags, *FileMgr); std::shared_ptr Invocation; // Set after calling buildTree(). + std::unique_ptr TB; std::unique_ptr Arena; };