<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">This patch is breaking a test on Windows buildbot.<div><br></div><div><div>Failing Tests (1):</div><div> Clang-Unit :: Tooling/Release/ToolingTests.exe/ClangToolTest.BuildASTs</div><div><br></div><div><pre style="font-family: 'Courier New', courier, monotype, monospace; "><span class="stdout">FAIL: Clang-Unit :: Tooling/Release/ToolingTests.exe/ClangToolTest.BuildASTs (6615 of 6737)
******************** TEST 'Clang-Unit :: Tooling/Release/ToolingTests.exe/ClangToolTest.BuildASTs' FAILED ********************
Note: Google Test filter = ClangToolTest.BuildASTs
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from ClangToolTest
[ RUN ] ClangToolTest.BuildASTs
..\..\..\..\..\..\src\tools\clang\unittests\Tooling\ToolingTest.cpp(297): error : Value of: Tool.buildASTs(ASTs) [C:\...\clang-build\221761\tools\clang\test\check-clang.vcxproj]
Actual: 1
Expected: 0
..\..\..\..\..\..\src\tools\clang\unittests\Tooling\ToolingTest.cpp(298): error : Value of: ASTs.size() [C:\...\clang-build\221761\tools\clang\test\check-clang.vcxproj]
Actual: 0
Expected: 2u
Which is: 2
[ FAILED ] ClangToolTest.BuildASTs (78 ms)
[----------] 1 test from ClangToolTest (78 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (78 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] ClangToolTest.BuildASTs
1 FAILED TEST</span></pre><div><br></div></div><div>- Fariborz</div><div><br></div><div><br></div><div><div>On Nov 6, 2013, at 12:12 PM, Peter Collingbourne <<a href="mailto:peter@pcc.me.uk">peter@pcc.me.uk</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Author: pcc<br>Date: Wed Nov 6 14:12:45 2013<br>New Revision: 194164<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=194164&view=rev">http://llvm.org/viewvc/llvm-project?rev=194164&view=rev</a><br>Log:<br>Introduce ClangTool::buildASTs, and buildASTFromCode.<br><br>These allow clients to retrieve persistent AST objects (ASTUnits) which<br>can be used in an ad-hoc manner after parsing.<br><br>To accommodate this change, the code for processing a CompilerInvocation<br>using a FrontendAction has been factored out to FrontendActionFactory, and<br>a new base class, ToolAction, has been introduced, allowing the tool to do<br>arbitrary things with each CompilerInvocation. This change was necessary<br>because ASTUnit does not use the FrontendAction interface directly.<br><br>This change also causes the FileManager in ClangTool to use shared ownership.<br>This will become necessary because ASTUnit takes shared ownership of<br>FileManager (ClangTool's FileManager is currently unused by ASTUnit; this<br>is a FIXME). As shown in the tests, any client of ToolInvocation will<br>need to be modified to use shared ownership for FileManager.<br><br>Differential Revision: <a href="http://llvm-reviews.chandlerc.com/D2097">http://llvm-reviews.chandlerc.com/D2097</a><br><br>Modified:<br> cfe/trunk/include/clang/Tooling/Tooling.h<br> cfe/trunk/lib/Tooling/Tooling.cpp<br> cfe/trunk/unittests/Tooling/ToolingTest.cpp<br><br>Modified: cfe/trunk/include/clang/Tooling/Tooling.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Tooling.h?rev=194164&r1=194163&r2=194164&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Tooling.h?rev=194164&r1=194163&r2=194164&view=diff</a><br>==============================================================================<br>--- cfe/trunk/include/clang/Tooling/Tooling.h (original)<br>+++ cfe/trunk/include/clang/Tooling/Tooling.h Wed Nov 6 14:12:45 2013<br>@@ -53,14 +53,33 @@ class FrontendAction;<br><br> namespace tooling {<br><br>+/// \brief Interface to process a clang::CompilerInvocation.<br>+///<br>+/// If your tool is based on FrontendAction, you should be deriving from<br>+/// FrontendActionFactory instead.<br>+class ToolAction {<br>+public:<br>+ virtual ~ToolAction();<br>+<br>+ /// \brief Perform an action for an invocation.<br>+ virtual bool runInvocation(clang::CompilerInvocation *Invocation,<br>+ FileManager *Files) = 0;<br>+};<br>+<br> /// \brief Interface to generate clang::FrontendActions.<br> ///<br> /// Having a factory interface allows, for example, a new FrontendAction to be<br>-/// created for each translation unit processed by ClangTool.<br>-class FrontendActionFactory {<br>+/// created for each translation unit processed by ClangTool. This class is<br>+/// also a ToolAction which uses the FrontendActions created by create() to<br>+/// process each translation unit.<br>+class FrontendActionFactory : public ToolAction {<br> public:<br> virtual ~FrontendActionFactory();<br><br>+ /// \brief Invokes the compiler with a FrontendAction created by create().<br>+ bool runInvocation(clang::CompilerInvocation *Invocation,<br>+ FileManager *Files);<br>+<br> /// \brief Returns a new clang::FrontendAction.<br> ///<br> /// The caller takes ownership of the returned action.<br>@@ -133,6 +152,26 @@ bool runToolOnCodeWithArgs(clang::Fronte<br> const std::vector<std::string> &Args,<br> const Twine &FileName = "input.cc");<br><br>+/// \brief Builds an AST for 'Code'.<br>+///<br>+/// \param Code C++ code.<br>+/// \param FileName The file name which 'Code' will be mapped as.<br>+///<br>+/// \return The resulting AST or null if an error occurred.<br>+ASTUnit *buildASTFromCode(const Twine &Code,<br>+ const Twine &FileName = "input.cc");<br>+<br>+/// \brief Builds an AST for 'Code' with additional flags.<br>+///<br>+/// \param Code C++ code.<br>+/// \param Args Additional flags to pass on.<br>+/// \param FileName The file name which 'Code' will be mapped as.<br>+///<br>+/// \return The resulting AST or null if an error occurred.<br>+ASTUnit *buildASTFromCodeWithArgs(const Twine &Code,<br>+ const std::vector<std::string> &Args,<br>+ const Twine &FileName = "input.cc");<br>+<br> /// \brief Utility to run a FrontendAction in a single clang invocation.<br> class ToolInvocation {<br> public:<br>@@ -145,9 +184,19 @@ class ToolInvocation {<br> /// \param ToolAction The action to be executed. Class takes ownership.<br> /// \param Files The FileManager used for the execution. Class does not take<br> /// ownership.<br>- ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *ToolAction,<br>+ ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *FAction,<br> FileManager *Files);<br><br>+ /// \brief Create a tool invocation.<br>+ ///<br>+ /// \param CommandLine The command line arguments to clang.<br>+ /// \param Action The action to be executed.<br>+ /// \param Files The FileManager used for the execution.<br>+ ToolInvocation(ArrayRef<std::string> CommandLine, ToolAction *Action,<br>+ FileManager *Files);<br>+<br>+ ~ToolInvocation();<br>+<br> /// \brief Map a virtual file to be used while running the tool.<br> ///<br> /// \param FilePath The path at which the content will be mapped.<br>@@ -167,7 +216,8 @@ class ToolInvocation {<br> clang::CompilerInvocation *Invocation);<br><br> std::vector<std::string> CommandLine;<br>- OwningPtr<FrontendAction> ToolAction;<br>+ ToolAction *Action;<br>+ bool OwnsAction;<br> FileManager *Files;<br> // Maps <file name> -> <file content>.<br> llvm::StringMap<StringRef> MappedFileContents;<br>@@ -216,23 +266,25 @@ class ClangTool {<br> /// \brief Clear the command line arguments adjuster chain.<br> void clearArgumentsAdjusters();<br><br>- /// Runs a frontend action over all files specified in the command line.<br>+ /// Runs an action over all files specified in the command line.<br> ///<br>- /// \param ActionFactory Factory generating the frontend actions. The function<br>- /// takes ownership of this parameter. A new action is generated for every<br>- /// processed translation unit.<br>- virtual int run(FrontendActionFactory *ActionFactory);<br>+ /// \param Action Tool action.<br>+ int run(ToolAction *Action);<br>+<br>+ /// \brief Create an AST for each file specified in the command line and<br>+ /// append them to ASTs.<br>+ int buildASTs(std::vector<ASTUnit *> &ASTs);<br><br> /// \brief Returns the file manager used in the tool.<br> ///<br> /// The file manager is shared between all translation units.<br>- FileManager &getFiles() { return Files; }<br>+ FileManager &getFiles() { return *Files; }<br><br> private:<br> // We store compile commands as pair (file name, compile command).<br> std::vector< std::pair<std::string, CompileCommand> > CompileCommands;<br><br>- FileManager Files;<br>+ llvm::IntrusiveRefCntPtr<FileManager> Files;<br> // Contains a list of pairs (<file name>, <file content>).<br> std::vector< std::pair<StringRef, StringRef> > MappedFileContents;<br><br><br>Modified: cfe/trunk/lib/Tooling/Tooling.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Tooling.cpp?rev=194164&r1=194163&r2=194164&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Tooling.cpp?rev=194164&r1=194163&r2=194164&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/Tooling/Tooling.cpp (original)<br>+++ cfe/trunk/lib/Tooling/Tooling.cpp Wed Nov 6 14:12:45 2013<br>@@ -13,9 +13,11 @@<br> //===----------------------------------------------------------------------===//<br><br> #include "clang/Tooling/Tooling.h"<br>+#include "clang/AST/ASTConsumer.h"<br> #include "clang/Driver/Compilation.h"<br> #include "clang/Driver/Driver.h"<br> #include "clang/Driver/Tool.h"<br>+#include "clang/Frontend/ASTUnit.h"<br> #include "clang/Frontend/CompilerInstance.h"<br> #include "clang/Frontend/FrontendDiagnostic.h"<br> #include "clang/Frontend/TextDiagnosticPrinter.h"<br>@@ -38,6 +40,8 @@<br> namespace clang {<br> namespace tooling {<br><br>+ToolAction::~ToolAction() {}<br>+<br> FrontendActionFactory::~FrontendActionFactory() {}<br><br> // FIXME: This file contains structural duplication with other parts of the<br>@@ -104,18 +108,26 @@ bool runToolOnCode(clang::FrontendAction<br> ToolAction, Code, std::vector<std::string>(), FileName);<br> }<br><br>+static std::vector<std::string><br>+getSyntaxOnlyToolArgs(const std::vector<std::string> &ExtraArgs,<br>+ StringRef FileName) {<br>+ std::vector<std::string> Args;<br>+ Args.push_back("clang-tool");<br>+ Args.push_back("-fsyntax-only");<br>+ Args.insert(Args.end(), ExtraArgs.begin(), ExtraArgs.end());<br>+ Args.push_back(FileName.str());<br>+ return Args;<br>+}<br>+<br> bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code,<br> const std::vector<std::string> &Args,<br> const Twine &FileName) {<br> SmallString<16> FileNameStorage;<br> StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);<br>- std::vector<std::string> Commands;<br>- Commands.push_back("clang-tool");<br>- Commands.push_back("-fsyntax-only");<br>- Commands.insert(Commands.end(), Args.begin(), Args.end());<br>- Commands.push_back(FileNameRef.data());<br>- FileManager Files((FileSystemOptions()));<br>- ToolInvocation Invocation(Commands, ToolAction, &Files);<br>+ llvm::IntrusiveRefCntPtr<FileManager> Files(<br>+ new FileManager(FileSystemOptions()));<br>+ ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef), ToolAction,<br>+ Files.getPtr());<br><br> SmallString<1024> CodeStorage;<br> Invocation.mapVirtualFile(FileNameRef,<br>@@ -138,10 +150,33 @@ std::string getAbsolutePath(StringRef Fi<br> return AbsolutePath.str();<br> }<br><br>-ToolInvocation::ToolInvocation(<br>- ArrayRef<std::string> CommandLine, FrontendAction *ToolAction,<br>- FileManager *Files)<br>- : CommandLine(CommandLine.vec()), ToolAction(ToolAction), Files(Files) {<br>+namespace {<br>+<br>+class SingleFrontendActionFactory : public FrontendActionFactory {<br>+ FrontendAction *Action;<br>+<br>+public:<br>+ SingleFrontendActionFactory(FrontendAction *Action) : Action(Action) {}<br>+<br>+ FrontendAction *create() { return Action; }<br>+};<br>+<br>+}<br>+<br>+ToolInvocation::ToolInvocation(ArrayRef<std::string> CommandLine,<br>+ ToolAction *Action, FileManager *Files)<br>+ : CommandLine(CommandLine.vec()), Action(Action), OwnsAction(false),<br>+ Files(Files) {}<br>+<br>+ToolInvocation::ToolInvocation(ArrayRef<std::string> CommandLine,<br>+ FrontendAction *FAction, FileManager *Files)<br>+ : CommandLine(CommandLine.vec()),<br>+ Action(new SingleFrontendActionFactory(FAction)), OwnsAction(true),<br>+ Files(Files) {}<br>+<br>+ToolInvocation::~ToolInvocation() {<br>+ if (OwnsAction)<br>+ delete Action;<br> }<br><br> void ToolInvocation::mapVirtualFile(StringRef FilePath, StringRef Content) {<br>@@ -175,6 +210,14 @@ bool ToolInvocation::run() {<br> }<br> OwningPtr<clang::CompilerInvocation> Invocation(<br> newInvocation(&Diagnostics, *CC1Args));<br>+ for (llvm::StringMap<StringRef>::const_iterator<br>+ It = MappedFileContents.begin(), End = MappedFileContents.end();<br>+ It != End; ++It) {<br>+ // Inject the code as the given file name into the preprocessor options.<br>+ const llvm::MemoryBuffer *Input =<br>+ llvm::MemoryBuffer::getMemBuffer(It->getValue());<br>+ Invocation->getPreprocessorOpts().addRemappedFile(It->getKey(), Input);<br>+ }<br> return runInvocation(BinaryName, Compilation.get(), Invocation.take());<br> }<br><br>@@ -189,16 +232,20 @@ bool ToolInvocation::runInvocation(<br> llvm::errs() << "\n";<br> }<br><br>+ return Action->runInvocation(Invocation, Files);<br>+}<br>+<br>+bool FrontendActionFactory::runInvocation(CompilerInvocation *Invocation,<br>+ FileManager *Files) {<br> // Create a compiler instance to handle the actual work.<br> clang::CompilerInstance Compiler;<br> Compiler.setInvocation(Invocation);<br> Compiler.setFileManager(Files);<br>- // FIXME: What about LangOpts?<br><br>- // ToolAction can have lifetime requirements for Compiler or its members, and<br>- // we need to ensure it's deleted earlier than Compiler. So we pass it to an<br>- // OwningPtr declared after the Compiler variable.<br>- OwningPtr<FrontendAction> ScopedToolAction(ToolAction.take());<br>+ // The FrontendAction can have lifetime requirements for Compiler or its<br>+ // members, and we need to ensure it's deleted earlier than Compiler. So we<br>+ // pass it to an OwningPtr declared after the Compiler variable.<br>+ OwningPtr<FrontendAction> ScopedToolAction(create());<br><br> // Create the compilers actual diagnostics engine.<br> Compiler.createDiagnostics();<br>@@ -206,32 +253,16 @@ bool ToolInvocation::runInvocation(<br> return false;<br><br> Compiler.createSourceManager(*Files);<br>- addFileMappingsTo(Compiler.getSourceManager());<br><br> const bool Success = Compiler.ExecuteAction(*ScopedToolAction);<br><br>- Compiler.resetAndLeakFileManager();<br> Files->clearStatCaches();<br> return Success;<br> }<br><br>-void ToolInvocation::addFileMappingsTo(SourceManager &Sources) {<br>- for (llvm::StringMap<StringRef>::const_iterator<br>- It = MappedFileContents.begin(), End = MappedFileContents.end();<br>- It != End; ++It) {<br>- // Inject the code as the given file name into the preprocessor options.<br>- const llvm::MemoryBuffer *Input =<br>- llvm::MemoryBuffer::getMemBuffer(It->getValue());<br>- // FIXME: figure out what '0' stands for.<br>- const FileEntry *FromFile = Files->getVirtualFile(<br>- It->getKey(), Input->getBufferSize(), 0);<br>- Sources.overrideFileContents(FromFile, Input);<br>- }<br>-}<br>-<br> ClangTool::ClangTool(const CompilationDatabase &Compilations,<br> ArrayRef<std::string> SourcePaths)<br>- : Files((FileSystemOptions())) {<br>+ : Files(new FileManager(FileSystemOptions())) {<br> ArgsAdjusters.push_back(new ClangStripOutputAdjuster());<br> ArgsAdjusters.push_back(new ClangSyntaxOnlyAdjuster());<br> for (unsigned I = 0, E = SourcePaths.size(); I != E; ++I) {<br>@@ -274,7 +305,7 @@ void ClangTool::clearArgumentsAdjusters(<br> ArgsAdjusters.clear();<br> }<br><br>-int ClangTool::run(FrontendActionFactory *ActionFactory) {<br>+int ClangTool::run(ToolAction *Action) {<br> // Exists solely for the purpose of lookup of the resource path.<br> // This just needs to be some symbol in the binary.<br> static int StaticSymbol;<br>@@ -309,7 +340,7 @@ int ClangTool::run(FrontendActionFactory<br> DEBUG({<br> llvm::dbgs() << "Processing: " << File << ".\n";<br> });<br>- ToolInvocation Invocation(CommandLine, ActionFactory->create(), &Files);<br>+ ToolInvocation Invocation(CommandLine, Action, Files.getPtr());<br> for (int I = 0, E = MappedFileContents.size(); I != E; ++I) {<br> Invocation.mapVirtualFile(MappedFileContents[I].first,<br> MappedFileContents[I].second);<br>@@ -323,5 +354,58 @@ int ClangTool::run(FrontendActionFactory<br> return ProcessingFailed ? 1 : 0;<br> }<br><br>+namespace {<br>+<br>+class ASTBuilderAction : public ToolAction {<br>+ std::vector<ASTUnit *> &ASTs;<br>+<br>+public:<br>+ ASTBuilderAction(std::vector<ASTUnit *> &ASTs) : ASTs(ASTs) {}<br>+<br>+ bool runInvocation(CompilerInvocation *Invocation,<br>+ FileManager *Files) {<br>+ // FIXME: This should use the provided FileManager.<br>+ ASTUnit *AST = ASTUnit::LoadFromCompilerInvocation(<br>+ Invocation,<br>+ CompilerInstance::createDiagnostics(&Invocation->getDiagnosticOpts()));<br>+ if (!AST)<br>+ return false;<br>+<br>+ ASTs.push_back(AST);<br>+ return true;<br>+ }<br>+};<br>+<br>+}<br>+<br>+int ClangTool::buildASTs(std::vector<ASTUnit *> &ASTs) {<br>+ ASTBuilderAction Action(ASTs);<br>+ return run(&Action);<br>+}<br>+<br>+ASTUnit *buildASTFromCode(const Twine &Code, const Twine &FileName) {<br>+ return buildASTFromCodeWithArgs(Code, std::vector<std::string>(), FileName);<br>+}<br>+<br>+ASTUnit *buildASTFromCodeWithArgs(const Twine &Code,<br>+ const std::vector<std::string> &Args,<br>+ const Twine &FileName) {<br>+ SmallString<16> FileNameStorage;<br>+ StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);<br>+<br>+ std::vector<ASTUnit *> ASTs;<br>+ ASTBuilderAction Action(ASTs);<br>+ ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef), &Action, 0);<br>+<br>+ SmallString<1024> CodeStorage;<br>+ Invocation.mapVirtualFile(FileNameRef,<br>+ Code.toNullTerminatedStringRef(CodeStorage));<br>+ if (!Invocation.run())<br>+ return 0;<br>+<br>+ assert(ASTs.size() == 1);<br>+ return ASTs[0];<br>+}<br>+<br> } // end namespace tooling<br> } // end namespace clang<br><br>Modified: cfe/trunk/unittests/Tooling/ToolingTest.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/ToolingTest.cpp?rev=194164&r1=194163&r2=194164&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/ToolingTest.cpp?rev=194164&r1=194163&r2=194164&view=diff</a><br>==============================================================================<br>--- cfe/trunk/unittests/Tooling/ToolingTest.cpp (original)<br>+++ cfe/trunk/unittests/Tooling/ToolingTest.cpp Wed Nov 6 14:12:45 2013<br>@@ -10,12 +10,14 @@<br> #include "clang/AST/ASTConsumer.h"<br> #include "clang/AST/DeclCXX.h"<br> #include "clang/AST/DeclGroup.h"<br>+#include "clang/Frontend/ASTUnit.h"<br> #include "clang/Frontend/CompilerInstance.h"<br> #include "clang/Frontend/FrontendAction.h"<br> #include "clang/Frontend/FrontendActions.h"<br> #include "clang/Tooling/CompilationDatabase.h"<br> #include "clang/Tooling/Tooling.h"<br> #include "gtest/gtest.h"<br>+#include "llvm/ADT/STLExtras.h"<br> #include <string><br><br> namespace clang {<br>@@ -83,6 +85,18 @@ class FindClassDeclXConsumer : public cl<br> private:<br> bool *FoundClassDeclX;<br> };<br>+bool FindClassDeclX(ASTUnit *AST) {<br>+ for (std::vector<Decl *>::iterator i = AST->top_level_begin(),<br>+ e = AST->top_level_end();<br>+ i != e; ++i) {<br>+ if (CXXRecordDecl* Record = dyn_cast<clang::CXXRecordDecl>(*i)) {<br>+ if (Record->getName() == "X") {<br>+ return true;<br>+ }<br>+ }<br>+ }<br>+ return false;<br>+}<br> } // end namespace<br><br> TEST(runToolOnCode, FindsClassDecl) {<br>@@ -97,6 +111,16 @@ TEST(runToolOnCode, FindsClassDecl) {<br> EXPECT_FALSE(FoundClassDeclX);<br> }<br><br>+TEST(buildASTFromCode, FindsClassDecl) {<br>+ OwningPtr<ASTUnit> AST(buildASTFromCode("class X;"));<br>+ ASSERT_TRUE(AST.get());<br>+ EXPECT_TRUE(FindClassDeclX(AST.get()));<br>+<br>+ AST.reset(buildASTFromCode("class Y;"));<br>+ ASSERT_TRUE(AST.get());<br>+ EXPECT_FALSE(FindClassDeclX(AST.get()));<br>+}<br>+<br> TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromType) {<br> OwningPtr<FrontendActionFactory> Factory(<br> newFrontendActionFactory<SyntaxOnlyAction>());<br>@@ -119,13 +143,15 @@ TEST(newFrontendActionFactory, CreatesFr<br> }<br><br> TEST(ToolInvocation, TestMapVirtualFile) {<br>- clang::FileManager Files((clang::FileSystemOptions()));<br>+ IntrusiveRefCntPtr<clang::FileManager> Files(<br>+ new clang::FileManager(clang::FileSystemOptions()));<br> std::vector<std::string> Args;<br> Args.push_back("tool-executable");<br> Args.push_back("-Idef");<br> Args.push_back("-fsyntax-only");<br> Args.push_back("test.cpp");<br>- clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction, &Files);<br>+ clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,<br>+ Files.getPtr());<br> Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");<br> Invocation.mapVirtualFile("def/abc", "\n");<br> EXPECT_TRUE(Invocation.run());<br>@@ -136,13 +162,15 @@ TEST(ToolInvocation, TestVirtualModulesC<br> // mapped module.map is found on the include path. In the future, expand this<br> // test to run a full modules enabled compilation, so we make sure we can<br> // rerun modules compilations with a virtual file system.<br>- clang::FileManager Files((clang::FileSystemOptions()));<br>+ IntrusiveRefCntPtr<clang::FileManager> Files(<br>+ new clang::FileManager(clang::FileSystemOptions()));<br> std::vector<std::string> Args;<br> Args.push_back("tool-executable");<br> Args.push_back("-Idef");<br> Args.push_back("-fsyntax-only");<br> Args.push_back("test.cpp");<br>- clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction, &Files);<br>+ clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,<br>+ Files.getPtr());<br> Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");<br> Invocation.mapVirtualFile("def/abc", "\n");<br> // Add a module.map file in the include directory of our header, so we trigger<br>@@ -254,5 +282,23 @@ TEST(ClangToolTest, ArgumentAdjusters) {<br> EXPECT_FALSE(Found);<br> }<br><br>+TEST(ClangToolTest, BuildASTs) {<br>+ FixedCompilationDatabase Compilations("/", std::vector<std::string>());<br>+<br>+ std::vector<std::string> Sources;<br>+ Sources.push_back("/a.cc");<br>+ Sources.push_back("/b.cc");<br>+ ClangTool Tool(Compilations, Sources);<br>+<br>+ Tool.mapVirtualFile("/a.cc", "void a() {}");<br>+ Tool.mapVirtualFile("/b.cc", "void b() {}");<br>+<br>+ std::vector<ASTUnit *> ASTs;<br>+ EXPECT_EQ(0, Tool.buildASTs(ASTs));<br>+ EXPECT_EQ(2u, ASTs.size());<br>+<br>+ llvm::DeleteContainerPointers(ASTs);<br>+}<br>+<br> } // end namespace tooling<br> } // end namespace clang<br><br><br>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits<br></blockquote></div><br></div></body></html>