diff options
author | Manman Ren <manman.ren@gmail.com> | 2016-03-17 03:09:55 +0000 |
---|---|---|
committer | Manman Ren <manman.ren@gmail.com> | 2016-03-17 03:09:55 +0000 |
commit | a7c4760c8efa0e7ad3564bb1a0966bf8940463cf (patch) | |
tree | d404671d0d800ddb0aea795b9c87a16cd3e7f5b0 /clang/lib | |
parent | b76c02771786ecb235ed6da6dda845e2a06330be (diff) | |
download | llvm-a7c4760c8efa0e7ad3564bb1a0966bf8940463cf.zip llvm-a7c4760c8efa0e7ad3564bb1a0966bf8940463cf.tar.gz llvm-a7c4760c8efa0e7ad3564bb1a0966bf8940463cf.tar.bz2 |
Add an optional named argument (replacement = "xxx") to AvailabilityAttr.
This commit adds a named argument to AvailabilityAttr, while r263652 adds an
optional string argument to __attribute__((deprecated)). This enables the
compiler to provide Fix-Its for deprecated declarations.
rdar://20588929
llvm-svn: 263687
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 24 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 14 |
5 files changed, 33 insertions, 10 deletions
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 36255a8..50ce271 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1074,6 +1074,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { .Case("attribute_availability_tvos", true) .Case("attribute_availability_watchos", true) .Case("attribute_availability_with_strict", true) + .Case("attribute_availability_with_replacement", true) .Case("attribute_availability_in_templates", true) .Case("attribute_cf_returns_not_retained", true) .Case("attribute_cf_returns_retained", true) diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 52f3f9f..fef5d8d 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -833,7 +833,8 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) { /// \brief Parse the contents of the "availability" attribute. /// /// availability-attribute: -/// 'availability' '(' platform ',' opt-strict version-arg-list, opt-message')' +/// 'availability' '(' platform ',' opt-strict version-arg-list, +/// opt-replacement, opt-message')' /// /// platform: /// identifier @@ -850,6 +851,8 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) { /// 'deprecated' '=' version /// 'obsoleted' = version /// 'unavailable' +/// opt-replacement: +/// 'replacement' '=' <string> /// opt-message: /// 'message' '=' <string> void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, @@ -861,7 +864,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, AttributeList::Syntax Syntax) { enum { Introduced, Deprecated, Obsoleted, Unknown }; AvailabilityChange Changes[Unknown]; - ExprResult MessageExpr; + ExprResult MessageExpr, ReplacementExpr; // Opening '('. BalancedDelimiterTracker T(*this, tok::l_paren); @@ -893,9 +896,10 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, Ident_unavailable = PP.getIdentifierInfo("unavailable"); Ident_message = PP.getIdentifierInfo("message"); Ident_strict = PP.getIdentifierInfo("strict"); + Ident_replacement = PP.getIdentifierInfo("replacement"); } - // Parse the optional "strict" and the set of + // Parse the optional "strict", the optional "replacement" and the set of // introductions/deprecations/removals. SourceLocation UnavailableLoc, StrictLoc; do { @@ -931,14 +935,17 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, return; } ConsumeToken(); - if (Keyword == Ident_message) { + if (Keyword == Ident_message || Keyword == Ident_replacement) { if (Tok.isNot(tok::string_literal)) { Diag(Tok, diag::err_expected_string_literal) << /*Source='availability attribute'*/2; SkipUntil(tok::r_paren, StopAtSemi); return; } - MessageExpr = ParseStringLiteralExpression(); + if (Keyword == Ident_message) + MessageExpr = ParseStringLiteralExpression(); + else + ReplacementExpr = ParseStringLiteralExpression(); // Also reject wide string literals. if (StringLiteral *MessageStringLiteral = cast_or_null<StringLiteral>(MessageExpr.get())) { @@ -950,7 +957,10 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, return; } } - break; + if (Keyword == Ident_message) + break; + else + continue; } // Special handling of 'NA' only when applied to introduced or @@ -1037,7 +1047,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, Changes[Deprecated], Changes[Obsoleted], UnavailableLoc, MessageExpr.get(), - Syntax, StrictLoc); + Syntax, StrictLoc, ReplacementExpr.get()); } /// \brief Parse the contents of the "objc_bridge_related" attribute. diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 9ef57cb..07f60cb 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -492,6 +492,7 @@ void Parser::Initialize() { Ident_obsoleted = nullptr; Ident_unavailable = nullptr; Ident_strict = nullptr; + Ident_replacement = nullptr; Ident__except = nullptr; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index d8740d2..2f50b70 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2196,7 +2196,8 @@ 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->getStrict(), AMK, + AA->getMessage(), AA->getStrict(), + AA->getReplacement(), AMK, AttrSpellingListIndex); else if (const auto *VA = dyn_cast<VisibilityAttr>(Attr)) NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 18065cb..c90d623 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1941,6 +1941,7 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, bool IsUnavailable, StringRef Message, bool IsStrict, + StringRef Replacement, AvailabilityMergeKind AMK, unsigned AttrSpellingListIndex) { VersionTuple MergedIntroduced = Introduced; @@ -2087,7 +2088,8 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, return ::new (Context) AvailabilityAttr(Range, Context, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable, Message, - IsStrict, AttrSpellingListIndex); + IsStrict, Replacement, + AttrSpellingListIndex); } return nullptr; } @@ -2119,13 +2121,17 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, if (const StringLiteral *SE = dyn_cast_or_null<StringLiteral>(Attr.getMessageExpr())) Str = SE->getString(); + StringRef Replacement; + if (const StringLiteral *SE = + dyn_cast_or_null<StringLiteral>(Attr.getReplacementExpr())) + Replacement = SE->getString(); AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), II, Introduced.Version, Deprecated.Version, Obsoleted.Version, IsUnavailable, Str, - IsStrict, + IsStrict, Replacement, Sema::AMK_None, Index); if (NewAttr) @@ -2171,6 +2177,7 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, NewObsoleted, IsUnavailable, Str, IsStrict, + Replacement, Sema::AMK_None, Index); if (NewAttr) @@ -2194,6 +2201,7 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, Obsoleted.Version, IsUnavailable, Str, IsStrict, + Replacement, Sema::AMK_None, Index); if (NewAttr) @@ -6229,6 +6237,8 @@ static void DoEmitAvailabilityWarning(Sema &S, Sema::AvailabilityDiagnostic K, if (K == Sema::AD_Deprecation) { if (auto attr = D->getAttr<DeprecatedAttr>()) Replacement = attr->getReplacement(); + if (auto attr = D->getAttr<AvailabilityAttr>()) + Replacement = attr->getReplacement(); if (!Replacement.empty()) UseRange = |