r263687 - Add an optional named argument (replacement = "xxx") to AvailabilityAttr.
Manman Ren via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 16 20:09:55 PDT 2016
Author: mren
Date: Wed Mar 16 22:09:55 2016
New Revision: 263687
URL: http://llvm.org/viewvc/llvm-project?rev=263687&view=rev
Log:
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
Modified:
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Basic/AttrDocs.td
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/AttributeList.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Lex/PPMacroExpansion.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/test/SemaCXX/attr-deprecated-replacement-fixit.cpp
Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=263687&r1=263686&r2=263687&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Mar 16 22:09:55 2016
@@ -467,7 +467,7 @@ def Availability : InheritableAttr {
let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">,
VersionArgument<"deprecated">, VersionArgument<"obsoleted">,
BoolArgument<"unavailable">, StringArgument<"message">,
- BoolArgument<"strict">];
+ BoolArgument<"strict">, StringArgument<"replacement">];
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=263687&r1=263686&r2=263687&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Wed Mar 16 22:09:55 2016
@@ -661,6 +661,11 @@ message=\ *string-literal*
error about use of a deprecated or obsoleted declaration. Useful to direct
users to replacement APIs.
+replacement=\ *string-literal*
+ Additional message text that Clang will use to provide Fix-It when emitting
+ a warning about use of a deprecated declaration. The Fix-It will replace
+ the deprecated declaration with the new declaration specified.
+
Multiple availability attributes can be placed on a declaration, which may
correspond to different platforms. Only the availability attribute with the
platform corresponding to the target platform will be used; any others will be
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=263687&r1=263686&r2=263687&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Mar 16 22:09:55 2016
@@ -137,6 +137,9 @@ class Parser : public CodeCompletionHand
/// \brief Identifier for "strict".
IdentifierInfo *Ident_strict;
+ /// \brief Identifier for "replacement".
+ IdentifierInfo *Ident_replacement;
+
/// 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=263687&r1=263686&r2=263687&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)
+++ cfe/trunk/include/clang/Sema/AttributeList.h Wed Mar 16 22:09:55 2016
@@ -174,6 +174,14 @@ private:
&getAvailabilitySlot(ObsoletedSlot) + 1);
}
+ const Expr **getReplacementSlot() {
+ return reinterpret_cast<const Expr**>(getStrictSlot() + 1);
+ }
+
+ const Expr *const *getReplacementSlot() const {
+ return reinterpret_cast<const Expr *const *>(getStrictSlot() + 1);
+ }
+
public:
struct TypeTagForDatatypeData {
ParsedType *MatchingCType;
@@ -251,7 +259,8 @@ private:
const AvailabilityChange &obsoleted,
SourceLocation unavailable,
const Expr *messageExpr,
- Syntax syntaxUsed, SourceLocation strict)
+ Syntax syntaxUsed, SourceLocation strict,
+ const Expr *replacementExpr)
: AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
@@ -264,6 +273,7 @@ private:
new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
memcpy(getStrictSlot(), &strict, sizeof(SourceLocation));
+ *getReplacementSlot() = replacementExpr;
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
@@ -456,6 +466,11 @@ public:
return MessageExpr;
}
+ const Expr *getReplacementExpr() const {
+ assert(getKind() == AT_Availability && "Not an availability attribute");
+ return *getReplacementSlot();
+ }
+
const ParsedType &getMatchingCType() const {
assert(getKind() == AT_TypeTagForDatatype &&
"Not a type_tag_for_datatype attribute");
@@ -523,7 +538,7 @@ public:
AvailabilityAllocSize =
sizeof(AttributeList)
+ ((3 * sizeof(AvailabilityChange) + sizeof(void*) +
- sizeof(ArgsUnion) + sizeof(SourceLocation) - 1)
+ sizeof(ArgsUnion) + sizeof(SourceLocation) + sizeof(const Expr *) - 1)
/ sizeof(void*) * sizeof(void*)),
TypeTagForDatatypeAllocSize =
sizeof(AttributeList)
@@ -642,13 +657,13 @@ public:
SourceLocation unavailable,
const Expr *MessageExpr,
AttributeList::Syntax syntax,
- SourceLocation strict) {
+ SourceLocation strict, const Expr *ReplacementExpr) {
void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
return add(new (memory) AttributeList(attrName, attrRange,
scopeName, scopeLoc,
Param, introduced, deprecated,
obsoleted, unavailable, MessageExpr,
- syntax, strict));
+ syntax, strict, ReplacementExpr));
}
AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
@@ -778,11 +793,11 @@ public:
SourceLocation unavailable,
const Expr *MessageExpr,
AttributeList::Syntax syntax,
- SourceLocation strict) {
+ SourceLocation strict, const Expr *ReplacementExpr) {
AttributeList *attr =
pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
deprecated, obsoleted, unavailable, MessageExpr, syntax,
- strict);
+ strict, ReplacementExpr);
add(attr);
return attr;
}
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=263687&r1=263686&r2=263687&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Mar 16 22:09:55 2016
@@ -2110,7 +2110,7 @@ public:
VersionTuple Obsoleted,
bool IsUnavailable,
StringRef Message,
- bool IsStrict,
+ bool IsStrict, StringRef Replacement,
AvailabilityMergeKind AMK,
unsigned AttrSpellingListIndex);
TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=263687&r1=263686&r2=263687&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Wed Mar 16 22:09:55 2016
@@ -1074,6 +1074,7 @@ static bool HasFeature(const Preprocesso
.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)
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=263687&r1=263686&r2=263687&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Mar 16 22:09:55 2016
@@ -833,7 +833,8 @@ VersionTuple Parser::ParseVersionTuple(S
/// \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(S
/// '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(
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(
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(
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(
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(
Changes[Deprecated],
Changes[Obsoleted],
UnavailableLoc, MessageExpr.get(),
- Syntax, StrictLoc);
+ Syntax, StrictLoc, ReplacementExpr.get());
}
/// \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=263687&r1=263686&r2=263687&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Wed Mar 16 22:09:55 2016
@@ -492,6 +492,7 @@ void Parser::Initialize() {
Ident_obsoleted = nullptr;
Ident_unavailable = nullptr;
Ident_strict = nullptr;
+ Ident_replacement = nullptr;
Ident__except = nullptr;
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=263687&r1=263686&r2=263687&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Mar 16 22:09:55 2016
@@ -2196,7 +2196,8 @@ static bool mergeDeclAttribute(Sema &S,
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(),
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=263687&r1=263686&r2=263687&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Mar 16 22:09:55 2016
@@ -1941,6 +1941,7 @@ AvailabilityAttr *Sema::mergeAvailabilit
bool IsUnavailable,
StringRef Message,
bool IsStrict,
+ StringRef Replacement,
AvailabilityMergeKind AMK,
unsigned AttrSpellingListIndex) {
VersionTuple MergedIntroduced = Introduced;
@@ -2087,7 +2088,8 @@ AvailabilityAttr *Sema::mergeAvailabilit
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
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
NewObsoleted,
IsUnavailable, Str,
IsStrict,
+ Replacement,
Sema::AMK_None,
Index);
if (NewAttr)
@@ -2194,6 +2201,7 @@ static void handleAvailabilityAttr(Sema
Obsoleted.Version,
IsUnavailable, Str,
IsStrict,
+ Replacement,
Sema::AMK_None,
Index);
if (NewAttr)
@@ -6229,6 +6237,8 @@ static void DoEmitAvailabilityWarning(Se
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 =
Modified: cfe/trunk/test/SemaCXX/attr-deprecated-replacement-fixit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-deprecated-replacement-fixit.cpp?rev=263687&r1=263686&r2=263687&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-deprecated-replacement-fixit.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-deprecated-replacement-fixit.cpp Wed Mar 16 22:09:55 2016
@@ -8,9 +8,17 @@
#error "Missing __has_feature"
#endif
+#if !__has_feature(attribute_availability_with_replacement)
+#error "Missing __has_feature"
+#endif
+
void f_8(int) __attribute__((deprecated("message", "new8"))); // expected-note {{'f_8' has been explicitly marked deprecated here}}
void new8(int);
+void f_2(int) __attribute__((availability(macosx,deprecated=9.0,replacement="new2"))); // expected-note {{'f_2' has been explicitly marked deprecated here}}
+void new2(int);
void test() {
f_8(0); // expected-warning{{'f_8' is deprecated}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:6}:"new8"
+ f_2(0); // expected-warning{{'f_2' is deprecated: first deprecated in OS X 9.0}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:6}:"new2"
}
More information about the cfe-commits
mailing list