summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-10-15 17:00:53 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-10-15 17:00:53 +0000
commit2bf1c0127382709a935ce87646c0662def3a0707 (patch)
tree854acfc77f65730eb026cc12a06421ed86002b30 /tools
parent64601ce643e27e970a6360f00b5e911aa9953f9b (diff)
downloadclang-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.cpp115
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);