forked from OSchip/llvm-project
[libclang] Merge multiple availability clauses when getting the platform's
availability Patch by Ronald Wampler! Differential Revision: https://reviews.llvm.org/D33478 llvm-svn: 305117
This commit is contained in:
parent
86a3ef5b03
commit
2e34be23a2
|
@ -8,13 +8,15 @@ enum {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
old_enum_plat
|
old_enum_plat
|
||||||
} __attribute__((availability(macosx,introduced=10.4,deprecated=10.5,obsoleted=10.7)
|
} __attribute__((availability(macosx,introduced=10.4,deprecated=10.5,obsoleted=10.7)));
|
||||||
|
|
||||||
// RUN: c-index-test -test-load-source all %s > %t
|
void bar(void) __attribute__((availability(macosx,introduced=10.4))) __attribute__((availability(macosx,obsoleted=10.6))) __attribute__((availability(ios,introduced=3.2))) __attribute__((availability(macosx,deprecated=10.5,message="use foobar")));
|
||||||
// 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: (macos, introduced=10.4, deprecated=10.5, obsoleted=10.7)
|
|
||||||
|
|
||||||
// CHECK-2: EnumConstantDecl=old_enum:6:3 (Definition) (deprecated)
|
void bar2(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.5,obsoleted=10.7))) __attribute__((availability(ios,introduced=3.2,deprecated=10.0))) __attribute__((availability(macosx,introduced=10.4,deprecated=10.5,obsoleted=10.7))) __attribute__((availability(ios,introduced=3.2,deprecated=10.0)));
|
||||||
// CHECK-2: EnumConstantDecl=old_enum_plat:10:3 {{.*}} (macos, introduced=10.4, deprecated=10.5, obsoleted=10.7)
|
|
||||||
|
// RUN: c-index-test -test-load-source all %s | FileCheck %s
|
||||||
|
// CHECK: FunctionDecl=foo:3:6 {{.*}} (ios, introduced=3.2, deprecated=4.1) (macos, introduced=10.4, deprecated=10.5, obsoleted=10.7)
|
||||||
|
// CHECK: EnumConstantDecl=old_enum:6:3 (Definition) (deprecated)
|
||||||
|
// CHECK: EnumConstantDecl=old_enum_plat:10:3 {{.*}} (macos, introduced=10.4, deprecated=10.5, obsoleted=10.7)
|
||||||
|
// CHECK: FunctionDecl=bar:13:6 {{.*}} (ios, introduced=3.2) (macos, introduced=10.4, deprecated=10.5, obsoleted=10.6, message="use foobar")
|
||||||
|
// CHECK: FunctionDecl=bar2:15:6 {{.*}} (ios, introduced=3.2, deprecated=10.0) (macos, introduced=10.4, deprecated=10.5, obsoleted=10.7)
|
||||||
|
|
|
@ -7216,15 +7216,11 @@ static CXVersion convertVersion(VersionTuple In) {
|
||||||
return Out;
|
return Out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getCursorPlatformAvailabilityForDecl(const Decl *D,
|
static void getCursorPlatformAvailabilityForDecl(
|
||||||
int *always_deprecated,
|
const Decl *D, int *always_deprecated, CXString *deprecated_message,
|
||||||
CXString *deprecated_message,
|
int *always_unavailable, CXString *unavailable_message,
|
||||||
int *always_unavailable,
|
SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
|
||||||
CXString *unavailable_message,
|
|
||||||
CXPlatformAvailability *availability,
|
|
||||||
int availability_size) {
|
|
||||||
bool HadAvailAttr = false;
|
bool HadAvailAttr = false;
|
||||||
int N = 0;
|
|
||||||
for (auto A : D->attrs()) {
|
for (auto A : D->attrs()) {
|
||||||
if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
|
if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
|
||||||
HadAvailAttr = true;
|
HadAvailAttr = true;
|
||||||
|
@ -7249,36 +7245,69 @@ static int getCursorPlatformAvailabilityForDecl(const Decl *D,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
|
if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
|
||||||
|
AvailabilityAttrs.push_back(Avail);
|
||||||
HadAvailAttr = true;
|
HadAvailAttr = true;
|
||||||
if (N < availability_size) {
|
|
||||||
availability[N].Platform
|
|
||||||
= cxstring::createDup(Avail->getPlatform()->getName());
|
|
||||||
availability[N].Introduced = convertVersion(Avail->getIntroduced());
|
|
||||||
availability[N].Deprecated = convertVersion(Avail->getDeprecated());
|
|
||||||
availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
|
|
||||||
availability[N].Unavailable = Avail->getUnavailable();
|
|
||||||
availability[N].Message = cxstring::createDup(Avail->getMessage());
|
|
||||||
}
|
|
||||||
++N;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HadAvailAttr)
|
if (!HadAvailAttr)
|
||||||
if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
|
if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
|
||||||
return getCursorPlatformAvailabilityForDecl(
|
return getCursorPlatformAvailabilityForDecl(
|
||||||
cast<Decl>(EnumConst->getDeclContext()),
|
cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
|
||||||
always_deprecated,
|
deprecated_message, always_unavailable, unavailable_message,
|
||||||
deprecated_message,
|
AvailabilityAttrs);
|
||||||
always_unavailable,
|
|
||||||
unavailable_message,
|
|
||||||
availability,
|
|
||||||
availability_size);
|
|
||||||
|
|
||||||
return N;
|
if (AvailabilityAttrs.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::sort(AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
|
||||||
|
[](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
|
||||||
|
return LHS->getPlatform() > RHS->getPlatform();
|
||||||
|
});
|
||||||
|
ASTContext &Ctx = D->getASTContext();
|
||||||
|
auto It = std::unique(
|
||||||
|
AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
|
||||||
|
[&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
|
||||||
|
if (LHS->getPlatform() != RHS->getPlatform())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (LHS->getIntroduced() == RHS->getIntroduced() &&
|
||||||
|
LHS->getDeprecated() == RHS->getDeprecated() &&
|
||||||
|
LHS->getObsoleted() == RHS->getObsoleted() &&
|
||||||
|
LHS->getMessage() == RHS->getMessage() &&
|
||||||
|
LHS->getReplacement() == RHS->getReplacement())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
|
||||||
|
(!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
|
||||||
|
(!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
|
||||||
|
LHS->setIntroduced(Ctx, RHS->getIntroduced());
|
||||||
|
|
||||||
|
if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
|
||||||
|
LHS->setDeprecated(Ctx, RHS->getDeprecated());
|
||||||
|
if (LHS->getMessage().empty())
|
||||||
|
LHS->setMessage(Ctx, RHS->getMessage());
|
||||||
|
if (LHS->getReplacement().empty())
|
||||||
|
LHS->setReplacement(Ctx, RHS->getReplacement());
|
||||||
}
|
}
|
||||||
|
|
||||||
int clang_getCursorPlatformAvailability(CXCursor cursor,
|
if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
|
||||||
int *always_deprecated,
|
LHS->setObsoleted(Ctx, RHS->getObsoleted());
|
||||||
|
if (LHS->getMessage().empty())
|
||||||
|
LHS->setMessage(Ctx, RHS->getMessage());
|
||||||
|
if (LHS->getReplacement().empty())
|
||||||
|
LHS->setReplacement(Ctx, RHS->getReplacement());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
|
||||||
CXString *deprecated_message,
|
CXString *deprecated_message,
|
||||||
int *always_unavailable,
|
int *always_unavailable,
|
||||||
CXString *unavailable_message,
|
CXString *unavailable_message,
|
||||||
|
@ -7300,12 +7329,27 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
|
||||||
if (!D)
|
if (!D)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
|
SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
|
||||||
deprecated_message,
|
getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
|
||||||
always_unavailable,
|
always_unavailable, unavailable_message,
|
||||||
unavailable_message,
|
AvailabilityAttrs);
|
||||||
availability,
|
for (const auto &Avail :
|
||||||
availability_size);
|
llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
|
||||||
|
.take_front(availability_size))) {
|
||||||
|
availability[Avail.index()].Platform =
|
||||||
|
cxstring::createDup(Avail.value()->getPlatform()->getName());
|
||||||
|
availability[Avail.index()].Introduced =
|
||||||
|
convertVersion(Avail.value()->getIntroduced());
|
||||||
|
availability[Avail.index()].Deprecated =
|
||||||
|
convertVersion(Avail.value()->getDeprecated());
|
||||||
|
availability[Avail.index()].Obsoleted =
|
||||||
|
convertVersion(Avail.value()->getObsoleted());
|
||||||
|
availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
|
||||||
|
availability[Avail.index()].Message =
|
||||||
|
cxstring::createDup(Avail.value()->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return AvailabilityAttrs.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
|
void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
|
||||||
|
|
Loading…
Reference in New Issue