Use precompiled preambles for in-process code completion.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110596 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 1530aa8..db897b3 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -874,7 +874,8 @@
   struct CXUnsavedFile *unsaved_files = 0;
   int num_unsaved_files = 0;
   CXCodeCompleteResults *results = 0;
-
+  CXTranslationUnit *TU = 0;
+  
   if (timing_only)
     input += strlen("-code-completion-timing=");
   else
@@ -889,15 +890,20 @@
 
   CIdx = clang_createIndex(0, 1);
   if (getenv("CINDEXTEST_EDITING")) {
-    CXTranslationUnit *TU = clang_parseTranslationUnit(CIdx, 0,
-                                  argv + num_unsaved_files + 2,
-                                  argc - num_unsaved_files - 2,
-                                  unsaved_files,
-                                  num_unsaved_files,
-                                  getDefaultParsingOptions());
-    results = clang_codeCompleteAt(TU, filename, line, column,
-                                   unsaved_files, num_unsaved_files,
-                                   clang_defaultCodeCompleteOptions());
+    TU = clang_parseTranslationUnit(CIdx, 0,
+                                    argv + num_unsaved_files + 2,
+                                    argc - num_unsaved_files - 2,
+                                    unsaved_files,
+                                    num_unsaved_files,
+                                    getDefaultParsingOptions());
+    unsigned I, Repeats = 5;
+    for (I = 0; I != Repeats; ++I) {
+      results = clang_codeCompleteAt(TU, filename, line, column,
+                                     unsaved_files, num_unsaved_files,
+                                     clang_defaultCodeCompleteOptions());
+      if (I != Repeats-1)
+        clang_disposeCodeCompleteResults(results);
+    }
   } else
     results = clang_codeComplete(CIdx,
                                  argv[argc - 1], argc - num_unsaved_files - 3,
@@ -918,7 +924,7 @@
     }
     clang_disposeCodeCompleteResults(results);
   }
-
+  clang_disposeTranslationUnit(TU);
   clang_disposeIndex(CIdx);
   free(filename);
 
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 6414166..60eef4d 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -1195,7 +1195,9 @@
   if (options & CXTranslationUnit_Editing)
     options |= CXTranslationUnit_PrecompiledPreamble;
   bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
-  
+  bool CompleteTranslationUnit
+    = ((options & CXTranslationUnit_Incomplete) == 0);
+
   // Configure the diagnostics.
   DiagnosticOptions DiagOpts;
   llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
@@ -1250,7 +1252,8 @@
                                    RemappedFiles.data(),
                                    RemappedFiles.size(),
                                    /*CaptureDiagnostics=*/true,
-                                   PrecompilePreamble));
+                                   PrecompilePreamble,
+                                   CompleteTranslationUnit));
 
     if (NumErrors != Diags->getNumErrors()) {
       // Make sure to check that 'Unit' is non-NULL.
@@ -1451,7 +1454,7 @@
   return static_cast<ASTUnit *>(TU)->Reparse(RemappedFiles.data(),
                                              RemappedFiles.size())? 1 : 0;
 }
-  
+
 CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
   if (!CTUnit)
     return createCXString("");
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 4ab6b9b..790f32f 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -20,17 +20,18 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/System/Program.h"
 #include <cstdlib>
 #include <cstdio>
 
+
 #ifdef UDP_CODE_COMPLETION_LOGGER
 #include "clang/Basic/Version.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/Timer.h"
-#include "llvm/Support/raw_ostream.h"
 #include <arpa/inet.h>
 #include <sys/socket.h>
 #include <sys/types.h>
@@ -277,7 +278,16 @@
 #endif
 
   bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
-  
+
+  llvm::OwningPtr<llvm::NamedRegionTimer> CCTimer;
+  if (getenv("LIBCLANG_TIMING")) {
+    llvm::SmallString<128> TimerName;
+    llvm::raw_svector_ostream TimerNameOut(TimerName);
+    TimerNameOut << "Code completion @ " << complete_filename << ":"
+      << complete_line << ":" << complete_column;
+    CCTimer.reset(new llvm::NamedRegionTimer(TimerNameOut.str()));
+  }
+
   // The indexer, which is mainly used to determine where diagnostics go.
   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);