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