aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorManman Ren <manman.ren@gmail.com>2016-03-17 03:09:55 +0000
committerManman Ren <manman.ren@gmail.com>2016-03-17 03:09:55 +0000
commita7c4760c8efa0e7ad3564bb1a0966bf8940463cf (patch)
treed404671d0d800ddb0aea795b9c87a16cd3e7f5b0 /clang/lib
parentb76c02771786ecb235ed6da6dda845e2a06330be (diff)
downloadllvm-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.cpp1
-rw-r--r--clang/lib/Parse/ParseDecl.cpp24
-rw-r--r--clang/lib/Parse/Parser.cpp1
-rw-r--r--clang/lib/Sema/SemaDecl.cpp3
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp14
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 =