From: Michael Wu Date: Mon, 12 Nov 2018 02:44:33 +0000 (+0000) Subject: Support Swift in platform availability attribute X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4683394cd0b76e9ab4256713fa84206207607c6d;p=clang Support Swift in platform availability attribute Summary: This adds support for Swift platform availability attributes. It's largely a port of the changes made to https://github.com/apple/swift-clang/ for Swift availability attributes. Specifically, https://github.com/apple/swift-clang/commit/84b5a21c31cb5b0d7d958a478bc01964939b6952 and https://github.com/apple/swift-clang/commit/e5b87f265aede41c8381094bbf54e2715c8293b0 . The implementation of attribute_availability_swift is a little different and additional tests in test/Index/availability.c were added. Reviewers: manmanren, friss, doug.gregor, arphaman, jfb, erik.pilkington, aaron.ballman Reviewed By: aaron.ballman Subscribers: aaron.ballman, ColinKinloch, jrmuizel, cfe-commits Differential Revision: https://reviews.llvm.org/D50318 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@346633 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 2e2550aafb..f64cbd4653 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -723,6 +723,7 @@ def Availability : InheritableAttr { .Case("macos_app_extension", "macOS (App Extension)") .Case("tvos_app_extension", "tvOS (App Extension)") .Case("watchos_app_extension", "watchOS (App Extension)") + .Case("swift", "Swift") .Default(llvm::StringRef()); } static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) { diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 2436975c06..44a56d2d4f 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2993,6 +2993,9 @@ def warn_availability_on_static_initializer : Warning< InGroup; def note_overridden_method : Note< "overridden method is here">; +def warn_availability_swift_unavailable_deprecated_only : Warning< + "only 'unavailable' and 'deprecated' are supported for Swift availability">, + InGroup; def note_protocol_method : Note< "protocol method is here">; diff --git a/include/clang/Basic/Features.def b/include/clang/Basic/Features.def index 530978d8e9..0cece27eef 100644 --- a/include/clang/Basic/Features.def +++ b/include/clang/Basic/Features.def @@ -51,6 +51,7 @@ FEATURE(attribute_availability_watchos, true) FEATURE(attribute_availability_with_strict, true) FEATURE(attribute_availability_with_replacement, true) FEATURE(attribute_availability_in_templates, true) +FEATURE(attribute_availability_swift, true) FEATURE(attribute_cf_returns_not_retained, true) FEATURE(attribute_cf_returns_retained, true) FEATURE(attribute_cf_returns_on_parameters, true) diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index af6214cdf6..bff91793d9 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1001,6 +1001,21 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, continue; } + if (Keyword == Ident_deprecated && Platform->Ident && + Platform->Ident->isStr("swift")) { + // For swift, we deprecate for all versions. + if (Changes[Deprecated].KeywordLoc.isValid()) { + Diag(KeywordLoc, diag::err_availability_redundant) + << Keyword + << SourceRange(Changes[Deprecated].KeywordLoc); + } + + Changes[Deprecated].KeywordLoc = KeywordLoc; + // Use a fake version here. + Changes[Deprecated].Version = VersionTuple(1); + continue; + } + if (Tok.isNot(tok::equal)) { Diag(Tok, diag::err_expected_after) << Keyword << tok::equal; SkipUntil(tok::r_paren, StopAtSemi); diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index f3b281b644..b77b77d9ba 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -2410,6 +2410,15 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { if (const auto *SE = dyn_cast_or_null(AL.getReplacementExpr())) Replacement = SE->getString(); + if (II->isStr("swift")) { + if (Introduced.isValid() || Obsoleted.isValid() || + (!IsUnavailable && !Deprecated.isValid())) { + S.Diag(AL.getLoc(), + diag::warn_availability_swift_unavailable_deprecated_only); + return; + } + } + AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, AL.getRange(), II, false/*Implicit*/, Introduced.Version, diff --git a/test/Index/availability.c b/test/Index/availability.c index 206b8a2a71..9f3c995ffa 100644 --- a/test/Index/availability.c +++ b/test/Index/availability.c @@ -14,9 +14,14 @@ void bar(void) __attribute__((availability(macosx,introduced=10.4))) __attribute 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))); +void foo2(void) __attribute__((availability(swift,unavailable))); +void foo3(void) __attribute__((availability(swift,deprecated))); + // 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) +// CHECK: FunctionDecl=foo2:17:6{{.*}}(swift, unavailable) +// CHECK: FunctionDecl=foo3:18:6{{.*}}(swift, deprecated=1) diff --git a/test/Sema/attr-availability-swift.c b/test/Sema/attr-availability-swift.c new file mode 100644 index 0000000000..d77094cb21 --- /dev/null +++ b/test/Sema/attr-availability-swift.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -fblocks -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -ast-dump %s | FileCheck %s +// + +#if !__has_feature(attribute_availability_with_message) +# error "Missing __has_feature" +#endif + +#if __has_feature(attribute_availability_swift) +# warning "okay" +// expected-warning@-1{{okay}} +#else +# error "Missing __has_feature" +#endif + +extern int noSwiftGlobal1 __attribute__((availability(swift, unavailable))); +// CHECK: AvailabilityAttr {{.*}}swift 0 0 0 Unavailable "" "" +extern int noSwiftGlobal1 __attribute__((availability(macosx, introduced=10.1))); // okay +// CHECK: AvailabilityAttr {{.*}}Inherited swift 0 0 0 Unavailable "" "" +// CHECK: AvailabilityAttr {{.*}}macos 10.1 0 0 "" "" +extern int noSwiftGlobal1 __attribute__((availability(swift, unavailable, message="and this one has a message"))); // okay +// CHECK: AvailabilityAttr {{.*}}Inherited macos 10.1 0 0 "" "" +// CHECK: AvailabilityAttr {{.*}}swift 0 0 0 Unavailable "and this one has a message" "" +extern int noSwiftGlobal2 __attribute__((availability(swift, introduced=5))); // expected-warning{{only 'unavailable' and 'deprecated' are supported for Swift availability}} +// CHECK: VarDecl +// CHECK-NOT: AvailabilityAttr +extern int noSwiftGlobal3 __attribute__((availability(swift, deprecated, message="t"))); +// CHECK: VarDecl +// CHECK: AvailabilityAttr {{.*}}swift 0 1 0 "t" ""