]> granicus.if.org Git - clang/commitdiff
[libclang] When querying for the availability of an enumerator, pick up the availabil...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 15 Oct 2013 17:00:53 +0000 (17:00 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 15 Oct 2013 17:00:53 +0000 (17:00 +0000)
rdar://14789001.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192718 91177308-0d34-0410-b5e6-96231b3b80d8

test/Index/availability.c
tools/libclang/CIndex.cpp

index e6b1273acafb83ff8dafebe44e545ed6458618fe..cfe0ff5bea81b5f99770d7794c6679b3e9ec0916 100644 (file)
@@ -2,9 +2,19 @@
 
 void foo(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.5,obsoleted=10.7), availability(ios,introduced=3.2,deprecated=4.1)));
 
+enum {
+  old_enum
+} __attribute__((deprecated));
+
+enum {
+  old_enum_plat
+} __attribute__((availability(macosx,introduced=10.4,deprecated=10.5,obsoleted=10.7)
+
 // RUN: c-index-test -test-load-source all %s > %t
 // RUN: FileCheck -check-prefix=CHECK-1 %s < %t
 // RUN: FileCheck -check-prefix=CHECK-2 %s < %t
 // CHECK-1: (ios, introduced=3.2, deprecated=4.1) 
 // CHECK-2: (macosx, introduced=10.4, deprecated=10.5, obsoleted=10.7)
 
+// CHECK-2: EnumConstantDecl=old_enum:6:3 (Definition) (deprecated)
+// CHECK-2: EnumConstantDecl=old_enum_plat:10:3 {{.*}} (macosx, introduced=10.4, deprecated=10.5, obsoleted=10.7)
index 967750f954a54f0f6e0097a200597dcfbfa772f5..8e14d3ff16b6a8ea99df4278b385491a7902f69f 100644 (file)
@@ -5835,25 +5835,30 @@ static CXLanguageKind getDeclLanguage(const Decl *D) {
 }
 
 extern "C" {
+
+static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
+  if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
+    return CXAvailability_Available;
   
-enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
-  if (clang_isDeclaration(cursor.kind))
-    if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
-      if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
-        return CXAvailability_Available;
-      
-      switch (D->getAvailability()) {
-      case AR_Available:
-      case AR_NotYetIntroduced:
-        return CXAvailability_Available;
+  switch (D->getAvailability()) {
+  case AR_Available:
+  case AR_NotYetIntroduced:
+    if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
+      return getCursorAvailabilityForDecl(cast<Decl>(EnumConst->getDeclContext()));
+    return CXAvailability_Available;
 
-      case AR_Deprecated:
-        return CXAvailability_Deprecated;
+  case AR_Deprecated:
+    return CXAvailability_Deprecated;
 
-      case AR_Unavailable:
-        return CXAvailability_NotAvailable;
-      }
-    }
+  case AR_Unavailable:
+    return CXAvailability_NotAvailable;
+  }
+}
+
+enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
+  if (clang_isDeclaration(cursor.kind))
+    if (const Decl *D = cxcursor::getCursorDecl(cursor))
+      return getCursorAvailabilityForDecl(D);
 
   return CXAvailability_Available;
 }
@@ -5877,34 +5882,20 @@ static CXVersion convertVersion(VersionTuple In) {
   
   return Out;
 }
-  
-int clang_getCursorPlatformAvailability(CXCursor cursor,
-                                        int *always_deprecated,
-                                        CXString *deprecated_message,
-                                        int *always_unavailable,
-                                        CXString *unavailable_message,
-                                        CXPlatformAvailability *availability,
-                                        int availability_size) {
-  if (always_deprecated)
-    *always_deprecated = 0;
-  if (deprecated_message)
-    *deprecated_message = cxstring::createEmpty();
-  if (always_unavailable)
-    *always_unavailable = 0;
-  if (unavailable_message)
-    *unavailable_message = cxstring::createEmpty();
-  
-  if (!clang_isDeclaration(cursor.kind))
-    return 0;
-  
-  const Decl *D = cxcursor::getCursorDecl(cursor);
-  if (!D)
-    return 0;
-  
+
+static int getCursorPlatformAvailabilityForDecl(const Decl *D,
+                                                int *always_deprecated,
+                                                CXString *deprecated_message,
+                                                int *always_unavailable,
+                                                CXString *unavailable_message,
+                                           CXPlatformAvailability *availability,
+                                                int availability_size) {
+  bool HadAvailAttr = false;
   int N = 0;
   for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
        ++A) {
     if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
+      HadAvailAttr = true;
       if (always_deprecated)
         *always_deprecated = 1;
       if (deprecated_message)
@@ -5913,6 +5904,7 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
     }
     
     if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
+      HadAvailAttr = true;
       if (always_unavailable)
         *always_unavailable = 1;
       if (unavailable_message) {
@@ -5922,6 +5914,7 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
     }
     
     if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
+      HadAvailAttr = true;
       if (N < availability_size) {
         availability[N].Platform
           = cxstring::createDup(Avail->getPlatform()->getName());
@@ -5934,9 +5927,51 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
       ++N;
     }
   }
+
+  if (!HadAvailAttr)
+    if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
+      return getCursorPlatformAvailabilityForDecl(
+                                        cast<Decl>(EnumConst->getDeclContext()),
+                                                  always_deprecated,
+                                                  deprecated_message,
+                                                  always_unavailable,
+                                                  unavailable_message,
+                                                  availability,
+                                                  availability_size);
   
   return N;
 }
+
+int clang_getCursorPlatformAvailability(CXCursor cursor,
+                                        int *always_deprecated,
+                                        CXString *deprecated_message,
+                                        int *always_unavailable,
+                                        CXString *unavailable_message,
+                                        CXPlatformAvailability *availability,
+                                        int availability_size) {
+  if (always_deprecated)
+    *always_deprecated = 0;
+  if (deprecated_message)
+    *deprecated_message = cxstring::createEmpty();
+  if (always_unavailable)
+    *always_unavailable = 0;
+  if (unavailable_message)
+    *unavailable_message = cxstring::createEmpty();
+
+  if (!clang_isDeclaration(cursor.kind))
+    return 0;
+
+  const Decl *D = cxcursor::getCursorDecl(cursor);
+  if (!D)
+    return 0;
+
+  return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
+                                              deprecated_message,
+                                              always_unavailable,
+                                              unavailable_message,
+                                              availability,
+                                              availability_size);
+}
   
 void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
   clang_disposeString(availability->Platform);