From: Manman Ren Date: Mon, 22 Feb 2016 04:47:24 +0000 (+0000) Subject: Addressing review comments for r261163. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7391f7f03cb48c406dcd855627888b9895263be7;p=clang Addressing review comments for r261163. Use "strict" instead of "nopartial". Also make strictly not-introduced share the same diagnostics as Obsolete and Unavailable. rdar://23791325 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@261512 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index a16b969316..c7f559d9b3 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -451,7 +451,7 @@ def Availability : InheritableAttr { let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">, VersionArgument<"deprecated">, VersionArgument<"obsoleted">, BoolArgument<"unavailable">, StringArgument<"message">, - BoolArgument<"nopartial">]; + BoolArgument<"strict">]; let AdditionalMembers = [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) { return llvm::StringSwitch(Platform) diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td index 44f6ea2c46..5ed44de420 100644 --- a/include/clang/Basic/AttrDocs.td +++ b/include/clang/Basic/AttrDocs.td @@ -685,20 +685,21 @@ are: Apple's watchOS operating system. The minimum deployment target is specified by the ``-mwatchos-version-min=*version*`` command-line argument. -An optional nopartial can be placed after the platform name. -With the optional nopartial, when deploying back to a platform version prior to -when the declaration was introduced, Clang emits an error specifying that the -function is not introduced yet. - -Without the optional nopartial, a declaration can be used even when deploying back -to a platform version prior to when the declaration was introduced. When this -happens, the declaration is `weakly linked +A declaration can typically be used even when deploying back to a platform +version prior to when the declaration was introduced. When this happens, the +declaration is `weakly linked `_, as if the ``weak_import`` attribute were added to the declaration. A weakly-linked declaration may or may not be present a run-time, and a program can determine whether the declaration is present by checking whether the address of that declaration is non-NULL. +The flag ``strict`` disallows using API when deploying back to a +platform version prior to when the declaration was introduced. An +attempt to use such API before its introduction causes a hard error. +Weakly-linking is almost always a better API choice, since it allows +users to query availability at runtime. + If there are multiple declarations of the same entity, the availability attributes must either match on a per-platform basis or later declarations must not have availability attributes for that diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 875f5ceb90..969050df59 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -87,7 +87,6 @@ def DeprecatedAttributes : DiagGroup<"deprecated-attributes">; def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">; def UnavailableDeclarations : DiagGroup<"unavailable-declarations">; def PartialAvailability : DiagGroup<"partial-availability">; -def NotYetIntroducedDeclarations : DiagGroup<"not-yet-introduced-declarations">; def DeprecatedImplementations :DiagGroup<"deprecated-implementations">; def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">; def DeprecatedRegister : DiagGroup<"deprecated-register">; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 5394a06baf..45d1b4acc1 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -841,7 +841,7 @@ def warn_accessor_property_type_mismatch : Warning< def not_conv_function_declared_at : Note<"type conversion function declared here">; def note_method_declared_at : Note<"method %0 declared here">; def note_property_attribute : Note<"property %0 is declared " - "%select{deprecated|unavailable|partial|not-yet-introduced}1 here">; + "%select{deprecated|unavailable|partial}1 here">; def err_setter_type_void : Error<"type of setter must be void">; def err_duplicate_method_decl : Error<"duplicate declaration of method %0">; def warn_duplicate_method_decl : @@ -4128,14 +4128,9 @@ def err_unavailable_message : Error<"%0 is unavailable: %1">; def warn_unavailable_fwdclass_message : Warning< "%0 may be unavailable because the receiver type is unknown">, InGroup; -def err_notyetintroduced : Error<"%0 is not introduced yet">; -def err_notyetintroduced_message : Error<"%0 is not introduced yet: %1">; -def warn_notyetintroduced_fwdclass_message : Warning< - "%0 may not be introduced because the receiver type is unknown">, - InGroup; def note_availability_specified_here : Note< "%0 has been explicitly marked " - "%select{unavailable|deleted|deprecated|partial|not-yet-introduced}1 here">; + "%select{unavailable|deleted|deprecated|partial}1 here">; def note_implicitly_deleted : Note< "explicitly defaulted function was implicitly deleted here">; def note_inherited_deleted_here : Note< diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 781fdb3f4c..1aabc6ce28 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -134,8 +134,8 @@ class Parser : public CodeCompletionHandler { /// \brief Identifier for "message". IdentifierInfo *Ident_message; - /// \brief Identifier for "nopartial". - IdentifierInfo *Ident_nopartial; + /// \brief Identifier for "strict". + IdentifierInfo *Ident_strict; /// C++0x contextual keywords. mutable IdentifierInfo *Ident_final; diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index bfb85d0d21..836646de60 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -157,13 +157,13 @@ private: + NumArgs)[index]; } - /// The location of the 'nopartial' keyword in an availability attribute. - SourceLocation *getNopartialSlot() { + /// The location of the 'strict' keyword in an availability attribute. + SourceLocation *getStrictSlot() { return reinterpret_cast( &getAvailabilitySlot(ObsoletedSlot) + 1); } - SourceLocation const *getNopartialSlot() const { + SourceLocation const *getStrictSlot() const { return reinterpret_cast( &getAvailabilitySlot(ObsoletedSlot) + 1); } @@ -244,7 +244,7 @@ private: const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *messageExpr, - Syntax syntaxUsed, SourceLocation nopartial) + Syntax syntaxUsed, SourceLocation strict) : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), @@ -256,7 +256,7 @@ private: new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated); new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted); - memcpy(getNopartialSlot(), &nopartial, sizeof(SourceLocation)); + memcpy(getStrictSlot(), &strict, sizeof(SourceLocation)); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -424,9 +424,9 @@ public: return getAvailabilitySlot(ObsoletedSlot); } - SourceLocation getNopartialLoc() const { + SourceLocation getStrictLoc() const { assert(getKind() == AT_Availability && "Not an availability attribute"); - return *getNopartialSlot(); + return *getStrictSlot(); } SourceLocation getUnavailableLoc() const { @@ -624,13 +624,13 @@ public: SourceLocation unavailable, const Expr *MessageExpr, AttributeList::Syntax syntax, - SourceLocation nopartial) { + SourceLocation strict) { void *memory = allocate(AttributeFactory::AvailabilityAllocSize); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated, obsoleted, unavailable, MessageExpr, - syntax, nopartial)); + syntax, strict)); } AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, @@ -760,11 +760,11 @@ public: SourceLocation unavailable, const Expr *MessageExpr, AttributeList::Syntax syntax, - SourceLocation nopartial) { + SourceLocation strict) { AttributeList *attr = pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated, obsoleted, unavailable, MessageExpr, syntax, - nopartial); + strict); add(attr); return attr; } diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h index 43d6764050..155b3aa72d 100644 --- a/include/clang/Sema/DelayedDiagnostic.h +++ b/include/clang/Sema/DelayedDiagnostic.h @@ -113,8 +113,7 @@ private: /// the complete parsing of the current declaration. class DelayedDiagnostic { public: - enum DDKind { Deprecation, Unavailable, Access, ForbiddenType, - NotYetIntroduced }; + enum DDKind { Deprecation, Unavailable, Access, ForbiddenType }; unsigned char Kind; // actually a DDKind bool Triggered; @@ -166,15 +165,13 @@ public: } const NamedDecl *getDeprecationDecl() const { - assert((Kind == Deprecation || Kind == Unavailable || - Kind == NotYetIntroduced) && + assert((Kind == Deprecation || Kind == Unavailable) && "Not a deprecation diagnostic."); return DeprecationData.Decl; } StringRef getDeprecationMessage() const { - assert((Kind == Deprecation || Kind == Unavailable || - Kind == NotYetIntroduced) && + assert((Kind == Deprecation || Kind == Unavailable) && "Not a deprecation diagnostic."); return StringRef(DeprecationData.Message, DeprecationData.MessageLen); diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index ba2e23180e..bfba7b11ef 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2108,7 +2108,7 @@ public: VersionTuple Obsoleted, bool IsUnavailable, StringRef Message, - bool IsNopartial, + bool IsStrict, AvailabilityMergeKind AMK, unsigned AttrSpellingListIndex); TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range, @@ -3536,8 +3536,7 @@ public: void redelayDiagnostics(sema::DelayedDiagnosticPool &pool); - enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable, AD_Partial, - AD_NotYetIntroduced }; + enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable, AD_Partial }; void EmitAvailabilityWarning(AvailabilityDiagnostic AD, NamedDecl *D, StringRef Message, diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 24db6814b8..14b11285ea 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -833,13 +833,13 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) { /// \brief Parse the contents of the "availability" attribute. /// /// availability-attribute: -/// 'availability' '(' platform ',' opt-nopartial version-arg-list, opt-message')' +/// 'availability' '(' platform ',' opt-strict version-arg-list, opt-message')' /// /// platform: /// identifier /// -/// opt-nopartial: -/// 'nopartial' ',' +/// opt-strict: +/// 'strict' ',' /// /// version-arg-list: /// version-arg @@ -892,12 +892,12 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, Ident_obsoleted = PP.getIdentifierInfo("obsoleted"); Ident_unavailable = PP.getIdentifierInfo("unavailable"); Ident_message = PP.getIdentifierInfo("message"); - Ident_nopartial = PP.getIdentifierInfo("nopartial"); + Ident_strict = PP.getIdentifierInfo("strict"); } - // Parse the optional "nopartial" and the set of + // Parse the optional "strict" and the set of // introductions/deprecations/removals. - SourceLocation UnavailableLoc, NopartialLoc; + SourceLocation UnavailableLoc, StrictLoc; do { if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_availability_expected_change); @@ -907,12 +907,12 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, IdentifierInfo *Keyword = Tok.getIdentifierInfo(); SourceLocation KeywordLoc = ConsumeToken(); - if (Keyword == Ident_nopartial) { - if (NopartialLoc.isValid()) { + if (Keyword == Ident_strict) { + if (StrictLoc.isValid()) { Diag(KeywordLoc, diag::err_availability_redundant) - << Keyword << SourceRange(NopartialLoc); + << Keyword << SourceRange(StrictLoc); } - NopartialLoc = KeywordLoc; + StrictLoc = KeywordLoc; continue; } @@ -1037,7 +1037,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, Changes[Deprecated], Changes[Obsoleted], UnavailableLoc, MessageExpr.get(), - Syntax, NopartialLoc); + Syntax, StrictLoc); } /// \brief Parse the contents of the "objc_bridge_related" attribute. diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index cfc02e042c..149765ca81 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -491,7 +491,7 @@ void Parser::Initialize() { Ident_deprecated = nullptr; Ident_obsoleted = nullptr; Ident_unavailable = nullptr; - Ident_nopartial = nullptr; + Ident_strict = nullptr; Ident__except = nullptr; diff --git a/lib/Sema/DelayedDiagnostic.cpp b/lib/Sema/DelayedDiagnostic.cpp index 853f598054..ceea04f276 100644 --- a/lib/Sema/DelayedDiagnostic.cpp +++ b/lib/Sema/DelayedDiagnostic.cpp @@ -35,9 +35,6 @@ DelayedDiagnostic::makeAvailability(Sema::AvailabilityDiagnostic AD, case Sema::AD_Unavailable: DD.Kind = Unavailable; break; - case Sema::AD_NotYetIntroduced: - DD.Kind = NotYetIntroduced; - break; case Sema::AD_Partial: llvm_unreachable("AD_Partial diags should not be delayed"); } @@ -66,7 +63,6 @@ void DelayedDiagnostic::Destroy() { case Deprecation: case Unavailable: - case NotYetIntroduced: delete [] DeprecationData.Message; break; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index a775be9ea2..0f6470bf45 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2196,7 +2196,7 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, NewAttr = S.mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(), AA->getIntroduced(), AA->getDeprecated(), AA->getObsoleted(), AA->getUnavailable(), - AA->getMessage(), AA->getNopartial(), AMK, + AA->getMessage(), AA->getStrict(), AMK, AttrSpellingListIndex); else if (const auto *VA = dyn_cast(Attr)) NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index d2db4b9284..3f6af3d765 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -1918,7 +1918,7 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, VersionTuple Obsoleted, bool IsUnavailable, StringRef Message, - bool IsNopartial, + bool IsStrict, AvailabilityMergeKind AMK, unsigned AttrSpellingListIndex) { VersionTuple MergedIntroduced = Introduced; @@ -2065,7 +2065,7 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, return ::new (Context) AvailabilityAttr(Range, Context, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable, Message, - IsNopartial, AttrSpellingListIndex); + IsStrict, AttrSpellingListIndex); } return nullptr; } @@ -2092,7 +2092,7 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated(); AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted(); bool IsUnavailable = Attr.getUnavailableLoc().isValid(); - bool IsNopartial = Attr.getNopartialLoc().isValid(); + bool IsStrict = Attr.getStrictLoc().isValid(); StringRef Str; if (const StringLiteral *SE = dyn_cast_or_null(Attr.getMessageExpr())) @@ -2103,7 +2103,7 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, Deprecated.Version, Obsoleted.Version, IsUnavailable, Str, - IsNopartial, + IsStrict, Sema::AMK_None, Index); if (NewAttr) @@ -2148,7 +2148,7 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, NewDeprecated, NewObsoleted, IsUnavailable, Str, - IsNopartial, + IsStrict, Sema::AMK_None, Index); if (NewAttr) @@ -2171,7 +2171,7 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, Deprecated.Version, Obsoleted.Version, IsUnavailable, Str, - IsNopartial, + IsStrict, Sema::AMK_None, Index); if (NewAttr) @@ -5964,14 +5964,6 @@ static void DoEmitAvailabilityWarning(Sema &S, Sema::AvailabilityDiagnostic K, property_note_select = /* partial */ 2; available_here_select_kind = /* partial */ 3; break; - - case Sema::AD_NotYetIntroduced: - diag = diag::err_notyetintroduced; - diag_message = diag::err_notyetintroduced_message; - diag_fwdclass_message = diag::warn_notyetintroduced_fwdclass_message; - property_note_select = /* deprecated */ 3; - available_here_select_kind = /* notyetintroduced */ 4; - break; } if (!Message.empty()) { @@ -5998,22 +5990,10 @@ static void DoEmitAvailabilityWarning(Sema &S, Sema::AvailabilityDiagnostic K, static void handleDelayedAvailabilityCheck(Sema &S, DelayedDiagnostic &DD, Decl *Ctx) { assert(DD.Kind == DelayedDiagnostic::Deprecation || - DD.Kind == DelayedDiagnostic::Unavailable || - DD.Kind == DelayedDiagnostic::NotYetIntroduced); - Sema::AvailabilityDiagnostic AD; - switch (DD.Kind) { - case DelayedDiagnostic::Deprecation: - AD = Sema::AD_Deprecation; - break; - case DelayedDiagnostic::Unavailable: - AD = Sema::AD_Unavailable; - break; - case DelayedDiagnostic::NotYetIntroduced: - AD = Sema::AD_NotYetIntroduced; - break; - default: - llvm_unreachable("Expecting: deprecated, unavailable, not-yet-introduced"); - } + DD.Kind == DelayedDiagnostic::Unavailable); + Sema::AvailabilityDiagnostic AD = DD.Kind == DelayedDiagnostic::Deprecation + ? Sema::AD_Deprecation + : Sema::AD_Unavailable; DD.Triggered = true; DoEmitAvailabilityWarning( S, AD, Ctx, DD.getDeprecationDecl(), DD.getDeprecationMessage(), DD.Loc, diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index ad6280d6c7..bfbca298ce 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -159,12 +159,11 @@ DiagnoseAvailabilityOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc, break; case AR_NotYetIntroduced: { - // With nopartial, the compiler will emit delayed error just like how - // "deprecated, unavailable" are handled. + // With strict, the compiler will emit unavailable error. AvailabilityAttr *AA = D->getAttr(); - if (AA && AA->getNopartial() && + if (AA && AA->getStrict() && S.getCurContextAvailability() != AR_NotYetIntroduced) - S.EmitAvailabilityWarning(Sema::AD_NotYetIntroduced, + S.EmitAvailabilityWarning(Sema::AD_Unavailable, D, Message, Loc, UnknownObjCClass, ObjCPDecl, ObjCPropertyAccess); diff --git a/test/Sema/attr-availability-macosx.c b/test/Sema/attr-availability-macosx.c index 8f5550ede2..a177ef2972 100644 --- a/test/Sema/attr-availability-macosx.c +++ b/test/Sema/attr-availability-macosx.c @@ -6,7 +6,7 @@ void f2(int) __attribute__((availability(macosx,introduced=10.4,deprecated=10.5) void f3(int) __attribute__((availability(macosx,introduced=10.6))); void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(ios,introduced=2.0,deprecated=3.0))); // expected-note{{explicitly marked unavailable}} void f5(int) __attribute__((availability(ios,introduced=3.2), availability(macosx,unavailable))); // expected-note{{'f5' has been explicitly marked unavailable here}} -void f6(int) __attribute__((availability(macosx,nopartial,introduced=10.6))); //expected-note{{'f6' has been explicitly marked not-yet-introduced here}} +void f6(int) __attribute__((availability(macosx,strict,introduced=10.6))); //expected-note{{'f6' has been explicitly marked unavailable here}} void test() { f0(0); @@ -15,7 +15,7 @@ void test() { f3(0); f4(0); // expected-error{{f4' is unavailable: obsoleted in OS X 10.5}} f5(0); // expected-error{{'f5' is unavailable: not available on OS X}} - f6(0); // expected-error{{'f6' is not introduced yet: introduced in OS X 10.6}} + f6(0); // expected-error{{'f6' is unavailable: introduced in OS X 10.6}} } // rdar://10535640