Introduce a new libclang API to determine the parent context of a code
completion item. For example, if the code completion itself represents
a declaration in a namespace (say, std::vector), then this API
retrieves the cursor kind and name of the namespace (std). Implements
<rdar://problem/11121951>.

llvm-svn: 153545
diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp
index caebe3a..dbc9b00 100644
--- a/clang/lib/Sema/CodeCompleteConsumer.cpp
+++ b/clang/lib/Sema/CodeCompleteConsumer.cpp
@@ -192,9 +192,12 @@
                                            unsigned Priority, 
                                            CXAvailabilityKind Availability,
                                            const char **Annotations,
-                                           unsigned NumAnnotations)
-  : NumChunks(NumChunks), NumAnnotations(NumAnnotations)
-  , Priority(Priority), Availability(Availability)
+                                           unsigned NumAnnotations,
+                                           CXCursorKind ParentKind,
+                                           StringRef ParentName)
+  : NumChunks(NumChunks), NumAnnotations(NumAnnotations),
+    Priority(Priority), Availability(Availability), ParentKind(ParentKind),
+    ParentName(ParentName)
 { 
   assert(NumChunks <= 0xffff);
   assert(NumAnnotations <= 0xffff);
@@ -272,7 +275,8 @@
   CodeCompletionString *Result 
     = new (Mem) CodeCompletionString(Chunks.data(), Chunks.size(),
                                      Priority, Availability,
-                                     Annotations.data(), Annotations.size());
+                                     Annotations.data(), Annotations.size(),
+                                     ParentKind, ParentName);
   Chunks.clear();
   return Result;
 }
@@ -311,6 +315,70 @@
   Chunks.push_back(Chunk(CK, Text));
 }
 
+void CodeCompletionBuilder::addParentContext(DeclContext *DC) {
+  if (DC->isTranslationUnit()) {
+    ParentKind = CXCursor_TranslationUnit;
+    return;
+  }
+  
+  if (DC->isFunctionOrMethod())
+    return;
+  
+  NamedDecl *ND = dyn_cast<NamedDecl>(DC);
+  if (!ND)
+    return;
+  
+  ParentKind = getCursorKindForDecl(ND);
+  
+  // Check whether we've already cached the parent name.
+  StringRef &CachedParentName = Allocator.getParentNames()[DC];
+  if (!CachedParentName.empty()) {
+    ParentName = CachedParentName;
+    return;
+  }
+
+  // Find the interesting names.
+  llvm::SmallVector<DeclContext *, 2> Contexts;
+  while (DC && !DC->isFunctionOrMethod()) {
+    if (NamedDecl *ND = dyn_cast<NamedDecl>(DC)) {
+      if (ND->getIdentifier())
+        Contexts.push_back(DC);
+    }
+    
+    DC = DC->getParent();
+  }
+
+  {
+    llvm::SmallString<128> S;
+    llvm::raw_svector_ostream OS(S);
+    bool First = true;
+    for (unsigned I = Contexts.size(); I != 0; --I) {
+      if (First)
+        First = false;
+      else {
+        OS << "::";
+      }
+      
+      DeclContext *CurDC = Contexts[I-1];
+      if (ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
+        CurDC = CatImpl->getCategoryDecl();
+      
+      if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
+        ObjCInterfaceDecl *Interface = Cat->getClassInterface();
+        if (!Interface)
+          return;
+        
+        OS << Interface->getName() << '(' << Cat->getName() << ')';
+      } else {
+        OS << cast<NamedDecl>(CurDC)->getName();
+      }
+    }
+    
+    ParentName = Allocator.CopyString(OS.str());
+    CachedParentName = ParentName;
+  }
+}
+
 unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl *ND) {
   if (!ND)
     return CCP_Unlikely;
@@ -444,6 +512,13 @@
 
 void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) {
   switch (Kind) {
+  case RK_Pattern:
+    if (!Declaration) {
+      // Do nothing: Patterns can come with cursor kinds!
+      break;
+    }
+    // Fall through
+      
   case RK_Declaration: {
     // Set the availability based on attributes.
     switch (getDeclAvailability(Declaration)) {
@@ -488,11 +563,7 @@
   case RK_Keyword:
     Availability = CXAvailability_Available;      
     CursorKind = CXCursor_NotImplemented;
-    break;
-      
-  case RK_Pattern:
-    // Do nothing: Patterns can come with cursor kinds!
-    break;
+    break;      
   }
 
   if (!Accessible)