diff options
author | Alex Lorenz <arphaman@gmail.com> | 2017-04-18 10:46:41 +0000 |
---|---|---|
committer | Alex Lorenz <arphaman@gmail.com> | 2017-04-18 10:46:41 +0000 |
commit | 3bfe962afa502d7b12c286d6975f7d97f05ad3c3 (patch) | |
tree | fe80c43d28c2d616764df8e0d65b52fe158aa205 /clang/lib/Parse/ParsePragma.cpp | |
parent | 787fbd7addd617df47ecb39601a63e061fea2657 (diff) | |
download | bcm5719-llvm-3bfe962afa502d7b12c286d6975f7d97f05ad3c3.tar.gz bcm5719-llvm-3bfe962afa502d7b12c286d6975f7d97f05ad3c3.zip |
Revert r300539 - Add #pragma clang attribute
Some tests fail on the Windows buildbots. I will have to investigate more.
This commit reverts r300539, r300540 and r300542.
llvm-svn: 300543
Diffstat (limited to 'clang/lib/Parse/ParsePragma.cpp')
-rw-r--r-- | clang/lib/Parse/ParsePragma.cpp | 535 |
1 files changed, 0 insertions, 535 deletions
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index abddb6ba670..c8de6b35f9e 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -183,17 +183,6 @@ private: Sema &Actions; }; -/// PragmaAttributeHandler - "\#pragma clang attribute ...". -struct PragmaAttributeHandler : public PragmaHandler { - PragmaAttributeHandler(AttributeFactory &AttrFactory) - : PragmaHandler("attribute"), AttributesForPragmaAttribute(AttrFactory) {} - void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, - Token &FirstToken) override; - - /// A pool of attributes that were parsed in \#pragma clang attribute. - ParsedAttributes AttributesForPragmaAttribute; -}; - } // end namespace void Parser::initializePragmaHandlers() { @@ -286,9 +275,6 @@ void Parser::initializePragmaHandlers() { FPHandler.reset(new PragmaFPHandler()); PP.AddPragmaHandler("clang", FPHandler.get()); - - AttributePragmaHandler.reset(new PragmaAttributeHandler(AttrFactory)); - PP.AddPragmaHandler("clang", AttributePragmaHandler.get()); } void Parser::resetPragmaHandlers() { @@ -370,9 +356,6 @@ void Parser::resetPragmaHandlers() { PP.RemovePragmaHandler("clang", FPHandler.get()); FPHandler.reset(); - - PP.RemovePragmaHandler("clang", AttributePragmaHandler.get()); - AttributePragmaHandler.reset(); } /// \brief Handle the annotation token produced for #pragma unused(...) @@ -983,423 +966,6 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) { return true; } -namespace { -struct PragmaAttributeInfo { - enum ActionType { Push, Pop }; - ParsedAttributes &Attributes; - ActionType Action; - ArrayRef<Token> Tokens; - - PragmaAttributeInfo(ParsedAttributes &Attributes) : Attributes(Attributes) {} -}; - -#include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc" - -} // end anonymous namespace - -static StringRef getIdentifier(const Token &Tok) { - if (Tok.is(tok::identifier)) - return Tok.getIdentifierInfo()->getName(); - const char *S = tok::getKeywordSpelling(Tok.getKind()); - if (!S) - return ""; - return S; -} - -static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule) { - using namespace attr; - switch (Rule) { -#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \ - case Value: \ - return IsAbstract; -#include "clang/Basic/AttrSubMatchRulesList.inc" - } - llvm_unreachable("Invalid attribute subject match rule"); - return false; -} - -static void diagnoseExpectedAttributeSubjectSubRule( - Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName, - SourceLocation SubRuleLoc) { - auto Diagnostic = - PRef.Diag(SubRuleLoc, - diag::err_pragma_attribute_expected_subject_sub_identifier) - << PrimaryRuleName; - if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule)) - Diagnostic << /*SubRulesSupported=*/1 << SubRules; - else - Diagnostic << /*SubRulesSupported=*/0; -} - -static void diagnoseUnknownAttributeSubjectSubRule( - Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName, - StringRef SubRuleName, SourceLocation SubRuleLoc) { - - auto Diagnostic = - PRef.Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule) - << SubRuleName << PrimaryRuleName; - if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule)) - Diagnostic << /*SubRulesSupported=*/1 << SubRules; - else - Diagnostic << /*SubRulesSupported=*/0; -} - -bool Parser::ParsePragmaAttributeSubjectMatchRuleSet( - attr::ParsedSubjectMatchRuleSet &SubjectMatchRules, SourceLocation &AnyLoc, - SourceLocation &LastMatchRuleEndLoc) { - bool IsAny = false; - BalancedDelimiterTracker AnyParens(*this, tok::l_paren); - if (getIdentifier(Tok) == "any") { - AnyLoc = ConsumeToken(); - IsAny = true; - if (AnyParens.expectAndConsume()) - return true; - } - - do { - // Parse the subject matcher rule. - StringRef Name = getIdentifier(Tok); - if (Name.empty()) { - Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier); - return true; - } - std::pair< - Optional<attr::SubjectMatchRule>, - llvm::function_ref<Optional<attr::SubjectMatchRule>(StringRef, bool)>> - Rule = isAttributeSubjectMatchRule(Name); - if (!Rule.first) { - Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name; - return true; - } - attr::SubjectMatchRule PrimaryRule = *Rule.first; - SourceLocation RuleLoc = ConsumeToken(); - - BalancedDelimiterTracker Parens(*this, tok::l_paren); - if (isAbstractAttrMatcherRule(PrimaryRule)) { - if (Parens.expectAndConsume()) - return true; - } else if (Parens.consumeOpen()) { - if (!SubjectMatchRules - .insert( - std::make_pair(PrimaryRule, SourceRange(RuleLoc, RuleLoc))) - .second) - Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject) - << Name - << FixItHint::CreateRemoval(SourceRange( - RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleLoc)); - LastMatchRuleEndLoc = RuleLoc; - continue; - } - - // Parse the sub-rules. - StringRef SubRuleName = getIdentifier(Tok); - if (SubRuleName.empty()) { - diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name, - Tok.getLocation()); - return true; - } - attr::SubjectMatchRule SubRule; - if (SubRuleName == "unless") { - SourceLocation SubRuleLoc = ConsumeToken(); - BalancedDelimiterTracker Parens(*this, tok::l_paren); - if (Parens.expectAndConsume()) - return true; - SubRuleName = getIdentifier(Tok); - if (SubRuleName.empty()) { - diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name, - SubRuleLoc); - return true; - } - auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/true); - if (!SubRuleOrNone) { - std::string SubRuleUnlessName = "unless(" + SubRuleName.str() + ")"; - diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name, - SubRuleUnlessName, SubRuleLoc); - return true; - } - SubRule = *SubRuleOrNone; - ConsumeToken(); - if (Parens.consumeClose()) - return true; - } else { - auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/false); - if (!SubRuleOrNone) { - diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name, - SubRuleName, Tok.getLocation()); - return true; - } - SubRule = *SubRuleOrNone; - ConsumeToken(); - } - SourceLocation RuleEndLoc = Tok.getLocation(); - LastMatchRuleEndLoc = RuleEndLoc; - if (Parens.consumeClose()) - return true; - if (!SubjectMatchRules - .insert(std::make_pair(SubRule, SourceRange(RuleLoc, RuleEndLoc))) - .second) { - Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject) - << attr::getSubjectMatchRuleSpelling(SubRule) - << FixItHint::CreateRemoval(SourceRange( - RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleEndLoc)); - continue; - } - } while (IsAny && TryConsumeToken(tok::comma)); - - if (IsAny) - if (AnyParens.consumeClose()) - return true; - - return false; -} - -namespace { - -/// Describes the stage at which attribute subject rule parsing was interruped. -enum class MissingAttributeSubjectRulesRecoveryPoint { - Comma, - ApplyTo, - Equals, - Any, - None, -}; - -MissingAttributeSubjectRulesRecoveryPoint -getAttributeSubjectRulesRecoveryPointForToken(const Token &Tok) { - if (const auto *II = Tok.getIdentifierInfo()) { - if (II->isStr("apply_to")) - return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo; - if (II->isStr("any")) - return MissingAttributeSubjectRulesRecoveryPoint::Any; - } - if (Tok.is(tok::equal)) - return MissingAttributeSubjectRulesRecoveryPoint::Equals; - return MissingAttributeSubjectRulesRecoveryPoint::None; -} - -/// Creates a diagnostic for the attribute subject rule parsing diagnostic that -/// suggests the possible attribute subject rules in a fix-it together with -/// any other missing tokens. -DiagnosticBuilder createExpectedAttributeSubjectRulesTokenDiagnostic( - unsigned DiagID, AttributeList &Attribute, - MissingAttributeSubjectRulesRecoveryPoint Point, Parser &PRef) { - SourceLocation Loc = PRef.getEndOfPreviousToken(); - if (Loc.isInvalid()) - Loc = PRef.getCurToken().getLocation(); - auto Diagnostic = PRef.Diag(Loc, DiagID); - std::string FixIt; - MissingAttributeSubjectRulesRecoveryPoint EndPoint = - getAttributeSubjectRulesRecoveryPointForToken(PRef.getCurToken()); - if (Point == MissingAttributeSubjectRulesRecoveryPoint::Comma) - FixIt = ", "; - if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo && - EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo) - FixIt += "apply_to"; - if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals && - EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals) - FixIt += " = "; - SourceRange FixItRange(Loc); - if (EndPoint == MissingAttributeSubjectRulesRecoveryPoint::None) { - // Gather the subject match rules that are supported by the attribute. - SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4> SubjectMatchRuleSet; - Attribute.getMatchRules(PRef.getLangOpts(), SubjectMatchRuleSet); - if (SubjectMatchRuleSet.empty()) { - // FIXME: We can emit a "fix-it" with a subject list placeholder when - // placeholders will be supported by the fix-its. - return Diagnostic; - } - FixIt += "any("; - bool NeedsComma = false; - for (const auto &I : SubjectMatchRuleSet) { - // Ensure that the missing rule is reported in the fix-it only when it's - // supported in the current language mode. - if (!I.second) - continue; - if (NeedsComma) - FixIt += ", "; - else - NeedsComma = true; - FixIt += attr::getSubjectMatchRuleSpelling(I.first); - } - FixIt += ")"; - // Check if we need to remove the range - PRef.SkipUntil(tok::eof, Parser::StopBeforeMatch); - FixItRange.setEnd(PRef.getCurToken().getLocation()); - } - if (FixItRange.getBegin() == FixItRange.getEnd()) - Diagnostic << FixItHint::CreateInsertion(FixItRange.getBegin(), FixIt); - else - Diagnostic << FixItHint::CreateReplacement( - CharSourceRange::getCharRange(FixItRange), FixIt); - return Diagnostic; -} - -} // end anonymous namespace - -void Parser::HandlePragmaAttribute() { - assert(Tok.is(tok::annot_pragma_attribute) && - "Expected #pragma attribute annotation token"); - SourceLocation PragmaLoc = Tok.getLocation(); - auto *Info = static_cast<PragmaAttributeInfo *>(Tok.getAnnotationValue()); - if (Info->Action == PragmaAttributeInfo::Pop) { - ConsumeToken(); - Actions.ActOnPragmaAttributePop(PragmaLoc); - return; - } - // Parse the actual attribute with its arguments. - assert(Info->Action == PragmaAttributeInfo::Push && - "Unexpected #pragma attribute command"); - PP.EnterTokenStream(Info->Tokens, /*DisableMacroExpansion=*/false); - ConsumeToken(); - - ParsedAttributes &Attrs = Info->Attributes; - Attrs.clearListOnly(); - - auto SkipToEnd = [this]() { - SkipUntil(tok::eof, StopBeforeMatch); - ConsumeToken(); - }; - - if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) { - // Parse the CXX11 style attribute. - ParseCXX11AttributeSpecifier(Attrs); - } else if (Tok.is(tok::kw___attribute)) { - ConsumeToken(); - if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, - "attribute")) - return SkipToEnd(); - if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) - return SkipToEnd(); - - if (Tok.isNot(tok::identifier)) { - Diag(Tok, diag::err_pragma_attribute_expected_attribute_name); - SkipToEnd(); - return; - } - IdentifierInfo *AttrName = Tok.getIdentifierInfo(); - SourceLocation AttrNameLoc = ConsumeToken(); - - if (Tok.isNot(tok::l_paren)) - Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, - AttributeList::AS_GNU); - else - ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr, - /*ScopeName=*/nullptr, - /*ScopeLoc=*/SourceLocation(), - AttributeList::AS_GNU, - /*Declarator=*/nullptr); - - if (ExpectAndConsume(tok::r_paren)) - return SkipToEnd(); - if (ExpectAndConsume(tok::r_paren)) - return SkipToEnd(); - } else if (Tok.is(tok::kw___declspec)) { - ParseMicrosoftDeclSpecs(Attrs); - } else { - Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax); - if (Tok.getIdentifierInfo()) { - // If we suspect that this is an attribute suggest the use of - // '__attribute__'. - if (AttributeList::getKind(Tok.getIdentifierInfo(), /*ScopeName=*/nullptr, - AttributeList::AS_GNU) != - AttributeList::UnknownAttribute) { - SourceLocation InsertStartLoc = Tok.getLocation(); - ConsumeToken(); - if (Tok.is(tok::l_paren)) { - ConsumeAnyToken(); - SkipUntil(tok::r_paren, StopBeforeMatch); - if (Tok.isNot(tok::r_paren)) - return SkipToEnd(); - } - Diag(Tok, diag::note_pragma_attribute_use_attribute_kw) - << FixItHint::CreateInsertion(InsertStartLoc, "__attribute__((") - << FixItHint::CreateInsertion(Tok.getEndLoc(), "))"); - } - } - SkipToEnd(); - return; - } - - if (!Attrs.getList() || Attrs.getList()->isInvalid()) { - SkipToEnd(); - return; - } - - // Ensure that we don't have more than one attribute. - if (Attrs.getList()->getNext()) { - SourceLocation Loc = Attrs.getList()->getNext()->getLoc(); - Diag(Loc, diag::err_pragma_attribute_multiple_attributes); - SkipToEnd(); - return; - } - - if (!Attrs.getList()->isSupportedByPragmaAttribute()) { - Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute) - << Attrs.getList()->getName(); - SkipToEnd(); - return; - } - AttributeList &Attribute = *Attrs.getList(); - - // Parse the subject-list. - if (!TryConsumeToken(tok::comma)) { - createExpectedAttributeSubjectRulesTokenDiagnostic( - diag::err_expected, Attribute, - MissingAttributeSubjectRulesRecoveryPoint::Comma, *this) - << tok::comma; - SkipToEnd(); - return; - } - - if (Tok.isNot(tok::identifier)) { - createExpectedAttributeSubjectRulesTokenDiagnostic( - diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute, - MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this); - SkipToEnd(); - return; - } - const IdentifierInfo *II = Tok.getIdentifierInfo(); - if (!II->isStr("apply_to")) { - createExpectedAttributeSubjectRulesTokenDiagnostic( - diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute, - MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this); - SkipToEnd(); - return; - } - ConsumeToken(); - - if (!TryConsumeToken(tok::equal)) { - createExpectedAttributeSubjectRulesTokenDiagnostic( - diag::err_expected, Attribute, - MissingAttributeSubjectRulesRecoveryPoint::Equals, *this) - << tok::equal; - SkipToEnd(); - return; - } - - attr::ParsedSubjectMatchRuleSet SubjectMatchRules; - SourceLocation AnyLoc, LastMatchRuleEndLoc; - if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc, - LastMatchRuleEndLoc)) { - SkipToEnd(); - return; - } - - // Tokens following an ill-formed attribute will remain in the token stream - // and must be removed. - if (Tok.isNot(tok::eof)) { - Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute); - SkipToEnd(); - return; - } - - // Consume the eof terminator token. - ConsumeToken(); - - Actions.ActOnPragmaAttributePush(Attribute, PragmaLoc, - std::move(SubjectMatchRules)); -} - // #pragma GCC visibility comes in two variants: // 'push' '(' [visibility] ')' // 'pop' @@ -2829,104 +2395,3 @@ void PragmaForceCUDAHostDeviceHandler::HandlePragma( PP.Diag(FirstTok.getLocation(), diag::warn_pragma_force_cuda_host_device_bad_arg); } - -/// \brief Handle the #pragma clang attribute directive. -/// -/// The syntax is: -/// \code -/// #pragma clang attribute push(attribute, subject-set) -/// #pragma clang attribute pop -/// \endcode -/// -/// The subject-set clause defines the set of declarations which receive the -/// attribute. Its exact syntax is described in the LanguageExtensions document -/// in Clang's documentation. -/// -/// This directive instructs the compiler to begin/finish applying the specified -/// attribute to the set of attribute-specific declarations in the active range -/// of the pragma. -void PragmaAttributeHandler::HandlePragma(Preprocessor &PP, - PragmaIntroducerKind Introducer, - Token &FirstToken) { - Token Tok; - PP.Lex(Tok); - auto *Info = new (PP.getPreprocessorAllocator()) - PragmaAttributeInfo(AttributesForPragmaAttribute); - - // Parse the 'push' or 'pop'. - if (Tok.isNot(tok::identifier)) { - PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_push_pop); - return; - } - const auto *II = Tok.getIdentifierInfo(); - if (II->isStr("push")) - Info->Action = PragmaAttributeInfo::Push; - else if (II->isStr("pop")) - Info->Action = PragmaAttributeInfo::Pop; - else { - PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_invalid_argument) - << PP.getSpelling(Tok); - return; - } - PP.Lex(Tok); - - // Parse the actual attribute. - if (Info->Action == PragmaAttributeInfo::Push) { - if (Tok.isNot(tok::l_paren)) { - PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren; - return; - } - PP.Lex(Tok); - - // Lex the attribute tokens. - SmallVector<Token, 16> AttributeTokens; - int OpenParens = 1; - while (Tok.isNot(tok::eod)) { - if (Tok.is(tok::l_paren)) - OpenParens++; - else if (Tok.is(tok::r_paren)) { - OpenParens--; - if (OpenParens == 0) - break; - } - - AttributeTokens.push_back(Tok); - PP.Lex(Tok); - } - - if (AttributeTokens.empty()) { - PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_attribute); - return; - } - if (Tok.isNot(tok::r_paren)) { - PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren; - return; - } - SourceLocation EndLoc = Tok.getLocation(); - PP.Lex(Tok); - - // Terminate the attribute for parsing. - Token EOFTok; - EOFTok.startToken(); - EOFTok.setKind(tok::eof); - EOFTok.setLocation(EndLoc); - AttributeTokens.push_back(EOFTok); - - Info->Tokens = - llvm::makeArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator()); - } - - if (Tok.isNot(tok::eod)) - PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) - << "clang attribute"; - - // Generate the annotated pragma token. - auto TokenArray = llvm::make_unique<Token[]>(1); - TokenArray[0].startToken(); - TokenArray[0].setKind(tok::annot_pragma_attribute); - TokenArray[0].setLocation(FirstToken.getLocation()); - TokenArray[0].setAnnotationEndLoc(FirstToken.getLocation()); - TokenArray[0].setAnnotationValue(static_cast<void *>(Info)); - PP.EnterTokenStream(std::move(TokenArray), 1, - /*DisableMacroExpansion=*/false); -} |