diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2011-12-10 00:28:41 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2011-12-10 00:28:41 +0000 |
commit | 006e42f0c8b65b783d565ef10b938a9e82fc02e3 (patch) | |
tree | f541c4d72facab26b9a3ca324fa9566e46310453 /lib | |
parent | d937c21f53587e6481589553ab4f7b557ebb6337 (diff) |
Add ability to supply additional message to availability macros,
// rdar://10095131
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146304 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/DeclBase.cpp | 17 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 9 |
3 files changed, 37 insertions, 9 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 37e0892c5c..b7941506b0 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -282,13 +282,20 @@ static AvailabilityResult CheckAvailability(ASTContext &Context, // Match the platform name. if (A->getPlatform()->getName() != TargetPlatform) return AR_Available; - + + std::string HintMessage; + if (!A->getMessage().empty()) { + HintMessage = " - "; + HintMessage += A->getMessage(); + } + // Make sure that this declaration has not been marked 'unavailable'. if (A->getUnavailable()) { if (Message) { Message->clear(); llvm::raw_string_ostream Out(*Message); - Out << "not available on " << PrettyPlatformName; + Out << "not available on " << PrettyPlatformName + << HintMessage; } return AR_Unavailable; @@ -301,7 +308,7 @@ static AvailabilityResult CheckAvailability(ASTContext &Context, Message->clear(); llvm::raw_string_ostream Out(*Message); Out << "introduced in " << PrettyPlatformName << ' ' - << A->getIntroduced(); + << A->getIntroduced() << HintMessage; } return AR_NotYetIntroduced; @@ -313,7 +320,7 @@ static AvailabilityResult CheckAvailability(ASTContext &Context, Message->clear(); llvm::raw_string_ostream Out(*Message); Out << "obsoleted in " << PrettyPlatformName << ' ' - << A->getObsoleted(); + << A->getObsoleted() << HintMessage; } return AR_Unavailable; @@ -325,7 +332,7 @@ static AvailabilityResult CheckAvailability(ASTContext &Context, Message->clear(); llvm::raw_string_ostream Out(*Message); Out << "first deprecated in " << PrettyPlatformName << ' ' - << A->getDeprecated(); + << A->getDeprecated() << HintMessage; } return AR_Deprecated; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 61048f54e4..ff3084d0cb 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -522,7 +522,7 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) { /// \brief Parse the contents of the "availability" attribute. /// /// availability-attribute: -/// 'availability' '(' platform ',' version-arg-list ')' +/// 'availability' '(' platform ',' version-arg-list, opt-message')' /// /// platform: /// identifier @@ -536,6 +536,8 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) { /// 'deprecated' '=' version /// 'removed' = version /// 'unavailable' +/// opt-message: +/// 'message' '=' <string> void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, SourceLocation AvailabilityLoc, ParsedAttributes &attrs, @@ -545,6 +547,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, enum { Introduced, Deprecated, Obsoleted, Unknown }; AvailabilityChange Changes[Unknown]; + ExprResult MessageExpr; // Opening '('. BalancedDelimiterTracker T(*this, tok::l_paren); @@ -573,6 +576,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, Ident_deprecated = PP.getIdentifierInfo("deprecated"); Ident_obsoleted = PP.getIdentifierInfo("obsoleted"); Ident_unavailable = PP.getIdentifierInfo("unavailable"); + Ident_message = PP.getIdentifierInfo("message"); } // Parse the set of introductions/deprecations/removals. @@ -599,7 +603,7 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, ConsumeToken(); continue; } - + if (Tok.isNot(tok::equal)) { Diag(Tok, diag::err_expected_equal_after) << Keyword; @@ -607,6 +611,15 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, return; } ConsumeToken(); + if (Keyword == Ident_message) { + if (!isTokenStringLiteral()) { + Diag(Tok, diag::err_expected_string_literal); + SkipUntil(tok::r_paren); + return; + } + MessageExpr = ParseStringLiteralExpression(); + break; + } SourceRange VersionRange; VersionTuple Version = ParseVersionTuple(VersionRange); @@ -682,7 +695,8 @@ void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability, Changes[Introduced], Changes[Deprecated], Changes[Obsoleted], - UnavailableLoc, false, false); + UnavailableLoc, MessageExpr.take(), + false, false); } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index e60cd63369..63714fdfa7 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -1624,12 +1624,19 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, return; } + StringRef Str; + const StringLiteral *SE = + dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr()); + if (SE) + Str = SE->getString(); + D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context, Platform, Introduced.Version, Deprecated.Version, Obsoleted.Version, - IsUnavailable)); + IsUnavailable, + Str)); } static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { |