Introduce new libclang API functions that determine the availability
of a cursor or code-completion result, e.g., whether that result
refers to an unavailable, deleted, or deprecated declaration.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111858 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 95dbd45..330fa54 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -182,6 +182,19 @@
 
     if (clang_isCursorDefinition(Cursor))
       printf(" (Definition)");
+    
+    switch (clang_getCursorAvailability(Cursor)) {
+      case CXAvailability_Available:
+        break;
+        
+      case CXAvailability_Deprecated:
+        printf(" (deprecated)");
+        break;
+        
+      case CXAvailability_NotAvailable:
+        printf(" (unavailable)");
+        break;
+    }
   }
 }
 
@@ -865,8 +878,21 @@
   clang_disposeString(ks);
 
   print_completion_string(completion_result->CompletionString, file);
-  fprintf(file, " (%u)\n", 
+  fprintf(file, " (%u)", 
           clang_getCompletionPriority(completion_result->CompletionString));
+  switch (clang_getCompletionAvailability(completion_result->CompletionString)){
+  case CXAvailability_Available:
+    break;
+    
+  case CXAvailability_Deprecated:
+    fprintf(file, " (deprecated)");
+    break;
+    
+  case CXAvailability_NotAvailable:
+    fprintf(file, " (unavailable)");
+    break;
+  }
+  fprintf(file, "\n");
 }
 
 int perform_code_completion(int argc, const char **argv, int timing_only) {
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index a98f064..e59bdde 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -3018,6 +3018,21 @@
 }
 
 extern "C" {
+  
+enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
+  if (clang_isDeclaration(cursor.kind))
+    if (Decl *D = cxcursor::getCursorDecl(cursor)) {
+      if (D->hasAttr<UnavailableAttr>() ||
+          (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted()))
+        return CXAvailability_Available;
+      
+      if (D->hasAttr<DeprecatedAttr>())
+        return CXAvailability_Deprecated;
+    }
+  
+  return CXAvailability_Available;
+}
+
 CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
   if (clang_isDeclaration(cursor.kind))
     return getDeclLanguage(cxcursor::getCursorDecl(cursor));
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index c2febf9..e99927b 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -48,11 +48,15 @@
   /// This is the representation behind a CXCompletionString.
   class CXStoredCodeCompletionString : public CodeCompletionString {
     unsigned Priority;
+    CXAvailabilityKind Availability;
     
   public:
-    CXStoredCodeCompletionString(unsigned Priority) : Priority(Priority) { }
+    CXStoredCodeCompletionString(unsigned Priority,
+                                 CXAvailabilityKind Availability) 
+      : Priority(Priority), Availability(Availability) { }
     
     unsigned getPriority() const { return Priority; }
+    CXAvailabilityKind getAvailability() const { return Availability; }
   };
 }
 
@@ -210,6 +214,13 @@
   return CCStr? CCStr->getPriority() : unsigned(CCP_Unlikely);
 }
   
+enum CXAvailabilityKind 
+clang_getCompletionAvailability(CXCompletionString completion_string) {
+  CXStoredCodeCompletionString *CCStr
+    = (CXStoredCodeCompletionString *)completion_string;
+  return CCStr? CCStr->getAvailability() : CXAvailability_Available;
+}
+
 static bool ReadUnsigned(const char *&Memory, const char *MemoryEnd,
                          unsigned &Value) {
   if (Memory + sizeof(unsigned) > MemoryEnd)
@@ -433,8 +444,13 @@
       if (ReadUnsigned(Str, StrEnd, Priority))
         break;
       
+      unsigned Availability;
+      if (ReadUnsigned(Str, StrEnd, Availability))
+        break;
+      
       CXStoredCodeCompletionString *CCStr
-        = new CXStoredCodeCompletionString(Priority);
+        = new CXStoredCodeCompletionString(Priority, 
+                                           (CXAvailabilityKind)Availability);
       if (!CCStr->Deserialize(Str, StrEnd)) {
         delete CCStr;
         continue;
@@ -559,7 +575,8 @@
       AllocatedResults.NumResults = NumResults;
       for (unsigned I = 0; I != NumResults; ++I) {
         CXStoredCodeCompletionString *StoredCompletion
-          = new CXStoredCodeCompletionString(Results[I].Priority);
+          = new CXStoredCodeCompletionString(Results[I].Priority,
+                                             Results[I].Availability);
         (void)Results[I].CreateCodeCompletionString(S, StoredCompletion);
         AllocatedResults.Results[I].CursorKind = Results[I].CursorKind;
         AllocatedResults.Results[I].CompletionString = StoredCompletion;
@@ -743,7 +760,7 @@
     = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
   delete Results;
 }
-
+  
 unsigned 
 clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) {
   AllocatedCXCodeCompleteResults *Results
diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports
index 444d669..f2087b7 100644
--- a/tools/libclang/libclang.darwin.exports
+++ b/tools/libclang/libclang.darwin.exports
@@ -32,11 +32,13 @@
 _clang_getCString
 _clang_getCanonicalType
 _clang_getClangVersion
+_clang_getCompletionAvailability
 _clang_getCompletionChunkCompletionString
 _clang_getCompletionChunkKind
 _clang_getCompletionChunkText
 _clang_getCompletionPriority
 _clang_getCursor
+_clang_getCursorAvailability
 _clang_getCursorDefinition
 _clang_getCursorExtent
 _clang_getCursorKind
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index a1e114a..c1658f6 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -32,11 +32,13 @@
 clang_getCString
 clang_getCanonicalType
 clang_getClangVersion
+clang_getCompletionAvailability
 clang_getCompletionChunkCompletionString
 clang_getCompletionChunkKind
 clang_getCompletionChunkText
 clang_getCompletionPriority
 clang_getCursor
+clang_getCursorAvailability
 clang_getCursorDefinition
 clang_getCursorExtent
 clang_getCursorKind