r261163 - Add 'nopartial' qualifier for availability attributes.
Manman Ren via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 18 16:11:55 PST 2016
> On Feb 18, 2016, at 7:16 AM, Duncan P. N. Exon Smith via cfe-commits <cfe-commits at lists.llvm.org> wrote:
>
>>
>> On 2016-Feb-17, at 14:05, Manman Ren via cfe-commits <cfe-commits at lists.llvm.org> wrote:
>>
>> Author: mren
>> Date: Wed Feb 17 16:05:48 2016
>> New Revision: 261163
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=261163&view=rev
>> Log:
>> Add 'nopartial' qualifier for availability attributes.
>>
>> An optional nopartial can be placed after the platform name.
>> int bar() __attribute__((availability(macosx,nopartial,introduced=10.12))
>>
>> When deploying back to a platform version prior to when the declaration was
>> introduced, with 'nopartial', Clang emits an error specifying that the function
>> is not introduced yet; without 'nopartial', the behavior stays the same: the
>> declaration is `weakly linked`.
>>
>> A member is added to the end of AttributeList to save the location of the
>> 'nopartial' keyword. A bool member is added to AvailabilityAttr.
>>
>> The diagnostics for 'nopartial' not-yet-introduced is handled in the same way as
>> we handle unavailable cases.
>>
>> Reviewed by Doug Gregor and Jordan Rose.
>>
>> rdar://23791325
>>
>> Modified:
>> cfe/trunk/include/clang/Basic/Attr.td
>> cfe/trunk/include/clang/Basic/AttrDocs.td
>> cfe/trunk/include/clang/Basic/DiagnosticGroups.td
>> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> cfe/trunk/include/clang/Parse/Parser.h
>> cfe/trunk/include/clang/Sema/AttributeList.h
>> cfe/trunk/include/clang/Sema/DelayedDiagnostic.h
>> cfe/trunk/include/clang/Sema/Sema.h
>> cfe/trunk/lib/Parse/ParseDecl.cpp
>> cfe/trunk/lib/Parse/Parser.cpp
>> cfe/trunk/lib/Sema/DelayedDiagnostic.cpp
>> cfe/trunk/lib/Sema/SemaDecl.cpp
>> cfe/trunk/lib/Sema/SemaDeclAttr.cpp
>> cfe/trunk/lib/Sema/SemaExpr.cpp
>> cfe/trunk/test/Sema/attr-availability-macosx.c
>>
>> Modified: cfe/trunk/include/clang/Basic/Attr.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/Attr.td (original)
>> +++ cfe/trunk/include/clang/Basic/Attr.td Wed Feb 17 16:05:48 2016
>> @@ -450,7 +450,8 @@ def Availability : InheritableAttr {
>> let Spellings = [GNU<"availability">];
>> let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">,
>> VersionArgument<"deprecated">, VersionArgument<"obsoleted">,
>> - BoolArgument<"unavailable">, StringArgument<"message">];
>> + BoolArgument<"unavailable">, StringArgument<"message">,
>> + BoolArgument<"nopartial">];
>> let AdditionalMembers =
>> [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) {
>> return llvm::StringSwitch<llvm::StringRef>(Platform)
>>
>> Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
>> +++ cfe/trunk/include/clang/Basic/AttrDocs.td Wed Feb 17 16:05:48 2016
>> @@ -685,9 +685,14 @@ are:
>> Apple's watchOS operating system. The minimum deployment target is specified by
>> the ``-mwatchos-version-min=*version*`` command-line argument.
>>
>> -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
>> +An optional nopartial
>
> This should really be "``nopartial``" (code-quotes). However, I have
> a more substantial edit below.
>
>> 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.
>
> I'd rather de-emphasize the new flag. We're not expecting much adoption of
> it (just libc++), so we should keep the text focused on describing the
> default behaviour. I suggest leaving the wording more like the original:
> ```
> 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
> . . .
> ```
> ^ I've just added the word "typically".
>
> Later, add a paragraph:
> ```
> The flag ``flag-name`` 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.
> ```
Will update the doc.
>
> I'm also not sure about "nopartial" (my fault, this name was my idea).
> In the context of all the text we have about availability (here, and
> in the errors and notes) I think "strict" fits much better.
I will also change the name to “strict’.
>
>> When this
>> +happens, the declaration is `weakly linked
>> <https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html>`_,
>> 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
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Wed Feb 17 16:05:48 2016
>> @@ -87,6 +87,7 @@ def DeprecatedAttributes : DiagGroup<"de
>> 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">;
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Feb 17 16:05:48 2016
>> @@ -837,7 +837,7 @@ def warn_accessor_property_type_mismatch
>> 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}1 here">;
>> + "%select{deprecated|unavailable|partial|not-yet-introduced}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 :
>> @@ -4120,9 +4120,14 @@ def err_unavailable_message : Error<"%0
>> def warn_unavailable_fwdclass_message : Warning<
>> "%0 may be unavailable because the receiver type is unknown">,
>> InGroup<UnavailableDeclarations>;
>> +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<NotYetIntroducedDeclarations>;
>
> There's no testcase for this warning. However, I'm not sure you'll
> need all these new diagnostics given my other suggestions below.
>
>> def note_availability_specified_here : Note<
>> "%0 has been explicitly marked "
>> - "%select{unavailable|deleted|deprecated|partial}1 here">;
>> + "%select{unavailable|deleted|deprecated|partial|not-yet-introduced}1 here">;
>> def note_implicitly_deleted : Note<
>> "explicitly defaulted function was implicitly deleted here">;
>> def note_inherited_deleted_here : Note<
>>
>> Modified: cfe/trunk/include/clang/Parse/Parser.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Parse/Parser.h (original)
>> +++ cfe/trunk/include/clang/Parse/Parser.h Wed Feb 17 16:05:48 2016
>> @@ -134,6 +134,9 @@ class Parser : public CodeCompletionHand
>> /// \brief Identifier for "message".
>> IdentifierInfo *Ident_message;
>>
>> + /// \brief Identifier for "nopartial".
>> + IdentifierInfo *Ident_nopartial;
>> +
>> /// C++0x contextual keywords.
>> mutable IdentifierInfo *Ident_final;
>> mutable IdentifierInfo *Ident_override;
>>
>> Modified: cfe/trunk/include/clang/Sema/AttributeList.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Sema/AttributeList.h (original)
>> +++ cfe/trunk/include/clang/Sema/AttributeList.h Wed Feb 17 16:05:48 2016
>> @@ -157,6 +157,17 @@ private:
>> + NumArgs)[index];
>> }
>>
>> + /// The location of the 'nopartial' keyword in an availability attribute.
>> + SourceLocation *getNopartialSlot() {
>> + return reinterpret_cast<SourceLocation*>(
>> + &getAvailabilitySlot(ObsoletedSlot) + 1);
>> + }
>> +
>> + SourceLocation const *getNopartialSlot() const {
>> + return reinterpret_cast<SourceLocation const*>(
>> + &getAvailabilitySlot(ObsoletedSlot) + 1);
>> + }
>> +
>> public:
>> struct TypeTagForDatatypeData {
>> ParsedType *MatchingCType;
>> @@ -233,7 +244,7 @@ private:
>> const AvailabilityChange &obsoleted,
>> SourceLocation unavailable,
>> const Expr *messageExpr,
>> - Syntax syntaxUsed)
>> + Syntax syntaxUsed, SourceLocation nopartial)
>> : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
>> ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
>> Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
>> @@ -245,6 +256,7 @@ private:
>> new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
>> new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
>> new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
>> + memcpy(getNopartialSlot(), &nopartial, sizeof(SourceLocation));
>> AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
>> }
>>
>> @@ -412,6 +424,11 @@ public:
>> return getAvailabilitySlot(ObsoletedSlot);
>> }
>>
>> + SourceLocation getNopartialLoc() const {
>> + assert(getKind() == AT_Availability && "Not an availability attribute");
>> + return *getNopartialSlot();
>> + }
>> +
>> SourceLocation getUnavailableLoc() const {
>> assert(getKind() == AT_Availability && "Not an availability attribute");
>> return UnavailableLoc;
>> @@ -488,7 +505,7 @@ public:
>> AvailabilityAllocSize =
>> sizeof(AttributeList)
>> + ((3 * sizeof(AvailabilityChange) + sizeof(void*) +
>> - sizeof(ArgsUnion) - 1)
>> + sizeof(ArgsUnion) + sizeof(SourceLocation) - 1)
>> / sizeof(void*) * sizeof(void*)),
>> TypeTagForDatatypeAllocSize =
>> sizeof(AttributeList)
>> @@ -606,13 +623,14 @@ public:
>> const AvailabilityChange &obsoleted,
>> SourceLocation unavailable,
>> const Expr *MessageExpr,
>> - AttributeList::Syntax syntax) {
>> + AttributeList::Syntax syntax,
>> + SourceLocation nopartial) {
>> void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
>> return add(new (memory) AttributeList(attrName, attrRange,
>> scopeName, scopeLoc,
>> Param, introduced, deprecated,
>> obsoleted, unavailable, MessageExpr,
>> - syntax));
>> + syntax, nopartial));
>> }
>>
>> AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
>> @@ -741,10 +759,12 @@ public:
>> const AvailabilityChange &obsoleted,
>> SourceLocation unavailable,
>> const Expr *MessageExpr,
>> - AttributeList::Syntax syntax) {
>> + AttributeList::Syntax syntax,
>> + SourceLocation nopartial) {
>> AttributeList *attr =
>> pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
>> - deprecated, obsoleted, unavailable, MessageExpr, syntax);
>> + deprecated, obsoleted, unavailable, MessageExpr, syntax,
>> + nopartial);
>> add(attr);
>> return attr;
>> }
>>
>> Modified: cfe/trunk/include/clang/Sema/DelayedDiagnostic.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DelayedDiagnostic.h?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Sema/DelayedDiagnostic.h (original)
>> +++ cfe/trunk/include/clang/Sema/DelayedDiagnostic.h Wed Feb 17 16:05:48 2016
>> @@ -113,7 +113,8 @@ private:
>> /// the complete parsing of the current declaration.
>> class DelayedDiagnostic {
>> public:
>> - enum DDKind { Deprecation, Unavailable, Access, ForbiddenType };
>> + enum DDKind { Deprecation, Unavailable, Access, ForbiddenType,
>> + NotYetIntroduced };
>
> Why do we need "NotYetIntroduced"? We don't need a new DDKind
> for obsoleted API, so I don't think we need one here... and I
> think that will simplify the change quite a bit.
I agree that Obsolete, Unavailable and strictly not-introduced can share the same Diagnostic kind.
Thanks for reviewing!
Manman
>
> This has an effect on the error and note text, but I actually
> think it's a good effect.
>
>> unsigned char Kind; // actually a DDKind
>> bool Triggered;
>> @@ -165,13 +166,15 @@ public:
>> }
>>
>> const NamedDecl *getDeprecationDecl() const {
>> - assert((Kind == Deprecation || Kind == Unavailable) &&
>> + assert((Kind == Deprecation || Kind == Unavailable ||
>> + Kind == NotYetIntroduced) &&
>> "Not a deprecation diagnostic.");
>> return DeprecationData.Decl;
>> }
>>
>> StringRef getDeprecationMessage() const {
>> - assert((Kind == Deprecation || Kind == Unavailable) &&
>> + assert((Kind == Deprecation || Kind == Unavailable ||
>> + Kind == NotYetIntroduced) &&
>> "Not a deprecation diagnostic.");
>> return StringRef(DeprecationData.Message,
>> DeprecationData.MessageLen);
>>
>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>> +++ cfe/trunk/include/clang/Sema/Sema.h Wed Feb 17 16:05:48 2016
>> @@ -2108,6 +2108,7 @@ public:
>> VersionTuple Obsoleted,
>> bool IsUnavailable,
>> StringRef Message,
>> + bool IsNopartial,
>> AvailabilityMergeKind AMK,
>> unsigned AttrSpellingListIndex);
>> TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
>> @@ -3535,7 +3536,8 @@ public:
>>
>> void redelayDiagnostics(sema::DelayedDiagnosticPool &pool);
>>
>> - enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable, AD_Partial };
>> + enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable, AD_Partial,
>> + AD_NotYetIntroduced };
>>
>> void EmitAvailabilityWarning(AvailabilityDiagnostic AD,
>> NamedDecl *D, StringRef Message,
>>
>> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
>> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Feb 17 16:05:48 2016
>> @@ -833,11 +833,14 @@ VersionTuple Parser::ParseVersionTuple(S
>> /// \brief Parse the contents of the "availability" attribute.
>> ///
>> /// availability-attribute:
>> -/// 'availability' '(' platform ',' version-arg-list, opt-message')'
>> +/// 'availability' '(' platform ',' opt-nopartial version-arg-list, opt-message')'
>> ///
>> /// platform:
>> /// identifier
>> ///
>> +/// opt-nopartial:
>> +/// 'nopartial' ','
>> +///
>> /// version-arg-list:
>> /// version-arg
>> /// version-arg ',' version-arg-list
>> @@ -867,7 +870,7 @@ void Parser::ParseAvailabilityAttribute(
>> return;
>> }
>>
>> - // Parse the platform name,
>> + // Parse the platform name.
>> if (Tok.isNot(tok::identifier)) {
>> Diag(Tok, diag::err_availability_expected_platform);
>> SkipUntil(tok::r_paren, StopAtSemi);
>> @@ -889,10 +892,12 @@ void Parser::ParseAvailabilityAttribute(
>> Ident_obsoleted = PP.getIdentifierInfo("obsoleted");
>> Ident_unavailable = PP.getIdentifierInfo("unavailable");
>> Ident_message = PP.getIdentifierInfo("message");
>> + Ident_nopartial = PP.getIdentifierInfo("nopartial");
>> }
>>
>> - // Parse the set of introductions/deprecations/removals.
>> - SourceLocation UnavailableLoc;
>> + // Parse the optional "nopartial" and the set of
>> + // introductions/deprecations/removals.
>> + SourceLocation UnavailableLoc, NopartialLoc;
>> do {
>> if (Tok.isNot(tok::identifier)) {
>> Diag(Tok, diag::err_availability_expected_change);
>> @@ -902,6 +907,15 @@ void Parser::ParseAvailabilityAttribute(
>> IdentifierInfo *Keyword = Tok.getIdentifierInfo();
>> SourceLocation KeywordLoc = ConsumeToken();
>>
>> + if (Keyword == Ident_nopartial) {
>> + if (NopartialLoc.isValid()) {
>> + Diag(KeywordLoc, diag::err_availability_redundant)
>> + << Keyword << SourceRange(NopartialLoc);
>> + }
>> + NopartialLoc = KeywordLoc;
>> + continue;
>> + }
>> +
>> if (Keyword == Ident_unavailable) {
>> if (UnavailableLoc.isValid()) {
>> Diag(KeywordLoc, diag::err_availability_redundant)
>> @@ -1023,7 +1037,7 @@ void Parser::ParseAvailabilityAttribute(
>> Changes[Deprecated],
>> Changes[Obsoleted],
>> UnavailableLoc, MessageExpr.get(),
>> - Syntax);
>> + Syntax, NopartialLoc);
>> }
>>
>> /// \brief Parse the contents of the "objc_bridge_related" attribute.
>>
>> Modified: cfe/trunk/lib/Parse/Parser.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Parse/Parser.cpp (original)
>> +++ cfe/trunk/lib/Parse/Parser.cpp Wed Feb 17 16:05:48 2016
>> @@ -491,6 +491,7 @@ void Parser::Initialize() {
>> Ident_deprecated = nullptr;
>> Ident_obsoleted = nullptr;
>> Ident_unavailable = nullptr;
>> + Ident_nopartial = nullptr;
>>
>> Ident__except = nullptr;
>>
>>
>> Modified: cfe/trunk/lib/Sema/DelayedDiagnostic.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DelayedDiagnostic.cpp?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/DelayedDiagnostic.cpp (original)
>> +++ cfe/trunk/lib/Sema/DelayedDiagnostic.cpp Wed Feb 17 16:05:48 2016
>> @@ -35,6 +35,9 @@ DelayedDiagnostic::makeAvailability(Sema
>> 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");
>> }
>> @@ -63,6 +66,7 @@ void DelayedDiagnostic::Destroy() {
>>
>> case Deprecation:
>> case Unavailable:
>> + case NotYetIntroduced:
>> delete [] DeprecationData.Message;
>> break;
>>
>>
>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Feb 17 16:05:48 2016
>> @@ -2196,7 +2196,7 @@ static bool mergeDeclAttribute(Sema &S,
>> NewAttr = S.mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(),
>> AA->getIntroduced(), AA->getDeprecated(),
>> AA->getObsoleted(), AA->getUnavailable(),
>> - AA->getMessage(), AMK,
>> + AA->getMessage(), AA->getNopartial(), AMK,
>> AttrSpellingListIndex);
>> else if (const auto *VA = dyn_cast<VisibilityAttr>(Attr))
>> NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(),
>>
>> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Feb 17 16:05:48 2016
>> @@ -1916,6 +1916,7 @@ AvailabilityAttr *Sema::mergeAvailabilit
>> VersionTuple Obsoleted,
>> bool IsUnavailable,
>> StringRef Message,
>> + bool IsNopartial,
>> AvailabilityMergeKind AMK,
>> unsigned AttrSpellingListIndex) {
>> VersionTuple MergedIntroduced = Introduced;
>> @@ -2062,7 +2063,7 @@ AvailabilityAttr *Sema::mergeAvailabilit
>> return ::new (Context) AvailabilityAttr(Range, Context, Platform,
>> Introduced, Deprecated,
>> Obsoleted, IsUnavailable, Message,
>> - AttrSpellingListIndex);
>> + IsNopartial, AttrSpellingListIndex);
>> }
>> return nullptr;
>> }
>> @@ -2089,6 +2090,7 @@ static void handleAvailabilityAttr(Sema
>> AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
>> AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
>> bool IsUnavailable = Attr.getUnavailableLoc().isValid();
>> + bool IsNopartial = Attr.getNopartialLoc().isValid();
>> StringRef Str;
>> if (const StringLiteral *SE =
>> dyn_cast_or_null<StringLiteral>(Attr.getMessageExpr()))
>> @@ -2099,6 +2101,7 @@ static void handleAvailabilityAttr(Sema
>> Deprecated.Version,
>> Obsoleted.Version,
>> IsUnavailable, Str,
>> + IsNopartial,
>> Sema::AMK_None,
>> Index);
>> if (NewAttr)
>> @@ -2143,6 +2146,7 @@ static void handleAvailabilityAttr(Sema
>> NewDeprecated,
>> NewObsoleted,
>> IsUnavailable, Str,
>> + IsNopartial,
>> Sema::AMK_None,
>> Index);
>> if (NewAttr)
>> @@ -2165,6 +2169,7 @@ static void handleAvailabilityAttr(Sema
>> Deprecated.Version,
>> Obsoleted.Version,
>> IsUnavailable, Str,
>> + IsNopartial,
>> Sema::AMK_None,
>> Index);
>> if (NewAttr)
>> @@ -5957,6 +5962,14 @@ static void DoEmitAvailabilityWarning(Se
>> 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()) {
>> @@ -5983,10 +5996,22 @@ static void DoEmitAvailabilityWarning(Se
>> static void handleDelayedAvailabilityCheck(Sema &S, DelayedDiagnostic &DD,
>> Decl *Ctx) {
>> assert(DD.Kind == DelayedDiagnostic::Deprecation ||
>> - DD.Kind == DelayedDiagnostic::Unavailable);
>> - Sema::AvailabilityDiagnostic AD = DD.Kind == DelayedDiagnostic::Deprecation
>> - ? Sema::AD_Deprecation
>> - : Sema::AD_Unavailable;
>> + 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.Triggered = true;
>> DoEmitAvailabilityWarning(
>> S, AD, Ctx, DD.getDeprecationDecl(), DD.getDeprecationMessage(), DD.Loc,
>>
>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Feb 17 16:05:48 2016
>> @@ -137,7 +137,7 @@ DiagnoseAvailabilityOfDecl(Sema &S, Name
>>
>> const ObjCPropertyDecl *ObjCPDecl = nullptr;
>> if (Result == AR_Deprecated || Result == AR_Unavailable ||
>> - AR_NotYetIntroduced) {
>> + Result == AR_NotYetIntroduced) {
>> if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
>> if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) {
>> AvailabilityResult PDeclResult = PD->getAvailability(nullptr);
>> @@ -159,11 +159,20 @@ DiagnoseAvailabilityOfDecl(Sema &S, Name
>> break;
>>
>> case AR_NotYetIntroduced: {
>> + // With nopartial, the compiler will emit delayed error just like how
>> + // "deprecated, unavailable" are handled.
>> + AvailabilityAttr *AA = D->getAttr<AvailabilityAttr>();
>> + if (AA && AA->getNopartial() &&
>> + S.getCurContextAvailability() != AR_NotYetIntroduced)
>> + S.EmitAvailabilityWarning(Sema::AD_NotYetIntroduced,
>> + D, Message, Loc, UnknownObjCClass, ObjCPDecl,
>> + ObjCPropertyAccess);
>> +
>> // Don't do this for enums, they can't be redeclared.
>> if (isa<EnumConstantDecl>(D) || isa<EnumDecl>(D))
>> break;
>>
>> - bool Warn = !D->getAttr<AvailabilityAttr>()->isInherited();
>> + bool Warn = !AA->isInherited();
>> // Objective-C method declarations in categories are not modelled as
>> // redeclarations, so manually look for a redeclaration in a category
>> // if necessary.
>>
>> Modified: cfe/trunk/test/Sema/attr-availability-macosx.c
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-availability-macosx.c?rev=261163&r1=261162&r2=261163&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/Sema/attr-availability-macosx.c (original)
>> +++ cfe/trunk/test/Sema/attr-availability-macosx.c Wed Feb 17 16:05:48 2016
>> @@ -6,6 +6,7 @@ void f2(int) __attribute__((availability
>> 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}}
>
>
> In the context of this note, I think "nopartial" isn't self-explanatory
> with the error/note text (sadly I came up with it). I think "strict"
> is better.
>
> Also, for consistency with obsoleted API, I think this should be
> "marked unavailable here" ("marked not-yet-introduced here" is awkward).
>
>> void test() {
>> f0(0);
>> @@ -14,6 +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}}
>
> This error makes more sense to me:
> ```
> expected-error{{'f6' is unavailable: not introduced until OS X 10.6}
> ```
>
> In combination with the note, we get something like:
> ```
> ...: error: 'f6' is unavailable: not introduced until OS X 10.6
> f6(0);
> ^
> ...: note: 'f6' has been explicitly marked unavailable here
> void f6(int) __attribute__((availability(macosx,strict,introduced=10.6)));
> ^
> ```
> This is more consistent with the other reasons API might be
> unavailable, and I think the language is more clear.
>
>> }
>>
>> // rdar://10535640 <rdar://10535640>
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160218/bd9de9d6/attachment-0001.html>
More information about the cfe-commits
mailing list