diff options
author | Manman Ren <manman.ren@gmail.com> | 2016-02-17 22:05:48 +0000 |
---|---|---|
committer | Manman Ren <manman.ren@gmail.com> | 2016-02-17 22:05:48 +0000 |
commit | b636b904c229f02d574a27b3f6f2a41c39a1d541 (patch) | |
tree | 146892ac295d3d9d8b8809e2c23253d3452e25d7 /clang/lib/Parse/ParseDecl.cpp | |
parent | 4083e038e918ccc1a5800f424c3e814bdd425e79 (diff) | |
download | bcm5719-llvm-b636b904c229f02d574a27b3f6f2a41c39a1d541.tar.gz bcm5719-llvm-b636b904c229f02d574a27b3f6f2a41c39a1d541.zip |
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
llvm-svn: 261163
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 900c33b7911..c766ef30e62 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -833,11 +833,14 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) { /// \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(IdentifierInfo &Availability, 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(IdentifierInfo &Availability, 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 &Availability, 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(IdentifierInfo &Availability, Changes[Deprecated], Changes[Obsoleted], UnavailableLoc, MessageExpr.get(), - Syntax); + Syntax, NopartialLoc); } /// \brief Parse the contents of the "objc_bridge_related" attribute. |