From: Argyrios Kyrtzidis Date: Tue, 15 Oct 2013 17:00:53 +0000 (+0000) Subject: [libclang] When querying for the availability of an enumerator, pick up the availabil... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2bf1c0127382709a935ce87646c0662def3a0707;p=clang [libclang] When querying for the availability of an enumerator, pick up the availability from the enum declaration. rdar://14789001. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192718 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Index/availability.c b/test/Index/availability.c index e6b1273aca..cfe0ff5bea 100644 --- a/test/Index/availability.c +++ b/test/Index/availability.c @@ -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) diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 967750f954..8e14d3ff16 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -5835,25 +5835,30 @@ static CXLanguageKind getDeclLanguage(const Decl *D) { } extern "C" { + +static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) { + if (isa(D) && cast(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(D) && cast(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(D)) + return getCursorAvailabilityForDecl(cast(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(*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(*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(*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(D)) + return getCursorPlatformAvailabilityForDecl( + cast(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);