Add code-completion support directly to ASTUnit, which performs code
completion within the translation unit using the same command-line
arguments for parsing the translation unit. Eventually, we'll reuse
the precompiled preamble to improve code-completion performance, and
this also gives us a place to cache results.

Expose this function via the new libclang function
clang_codeCompleteAt(), which performs the code completion within a
CXTranslationUnit. The completion occurs in-process
(clang_codeCompletion() runs code completion out-of-process).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110210 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp
index 0310776..62e4abb 100644
--- a/lib/Sema/CodeCompleteConsumer.cpp
+++ b/lib/Sema/CodeCompleteConsumer.cpp
@@ -245,8 +245,10 @@
   return 0;
 }
 
-CodeCompletionString *CodeCompletionString::Clone() const {
-  CodeCompletionString *Result = new CodeCompletionString;
+CodeCompletionString *
+CodeCompletionString::Clone(CodeCompletionString *Result) const {
+  if (!Result)
+    Result = new CodeCompletionString;
   for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
     Result->AddChunk(C->Clone());
   return Result;
@@ -493,98 +495,81 @@
   }
 }
 
-void 
-CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
-                                                       Result *Results, 
-                                                       unsigned NumResults) {
-  // Print the results.
-  for (unsigned I = 0; I != NumResults; ++I) {
-    CXCursorKind Kind = CXCursor_NotImplemented;
-
-    switch (Results[I].Kind) {
+namespace clang {
+  // FIXME: Used externally by CIndexCodeCompletion.cpp; this code
+  // will move there, eventually, when the CIndexCodeCompleteConsumer
+  // dies.
+  CXCursorKind 
+  getCursorKindForCompletionResult(const CodeCompleteConsumer::Result &R) {
+    typedef CodeCompleteConsumer::Result Result;
+    switch (R.Kind) {
     case Result::RK_Declaration:
-      switch (Results[I].Declaration->getKind()) {
+      switch (R.Declaration->getKind()) {
       case Decl::Record:
       case Decl::CXXRecord:
       case Decl::ClassTemplateSpecialization: {
-        RecordDecl *Record = cast<RecordDecl>(Results[I].Declaration);
+        RecordDecl *Record = cast<RecordDecl>(R.Declaration);
         if (Record->isStruct())
-          Kind = CXCursor_StructDecl;
+          return CXCursor_StructDecl;
         else if (Record->isUnion())
-          Kind = CXCursor_UnionDecl;
+          return CXCursor_UnionDecl;
         else
-          Kind = CXCursor_ClassDecl;
-        break;
+          return CXCursor_ClassDecl;
       }
         
       case Decl::ObjCMethod: {
-        ObjCMethodDecl *Method = cast<ObjCMethodDecl>(Results[I].Declaration);
+        ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
         if (Method->isInstanceMethod())
-            Kind = CXCursor_ObjCInstanceMethodDecl;
+            return CXCursor_ObjCInstanceMethodDecl;
         else
-          Kind = CXCursor_ObjCClassMethodDecl;
-        break;
+          return CXCursor_ObjCClassMethodDecl;
       }
         
       case Decl::Typedef:
-        Kind = CXCursor_TypedefDecl;
-        break;
+        return CXCursor_TypedefDecl;
         
       case Decl::Enum:
-        Kind = CXCursor_EnumDecl;
-        break;
+        return CXCursor_EnumDecl;
         
       case Decl::Field:
-        Kind = CXCursor_FieldDecl;
-        break;
+        return CXCursor_FieldDecl;
         
       case Decl::EnumConstant:
-        Kind = CXCursor_EnumConstantDecl;
-        break;
+        return CXCursor_EnumConstantDecl;
         
       case Decl::Function:
       case Decl::CXXMethod:
       case Decl::CXXConstructor:
       case Decl::CXXDestructor:
       case Decl::CXXConversion:
-        Kind = CXCursor_FunctionDecl;
-        break;
+        return CXCursor_FunctionDecl;
         
       case Decl::Var:
-        Kind = CXCursor_VarDecl;
-        break;
+        return CXCursor_VarDecl;
         
       case Decl::ParmVar:
-        Kind = CXCursor_ParmDecl;
-        break;
+        return CXCursor_ParmDecl;
         
       case Decl::ObjCInterface:
-        Kind = CXCursor_ObjCInterfaceDecl;
-        break;
+        return CXCursor_ObjCInterfaceDecl;
         
       case Decl::ObjCCategory:
-        Kind = CXCursor_ObjCCategoryDecl;
-        break;
+        return CXCursor_ObjCCategoryDecl;
         
       case Decl::ObjCProtocol:
-        Kind = CXCursor_ObjCProtocolDecl;
-        break;
+        return CXCursor_ObjCProtocolDecl;
         
       case Decl::ObjCProperty:
-        Kind = CXCursor_ObjCPropertyDecl;
-        break;
+        return CXCursor_ObjCPropertyDecl;
         
       case Decl::ObjCIvar:
-        Kind = CXCursor_ObjCIvarDecl;
-        break;
+        return CXCursor_ObjCIvarDecl;
         
       case Decl::ObjCImplementation:
-        Kind = CXCursor_ObjCImplementationDecl;
-        break;
+        return CXCursor_ObjCImplementationDecl;
         
       case Decl::ObjCCategoryImpl:
-        Kind = CXCursor_ObjCCategoryImplDecl;
-        break;
+        return CXCursor_ObjCCategoryImplDecl;
         
       default:
         break;
@@ -592,16 +577,23 @@
       break;
 
     case Result::RK_Macro:
-      Kind = CXCursor_MacroDefinition;
-      break;
+      return CXCursor_MacroDefinition;
 
     case Result::RK_Keyword:
     case Result::RK_Pattern:
-      Kind = CXCursor_NotImplemented;
-      break;
+      return CXCursor_NotImplemented;
     }
+    return CXCursor_NotImplemented;
+  }
+}
 
-    WriteUnsigned(OS, Kind);
+void 
+CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
+                                                       Result *Results, 
+                                                       unsigned NumResults) {
+  // Print the results.
+  for (unsigned I = 0; I != NumResults; ++I) {
+    WriteUnsigned(OS, getCursorKindForCompletionResult(Results[I]));
     WriteUnsigned(OS, Results[I].Priority);
     CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(SemaRef);
     assert(CCS && "No code-completion string?");
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 476c79c..52ac8dd 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -1811,13 +1811,15 @@
 /// how to use this result, or NULL to indicate that the string or name of the
 /// result is all that is needed.
 CodeCompletionString *
-CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
+CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S,
+                                               CodeCompletionString *Result) {
   typedef CodeCompletionString::Chunk Chunk;
   
   if (Kind == RK_Pattern)
-    return Pattern->Clone();
+    return Pattern->Clone(Result);
   
-  CodeCompletionString *Result = new CodeCompletionString;
+  if (!Result)
+    Result = new CodeCompletionString;
 
   if (Kind == RK_Keyword) {
     Result->AddTypedTextChunk(Keyword);