]> granicus.if.org Git - clang/commitdiff
[libclang] Indexing API: If the client requested to get a CXTranslationUnit after
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 28 Nov 2011 04:56:00 +0000 (04:56 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 28 Nov 2011 04:56:00 +0000 (04:56 +0000)
indexing, honor all the TU options.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145229 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Frontend/ASTUnit.h
include/clang/Frontend/MultiplexConsumer.h
lib/Frontend/ASTUnit.cpp
lib/Frontend/MultiplexConsumer.cpp
tools/c-index-test/c-index-test.c
tools/libclang/Indexing.cpp

index c6c766bb03be729abd1a11feba0493791ae490fe..3ccd04dfb29f938ddbc1a9ba6b2316c1495b2a2f 100644 (file)
@@ -674,10 +674,20 @@ public:
   ///
   /// \param Unit - optionally an already created ASTUnit. Its ownership is not
   /// transfered.
+  ///
+  /// \param Persistent - if true the returned ASTUnit will be complete.
+  /// false means the caller is only interested in getting info through the
+  /// provided \see Action.
   static ASTUnit *LoadFromCompilerInvocationAction(CompilerInvocation *CI,
                               llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
                                              ASTFrontendAction *Action = 0,
-                                             ASTUnit *Unit = 0);
+                                             ASTUnit *Unit = 0,
+                                             bool Persistent = true,
+                                      StringRef ResourceFilesPath = StringRef(),
+                                             bool OnlyLocalDecls = false,
+                                             bool CaptureDiagnostics = false,
+                                             bool PrecompilePreamble = false,
+                                       bool CacheCodeCompletionResults = false);
 
   /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
   /// CompilerInvocation object.
index 89972991d18ce6fb655601c911906ee408e74b7d..d95c069731cf5d6feb6ac000ee9a9303e3efe3ac 100644 (file)
@@ -37,6 +37,7 @@ public:
   virtual void HandleInterestingDecl(DeclGroupRef D);
   virtual void HandleTranslationUnit(ASTContext &Ctx);
   virtual void HandleTagDeclDefinition(TagDecl *D);
+  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
   virtual void CompleteTentativeDefinition(VarDecl *D);
   virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired);
   virtual ASTMutationListener *GetASTMutationListener();
index 2419d27941611e5a5ad5a850eba4fccc01e215fa..8606f686559ea609c9359532d2053a487d9c5662 100644 (file)
@@ -27,6 +27,7 @@
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/FrontendOptions.h"
+#include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/Frontend/Utils.h"
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/ASTWriter.h"
@@ -1649,21 +1650,33 @@ ASTUnit *ASTUnit::create(CompilerInvocation *CI,
 ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI,
                               llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
                                              ASTFrontendAction *Action,
-                                             ASTUnit *Unit) {
+                                             ASTUnit *Unit,
+                                             bool Persistent,
+                                             StringRef ResourceFilesPath,
+                                             bool OnlyLocalDecls,
+                                             bool CaptureDiagnostics,
+                                             bool PrecompilePreamble,
+                                             bool CacheCodeCompletionResults) {
   assert(CI && "A CompilerInvocation is required");
 
   llvm::OwningPtr<ASTUnit> OwnAST;
   ASTUnit *AST = Unit;
   if (!AST) {
     // Create the AST unit.
-    OwnAST.reset(create(CI, Diags));
+    OwnAST.reset(create(CI, Diags, CaptureDiagnostics));
     AST = OwnAST.get();
   }
   
-  AST->OnlyLocalDecls = false;
-  AST->CaptureDiagnostics = false;
+  if (!ResourceFilesPath.empty()) {
+    // Override the resources path.
+    CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
+  }
+  AST->OnlyLocalDecls = OnlyLocalDecls;
+  AST->CaptureDiagnostics = CaptureDiagnostics;
+  if (PrecompilePreamble)
+    AST->PreambleRebuildCounter = 2;
   AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
-  AST->ShouldCacheCodeCompletionResults = false;
+  AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
@@ -1742,7 +1755,17 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI,
                             Clang->getFrontendOpts().Inputs[0].second,
                             Clang->getFrontendOpts().Inputs[0].first))
     return 0;
-  
+
+  if (Persistent && !TrackerAct) {
+    Clang->getPreprocessor().addPPCallbacks(
+     new MacroDefinitionTrackerPPCallbacks(AST->getCurrentTopLevelHashValue()));
+    std::vector<ASTConsumer*> Consumers;
+    if (Clang->hasASTConsumer())
+      Consumers.push_back(Clang->takeASTConsumer());
+    Consumers.push_back(new TopLevelDeclTrackerConsumer(*AST,
+                                           AST->getCurrentTopLevelHashValue()));
+    Clang->setASTConsumer(new MultiplexConsumer(Consumers));
+  }
   Act->Execute();
   
   // Steal the created target, context, and preprocessor.
index e7b886ccb609c86a3fc5fe4aad42509f03515ba7..6ca40abc2abed15aaeec33fd6b5269bd818ff0ac 100644 (file)
@@ -184,9 +184,10 @@ void MultiplexConsumer::Initialize(ASTContext &Context) {
 }
 
 bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) {
+  bool Continue = true;
   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    Consumers[i]->HandleTopLevelDecl(D);
-  return true;
+    Continue = Continue && Consumers[i]->HandleTopLevelDecl(D);
+  return Continue;
 }
 
 void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) {
@@ -204,6 +205,11 @@ void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) {
     Consumers[i]->HandleTagDeclDefinition(D);
 }
 
+void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->HandleTopLevelDeclInObjCContainer(D);
+}
+
 void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) {
   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
     Consumers[i]->CompleteTentativeDefinition(D);
index 0e7193ee1043f6237e41f83493d2700d99913ebc..472c0b0e95013b32e0dab65c25164d58271e908b 100644 (file)
@@ -1548,6 +1548,7 @@ typedef struct {
   const char *check_prefix;
   int first_check_printed;
   int fail_for_error;
+  int abort;
 } IndexData;
 
 static void printCheck(IndexData *data) {
@@ -1850,8 +1851,14 @@ static void index_indexEntityReference(CXClientData client_data,
   printf("\n");
 }
 
+static int index_abortQuery(CXClientData client_data, void *reserved) {
+  IndexData *index_data;
+  index_data = (IndexData *)client_data;
+  return index_data->abort;
+}
+
 static IndexerCallbacks IndexCB = {
-  0, /*abortQuery*/
+  index_abortQuery,
   index_diagnostic,
   index_enteredMainFile,
   index_ppIncludedFile,
@@ -1894,6 +1901,7 @@ static int index_file(int argc, const char **argv) {
   index_data.check_prefix = check_prefix;
   index_data.first_check_printed = 0;
   index_data.fail_for_error = 0;
+  index_data.abort = 0;
 
   index_opts = 0;
   if (getenv("CINDEXTEST_SUPPRESSREFS"))
@@ -1948,6 +1956,7 @@ static int index_tu(int argc, const char **argv) {
   index_data.check_prefix = check_prefix;
   index_data.first_check_printed = 0;
   index_data.fail_for_error = 0;
+  index_data.abort = 0;
 
   index_opts = 0;
   if (getenv("CINDEXTEST_SUPPRESSREFS"))
index 5af1d50e7206ca3c6cff6dabb15eb2bfdbcbd235..222e301d46e951288a583c6141176ccf4fc1b1de 100644 (file)
@@ -244,9 +244,6 @@ static void clang_indexSourceFile_Impl(void *UserData) {
 
   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
 
-  (void)CXXIdx;
-  (void)TU_options;
-  
   CaptureDiagnosticConsumer *CaptureDiag = new CaptureDiagnosticConsumer();
 
   // Configure the diagnostics.
@@ -333,9 +330,38 @@ static void clang_indexSourceFile_Impl(void *UserData) {
   llvm::CrashRecoveryContextCleanupRegistrar<IndexingFrontendAction>
     IndexActionCleanup(IndexAction.get());
 
+  bool Persistent = requestedToGetTU;
+  StringRef ResourceFilesPath = CXXIdx->getClangResourcesPath();
+  bool OnlyLocalDecls = false;
+  bool CaptureDiagnostics = true;
+  bool PrecompilePreamble = false;
+  bool CacheCodeCompletionResults = false;
+  PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts(); 
+  PPOpts.DetailedRecord = false;
+  PPOpts.DetailedRecordIncludesNestedMacroExpansions = false;
+
+  if (requestedToGetTU) {
+    OnlyLocalDecls = CXXIdx->getOnlyLocalDecls();
+    PrecompilePreamble = TU_options & CXTranslationUnit_PrecompiledPreamble;
+    // FIXME: Add a flag for modules.
+    CacheCodeCompletionResults
+      = TU_options & CXTranslationUnit_CacheCompletionResults;
+    if (TU_options & CXTranslationUnit_DetailedPreprocessingRecord) {
+      PPOpts.DetailedRecord = true;
+      PPOpts.DetailedRecordIncludesNestedMacroExpansions
+          = (TU_options & CXTranslationUnit_NestedMacroExpansions);
+    }
+  }
+
   Unit = ASTUnit::LoadFromCompilerInvocationAction(CInvok.getPtr(), Diags,
                                                        IndexAction.get(),
-                                                       Unit);
+                                                       Unit,
+                                                       Persistent,
+                                                       ResourceFilesPath,
+                                                       OnlyLocalDecls,
+                                                       CaptureDiagnostics,
+                                                       PrecompilePreamble,
+                                                    CacheCodeCompletionResults);
   if (!Unit)
     return;