Add a new libclang API to return a CXCompletionString for an arbitrary
cursor, from Connor Wakamo! Addresses <rdar://problem/9087798>.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136911 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 b737a38..0fec798 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1333,7 +1333,13 @@
                                clang_getLocation(TU, file, Locations[Loc].line,
                                                  Locations[Loc].column));
       if (I + 1 == Repeats) {
+        CXCompletionString completionString = clang_getCursorCompletionString(
+                                                                        Cursor);
         PrintCursor(TU, Cursor);
+        if (completionString != NULL) {
+          printf("\nCompletion string: ");
+          print_completion_string(completionString, stdout);
+        }
         printf("\n");
         free(Locations[Loc].filename);
       }
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index b3c57dc..bbc9343 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -577,4 +577,40 @@
   entry = 1;
   return flag;
 }
+  
+CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
+  enum CXCursorKind kind = clang_getCursorKind(cursor);
+  if (clang_isDeclaration(kind)) {
+    Decl *decl = getCursorDecl(cursor);
+    if (isa<NamedDecl>(decl)) {
+      NamedDecl *namedDecl = (NamedDecl *)decl;
+      ASTUnit *unit = getCursorASTUnit(cursor);
+      if (unit->hasSema()) {
+        Sema &S = unit->getSema();
+        CodeCompletionAllocator *Allocator 
+          = unit->getCursorCompletionAllocator().getPtr();
+        CodeCompletionResult Result(namedDecl);
+        CodeCompletionString *String 
+          = Result.CreateCodeCompletionString(S, *Allocator);
+        return String;
+      }
+    }
+  }
+  else if (kind == CXCursor_MacroDefinition) {
+    MacroDefinition *definition = getCursorMacroDefinition(cursor);
+    const IdentifierInfo *MacroInfo = definition->getName();
+    ASTUnit *unit = getCursorASTUnit(cursor);
+    if (unit->hasSema()) {
+      Sema &S = unit->getSema();
+      CodeCompletionAllocator *Allocator
+        = unit->getCursorCompletionAllocator().getPtr();
+      CodeCompletionResult Result((IdentifierInfo *)MacroInfo);
+      CodeCompletionString *String 
+        = Result.CreateCodeCompletionString(S, *Allocator);
+      return String;
+    }
+  }
+  return NULL;
+}
+  
 } // end: extern "C"
diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports
index 5990536..a858f62 100644
--- a/tools/libclang/libclang.darwin.exports
+++ b/tools/libclang/libclang.darwin.exports
@@ -55,6 +55,7 @@
 _clang_getCompletionPriority
 _clang_getCursor
 _clang_getCursorAvailability
+_clang_getCursorCompletionString
 _clang_getCursorDefinition
 _clang_getCursorDisplayName
 _clang_getCursorExtent
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index ab9face..85e9f02 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -55,6 +55,7 @@
 clang_getCompletionPriority
 clang_getCursor
 clang_getCursorAvailability
+clang_getCursorCompletionString
 clang_getCursorDefinition
 clang_getCursorDisplayName
 clang_getCursorExtent