[cfe-commits] r90223 - in /cfe/trunk: include/clang/Frontend/ASTUnit.h lib/Frontend/ASTUnit.cpp tools/c-index-test/CMakeLists.txt tools/c-index-test/Makefile tools/index-test/CMakeLists.txt tools/index-test/Makefile tools/index-test/index-test.cpp

Daniel Dunbar daniel at zuster.org
Tue Dec 1 01:51:01 PST 2009


Author: ddunbar
Date: Tue Dec  1 03:51:01 2009
New Revision: 90223

URL: http://llvm.org/viewvc/llvm-project?rev=90223&view=rev
Log:
Add ASTUnit::LoadFromCompilerInvocation, which does what it says.

Also, add an -ast-from-source option to index-test which allows index-test to
run on source files directly.

Modified:
    cfe/trunk/include/clang/Frontend/ASTUnit.h
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/tools/c-index-test/CMakeLists.txt
    cfe/trunk/tools/c-index-test/Makefile
    cfe/trunk/tools/index-test/CMakeLists.txt
    cfe/trunk/tools/index-test/Makefile
    cfe/trunk/tools/index-test/index-test.cpp

Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=90223&r1=90222&r2=90223&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Tue Dec  1 03:51:01 2009
@@ -22,16 +22,17 @@
 #include <string>
 
 namespace clang {
-  class FileManager;
-  class FileEntry;
-  class SourceManager;
-  class Diagnostic;
-  class TextDiagnosticBuffer;
-  class HeaderSearch;
-  class TargetInfo;
-  class Preprocessor;
-  class ASTContext;
-  class Decl;
+class ASTContext;
+class CompilerInvocation;
+class Decl;
+class Diagnostic;
+class FileEntry;
+class FileManager;
+class HeaderSearch;
+class Preprocessor;
+class SourceManager;
+class TargetInfo;
+class TextDiagnosticBuffer;
 
 using namespace idx;
 
@@ -92,21 +93,35 @@
   ///
   /// \param Filename - The PCH file to load.
   ///
-  /// \param diagClient - The diagnostics client to use.  Specify NULL
+  /// \param DiagClient - The diagnostics client to use.  Specify NULL
   /// to use a default client that emits warnings/errors to standard error.
   /// The ASTUnit objects takes ownership of this object.
   ///
-  /// \param FileMgr - The FileManager to use.
-  ///
   /// \param ErrMsg - Error message to report if the PCH file could not be
   /// loaded.
   ///
   /// \returns - The initialized ASTUnit or null if the PCH failed to load.
   static ASTUnit *LoadFromPCHFile(const std::string &Filename,
                                   std::string *ErrMsg = 0,
-                                  DiagnosticClient *diagClient = NULL,
+                                  DiagnosticClient *DiagClient = NULL,
                                   bool OnlyLocalDecls = false,
                                   bool UseBumpAllocator = false);
+
+  /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
+  /// CompilerInvocation object.
+  ///
+  /// \param CI - The compiler invocation to use; it must have exactly one input
+  /// source file.
+  ///
+  /// \param Diags - The diagnostics engine to use for reporting errors.
+  //
+  // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
+  // shouldn't need to specify them at construction time.
+  static ASTUnit *LoadFromCompilerInvocation(const CompilerInvocation &CI,
+                                             Diagnostic &Diags,
+                                             bool OnlyLocalDecls = false,
+                                             bool UseBumpAllocator = false);
+
 };
 
 } // namespace clang

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=90223&r1=90222&r2=90223&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Tue Dec  1 03:51:01 2009
@@ -14,24 +14,28 @@
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/PCHReader.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTConsumer.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/AST/StmtVisitor.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/FrontendOptions.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/Diagnostic.h"
+#include "llvm/LLVMContext.h"
 #include "llvm/System/Path.h"
-
 using namespace clang;
 
-ASTUnit::ASTUnit(DiagnosticClient *diagClient) : tempFile(false) {      
+ASTUnit::ASTUnit(DiagnosticClient *diagClient) : tempFile(false) {
   Diags.setClient(diagClient ? diagClient : new TextDiagnosticBuffer());
 }
-ASTUnit::~ASTUnit() { 
+ASTUnit::~ASTUnit() {
   if (tempFile)
     llvm::sys::Path(getPCHFileName()).eraseFromDisk();
-  
+
   //  The ASTUnit object owns the DiagnosticClient.
   delete Diags.getClient();
 }
@@ -170,3 +174,90 @@
 
   return AST.take();
 }
+
+namespace {
+
+class NullAction : public ASTFrontendAction {
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         llvm::StringRef InFile) {
+    return new ASTConsumer();
+  }
+
+public:
+  virtual bool hasCodeCompletionSupport() const { return false; }
+};
+
+}
+
+ASTUnit *ASTUnit::LoadFromCompilerInvocation(const CompilerInvocation &CI,
+                                             Diagnostic &Diags,
+                                             bool OnlyLocalDecls,
+                                             bool UseBumpAllocator) {
+  // Create the compiler instance to use for building the AST.
+  CompilerInstance Clang(&llvm::getGlobalContext(), false);
+  llvm::OwningPtr<ASTUnit> AST;
+  NullAction Act;
+
+  Clang.getInvocation() = CI;
+
+  Clang.setDiagnostics(&Diags);
+  Clang.setDiagnosticClient(Diags.getClient());
+
+  // Create the target instance.
+  Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
+                                               Clang.getTargetOpts()));
+  if (!Clang.hasTarget())
+    goto error;
+
+  // Inform the target of the language options.
+  //
+  // FIXME: We shouldn't need to do this, the target should be immutable once
+  // created. This complexity should be lifted elsewhere.
+  Clang.getTarget().setForcedLangOptions(Clang.getLangOpts());
+
+  assert(Clang.getFrontendOpts().Inputs.size() == 1 &&
+         "Invocation must have exactly one source file!");
+  assert(Clang.getFrontendOpts().Inputs[0].first != FrontendOptions::IK_AST &&
+         "FIXME: AST inputs not yet supported here!");
+
+  // Create the AST unit.
+  //
+  // FIXME: Use the provided diagnostic client.
+  AST.reset(new ASTUnit());
+
+  // Create a file manager object to provide access to and cache the filesystem.
+  Clang.setFileManager(&AST->getFileManager());
+
+  // Create the source manager.
+  Clang.setSourceManager(&AST->getSourceManager());
+
+  // Create the preprocessor.
+  Clang.createPreprocessor();
+
+  if (!Act.BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second,
+                           /*IsAST=*/false))
+    goto error;
+
+  Act.Execute();
+
+  // Steal the created context and preprocessor, and take back the source and
+  // file managers.
+  AST->Ctx.reset(Clang.takeASTContext());
+  AST->PP.reset(Clang.takePreprocessor());
+  Clang.takeSourceManager();
+  Clang.takeFileManager();
+
+  Act.EndSourceFile();
+
+  Clang.takeDiagnosticClient();
+  Clang.takeDiagnostics();
+
+  return AST.take();
+
+error:
+  Clang.takeSourceManager();
+  Clang.takeFileManager();
+  Clang.takeDiagnosticClient();
+  Clang.takeDiagnostics();
+  return 0;
+}

Modified: cfe/trunk/tools/c-index-test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/CMakeLists.txt?rev=90223&r1=90222&r2=90223&view=diff

==============================================================================
--- cfe/trunk/tools/c-index-test/CMakeLists.txt (original)
+++ cfe/trunk/tools/c-index-test/CMakeLists.txt Tue Dec  1 03:51:01 2009
@@ -4,8 +4,11 @@
   CIndex
   clangIndex
   clangFrontend
+  clangDriver
+  clangAnalysis
   clangSema
   clangAST
+  clangParse
   clangLex
   clangBasic
   )

Modified: cfe/trunk/tools/c-index-test/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/Makefile?rev=90223&r1=90222&r2=90223&view=diff

==============================================================================
--- cfe/trunk/tools/c-index-test/Makefile (original)
+++ cfe/trunk/tools/c-index-test/Makefile Tue Dec  1 03:51:01 2009
@@ -19,6 +19,7 @@
 include $(LEVEL)/Makefile.config
 
 LINK_COMPONENTS := bitreader mc
-USEDLIBS = CIndex.a clangIndex.a clangFrontend.a clangSema.a clangAST.a clangLex.a clangBasic.a 
+USEDLIBS = CIndex.a clangIndex.a clangFrontend.a clangDriver.a clangAnalysis.a \
+	   clangSema.a clangAST.a clangParse.a clangLex.a clangBasic.a
 
 include $(LLVM_SRC_ROOT)/Makefile.rules

Modified: cfe/trunk/tools/index-test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/index-test/CMakeLists.txt?rev=90223&r1=90222&r2=90223&view=diff

==============================================================================
--- cfe/trunk/tools/index-test/CMakeLists.txt (original)
+++ cfe/trunk/tools/index-test/CMakeLists.txt Tue Dec  1 03:51:01 2009
@@ -3,8 +3,10 @@
 set( LLVM_USED_LIBS
   clangIndex
   clangFrontend
+  clangAnalysis
   clangSema
   clangAST
+  clangParse
   clangLex
   clangBasic
   )

Modified: cfe/trunk/tools/index-test/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/index-test/Makefile?rev=90223&r1=90222&r2=90223&view=diff

==============================================================================
--- cfe/trunk/tools/index-test/Makefile (original)
+++ cfe/trunk/tools/index-test/Makefile Tue Dec  1 03:51:01 2009
@@ -19,6 +19,7 @@
 include $(LEVEL)/Makefile.config
 
 LINK_COMPONENTS := bitreader mc
-USEDLIBS = clangIndex.a clangFrontend.a clangSema.a clangAST.a clangLex.a clangBasic.a 
+USEDLIBS = clangIndex.a clangFrontend.a clangDriver.a clangAnalysis.a clangSema.a \
+	   clangAST.a clangParse.a clangLex.a clangBasic.a
 
 include $(LLVM_SRC_ROOT)/Makefile.rules

Modified: cfe/trunk/tools/index-test/index-test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/index-test/index-test.cpp?rev=90223&r1=90222&r2=90223&view=diff

==============================================================================
--- cfe/trunk/tools/index-test/index-test.cpp (original)
+++ cfe/trunk/tools/index-test/index-test.cpp Tue Dec  1 03:51:01 2009
@@ -43,6 +43,10 @@
 #include "clang/Index/Analyzer.h"
 #include "clang/Index/Utils.h"
 #include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/DiagnosticOptions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Frontend/CommandLineSourceLoc.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprObjC.h"
@@ -202,9 +206,24 @@
   }
 }
 
+static llvm::cl::opt<bool>
+ASTFromSource("ast-from-source",
+              llvm::cl::desc("Treat the inputs as source files to parse."));
+
 static llvm::cl::list<std::string>
 InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input AST files>"));
 
+void CreateCompilerInvocation(const std::string &Filename,
+                              CompilerInvocation &CI, Diagnostic &Diags,
+                              const char *argv0) {
+  llvm::SmallVector<const char *, 16> Args;
+  Args.push_back(Filename.c_str());
+
+  void *MainAddr = (void*) (intptr_t) CreateCompilerInvocation;
+  CompilerInvocation::CreateFromArgs(CI, Args.data(), Args.data() + Args.size(),
+                                     argv0, MainAddr, Diags);
+}
+
 int main(int argc, char **argv) {
   llvm::sys::PrintStackTraceOnErrorSignal();
   llvm::PrettyStackTraceProgram X(argc, argv);
@@ -215,6 +234,10 @@
   Indexer Idxer(Prog);
   llvm::SmallVector<TUnit*, 4> TUnits;
 
+  TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions(), false);
+  llvm::OwningPtr<Diagnostic> Diags(
+    CompilerInstance::createDiagnostics(DiagnosticOptions(), argc, argv));
+
   // If no input was specified, read from stdin.
   if (InputFilenames.empty())
     InputFilenames.push_back("-");
@@ -225,7 +248,15 @@
     std::string ErrMsg;
     llvm::OwningPtr<ASTUnit> AST;
 
-    AST.reset(ASTUnit::LoadFromPCHFile(InFile, &ErrMsg));
+    if (ASTFromSource) {
+      CompilerInvocation CI;
+      CreateCompilerInvocation(InFile, CI, *Diags, argv[0]);
+      AST.reset(ASTUnit::LoadFromCompilerInvocation(CI, *Diags));
+      if (!AST)
+        ErrMsg = "unable to create AST";
+    } else
+      AST.reset(ASTUnit::LoadFromPCHFile(InFile, &ErrMsg));
+
     if (!AST) {
       llvm::errs() << "[" << InFile << "] Error: " << ErrMsg << '\n';
       return 1;





More information about the cfe-commits mailing list