<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>