diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-10-15 17:00:53 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-10-15 17:00:53 +0000 |
commit | 2bf1c0127382709a935ce87646c0662def3a0707 (patch) | |
tree | 854acfc77f65730eb026cc12a06421ed86002b30 /tools | |
parent | 64601ce643e27e970a6360f00b5e911aa9953f9b (diff) | |
download | clang-2bf1c0127382709a935ce87646c0662def3a0707.tar.gz clang-2bf1c0127382709a935ce87646c0662def3a0707.tar.bz2 clang-2bf1c0127382709a935ce87646c0662def3a0707.tar.xz |
[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
Diffstat (limited to 'tools')
-rw-r--r-- | tools/libclang/CIndex.cpp | 115 |
1 files changed, 75 insertions, 40 deletions
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<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); |