summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/Attributes.cpp11
-rw-r--r--clang/lib/Parse/ParsePragma.cpp535
-rw-r--r--clang/lib/Parse/ParseStmt.cpp4
-rw-r--r--clang/lib/Parse/Parser.cpp4
-rw-r--r--clang/lib/Sema/AttributeList.cpp21
-rw-r--r--clang/lib/Sema/Sema.cpp67
-rw-r--r--clang/lib/Sema/SemaAttr.cpp211
-rw-r--r--clang/lib/Sema/SemaDecl.cpp2
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp3
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp2
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp13
11 files changed, 39 insertions, 834 deletions
diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp
index b7570d03c85..c215366fc39 100644
--- a/clang/lib/Basic/Attributes.cpp
+++ b/clang/lib/Basic/Attributes.cpp
@@ -1,5 +1,4 @@
#include "clang/Basic/Attributes.h"
-#include "clang/Basic/AttrSubjectMatchRules.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/StringSwitch.h"
using namespace clang;
@@ -16,13 +15,3 @@ int clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
return 0;
}
-
-const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {
- switch (Rule) {
-#define ATTR_MATCH_RULE(NAME, SPELLING, IsAbstract) \
- case attr::NAME: \
- return SPELLING;
-#include "clang/Basic/AttrSubMatchRulesList.inc"
- }
- llvm_unreachable("Invalid subject match rule");
-}
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);
-}
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 7d78046d068..eaff9fe8eed 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -382,10 +382,6 @@ Retry:
case tok::annot_pragma_dump:
HandlePragmaDump();
return StmtEmpty();
-
- case tok::annot_pragma_attribute:
- HandlePragmaAttribute();
- return StmtEmpty();
}
// If we reached this code, the statement must end in a semicolon.
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 265c12d7d5e..aa8ed91d382 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -602,10 +602,6 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
ConsumeToken();
return false;
- case tok::annot_pragma_attribute:
- HandlePragmaAttribute();
- return false;
-
case tok::eof:
// Late template parsing can begin.
if (getLangOpts().DelayedTemplateParsing)
diff --git a/clang/lib/Sema/AttributeList.cpp b/clang/lib/Sema/AttributeList.cpp
index 724db456785..55e9601bf5e 100644
--- a/clang/lib/Sema/AttributeList.cpp
+++ b/clang/lib/Sema/AttributeList.cpp
@@ -16,7 +16,6 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
-#include "clang/Basic/AttrSubjectMatchRules.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/SemaInternal.h"
@@ -161,16 +160,12 @@ struct ParsedAttrInfo {
unsigned IsType : 1;
unsigned IsStmt : 1;
unsigned IsKnownToGCC : 1;
- unsigned IsSupportedByPragmaAttribute : 1;
bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr,
const Decl *);
bool (*DiagLangOpts)(Sema &S, const AttributeList &Attr);
bool (*ExistsInTarget)(const TargetInfo &Target);
unsigned (*SpellingIndexToSemanticSpelling)(const AttributeList &Attr);
- void (*GetPragmaAttributeMatchRules)(
- llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
- const LangOptions &LangOpts);
};
namespace {
@@ -197,18 +192,6 @@ bool AttributeList::diagnoseAppertainsTo(Sema &S, const Decl *D) const {
return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
}
-bool AttributeList::appliesToDecl(const Decl *D,
- attr::SubjectMatchRule MatchRule) const {
- return checkAttributeMatchRuleAppliesTo(D, MatchRule);
-}
-
-void AttributeList::getMatchRules(
- const LangOptions &LangOpts,
- SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
- const {
- return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts);
-}
-
bool AttributeList::diagnoseLangOpts(Sema &S) const {
return getInfo(*this).DiagLangOpts(S, *this);
}
@@ -233,10 +216,6 @@ bool AttributeList::isKnownToGCC() const {
return getInfo(*this).IsKnownToGCC;
}
-bool AttributeList::isSupportedByPragmaAttribute() const {
- return getInfo(*this).IsSupportedByPragmaAttribute;
-}
-
unsigned AttributeList::getSemanticSpelling() const {
return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
}
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 950f0408882..294b56059b3 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -71,35 +71,42 @@ void Sema::ActOnTranslationUnitScope(Scope *S) {
}
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
- TranslationUnitKind TUKind, CodeCompleteConsumer *CodeCompleter)
- : ExternalSource(nullptr), isMultiplexExternalSource(false),
- FPFeatures(pp.getLangOpts()), LangOpts(pp.getLangOpts()), PP(pp),
- Context(ctxt), Consumer(consumer), Diags(PP.getDiagnostics()),
- SourceMgr(PP.getSourceManager()), CollectStats(false),
- CodeCompleter(CodeCompleter), CurContext(nullptr),
- OriginalLexicalContext(nullptr), MSStructPragmaOn(false),
- MSPointerToMemberRepresentationMethod(
- LangOpts.getMSPointerToMemberRepresentationMethod()),
- VtorDispStack(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)), PackStack(0),
- DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr),
- CodeSegStack(nullptr), CurInitSeg(nullptr), VisContext(nullptr),
- PragmaAttributeCurrentTargetDecl(nullptr),
- IsBuildingRecoveryCallExpr(false), Cleanup{}, LateTemplateParser(nullptr),
- LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp),
- StdExperimentalNamespaceCache(nullptr), StdInitializerList(nullptr),
- CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr), NSNumberDecl(nullptr),
- NSValueDecl(nullptr), NSStringDecl(nullptr),
- StringWithUTF8StringMethod(nullptr),
- ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr),
- ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr),
- DictionaryWithObjectsMethod(nullptr), GlobalNewDeleteDeclared(false),
- TUKind(TUKind), NumSFINAEErrors(0), CachedFakeTopLevelModule(nullptr),
- AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),
- NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1),
- CurrentInstantiationScope(nullptr), DisableTypoCorrection(false),
- TyposCorrected(0), AnalysisWarnings(*this),
- ThreadSafetyDeclCache(nullptr), VarDataSharingAttributesStack(nullptr),
- CurScope(nullptr), Ident_super(nullptr), Ident___float128(nullptr) {
+ TranslationUnitKind TUKind,
+ CodeCompleteConsumer *CodeCompleter)
+ : ExternalSource(nullptr),
+ isMultiplexExternalSource(false), FPFeatures(pp.getLangOpts()),
+ LangOpts(pp.getLangOpts()), PP(pp), Context(ctxt), Consumer(consumer),
+ Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
+ CollectStats(false), CodeCompleter(CodeCompleter),
+ CurContext(nullptr), OriginalLexicalContext(nullptr),
+ MSStructPragmaOn(false),
+ MSPointerToMemberRepresentationMethod(
+ LangOpts.getMSPointerToMemberRepresentationMethod()),
+ VtorDispStack(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)),
+ PackStack(0), DataSegStack(nullptr), BSSSegStack(nullptr),
+ ConstSegStack(nullptr), CodeSegStack(nullptr), CurInitSeg(nullptr),
+ VisContext(nullptr),
+ IsBuildingRecoveryCallExpr(false),
+ Cleanup{}, LateTemplateParser(nullptr),
+ LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp),
+ StdExperimentalNamespaceCache(nullptr), StdInitializerList(nullptr),
+ CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr),
+ NSNumberDecl(nullptr), NSValueDecl(nullptr),
+ NSStringDecl(nullptr), StringWithUTF8StringMethod(nullptr),
+ ValueWithBytesObjCTypeMethod(nullptr),
+ NSArrayDecl(nullptr), ArrayWithObjectsMethod(nullptr),
+ NSDictionaryDecl(nullptr), DictionaryWithObjectsMethod(nullptr),
+ GlobalNewDeleteDeclared(false),
+ TUKind(TUKind),
+ NumSFINAEErrors(0),
+ CachedFakeTopLevelModule(nullptr),
+ AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),
+ NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1),
+ CurrentInstantiationScope(nullptr), DisableTypoCorrection(false),
+ TyposCorrected(0), AnalysisWarnings(*this), ThreadSafetyDeclCache(nullptr),
+ VarDataSharingAttributesStack(nullptr), CurScope(nullptr),
+ Ident_super(nullptr), Ident___float128(nullptr)
+{
TUScope = nullptr;
LoadedExternalKnownNamespaces = false;
@@ -724,8 +731,6 @@ void Sema::ActOnEndOfTranslationUnit() {
CheckDelayedMemberExceptionSpecs();
}
- DiagnoseUnterminatedPragmaAttribute();
-
// All delayed member exception specs should be checked or we end up accepting
// incompatible declarations.
// FIXME: This is wrong for TUKind == TU_Prefix. In that case, we need to
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index dfc5d6cd015..c6e3cc88631 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -368,217 +368,6 @@ void Sema::AddCFAuditedAttribute(Decl *D) {
D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Loc));
}
-namespace {
-
-Optional<attr::SubjectMatchRule>
-getParentAttrMatcherRule(attr::SubjectMatchRule Rule) {
- using namespace attr;
- switch (Rule) {
- default:
- return None;
-#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
-#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
- case Value: \
- return Parent;
-#include "clang/Basic/AttrSubMatchRulesList.inc"
- }
-}
-
-bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule) {
- using namespace attr;
- switch (Rule) {
- default:
- return false;
-#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
-#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
- case Value: \
- return IsNegated;
-#include "clang/Basic/AttrSubMatchRulesList.inc"
- }
-}
-
-CharSourceRange replacementRangeForListElement(const Sema &S,
- SourceRange Range) {
- // Make sure that the ',' is removed as well.
- SourceLocation AfterCommaLoc = Lexer::findLocationAfterToken(
- Range.getEnd(), tok::comma, S.getSourceManager(), S.getLangOpts(),
- /*SkipTrailingWhitespaceAndNewLine=*/false);
- if (AfterCommaLoc.isValid())
- return CharSourceRange::getCharRange(Range.getBegin(), AfterCommaLoc);
- else
- return CharSourceRange::getTokenRange(Range);
-}
-
-std::string
-attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) {
- std::string Result;
- llvm::raw_string_ostream OS(Result);
- for (const auto &I : llvm::enumerate(Rules)) {
- if (I.index())
- OS << (I.index() == Rules.size() - 1 ? ", and " : ", ");
- OS << "'" << attr::getSubjectMatchRuleSpelling(I.value()) << "'";
- }
- return OS.str();
-}
-
-} // end anonymous namespace
-
-void Sema::ActOnPragmaAttributePush(AttributeList &Attribute,
- SourceLocation PragmaLoc,
- attr::ParsedSubjectMatchRuleSet Rules) {
- SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules;
- // Gather the subject match rules that are supported by the attribute.
- SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4>
- StrictSubjectMatchRuleSet;
- Attribute.getMatchRules(LangOpts, StrictSubjectMatchRuleSet);
-
- // Figure out which subject matching rules are valid.
- if (StrictSubjectMatchRuleSet.empty()) {
- // Check for contradicting match rules. Contradicting match rules are
- // either:
- // - a top-level rule and one of its sub-rules. E.g. variable and
- // variable(is_parameter).
- // - a sub-rule and a sibling that's negated. E.g.
- // variable(is_thread_local) and variable(unless(is_parameter))
- llvm::SmallDenseMap<attr::SubjectMatchRule,
- std::pair<attr::SubjectMatchRule, SourceRange>, 2>
- RulesToFirstSpecifiedNegatedSubRule;
- for (const auto &Rule : Rules) {
- Optional<attr::SubjectMatchRule> ParentRule =
- getParentAttrMatcherRule(Rule.first);
- if (!ParentRule)
- continue;
- auto It = Rules.find(*ParentRule);
- if (It != Rules.end()) {
- // A sub-rule contradicts a parent rule.
- Diag(Rule.second.getBegin(),
- diag::err_pragma_attribute_matcher_subrule_contradicts_rule)
- << attr::getSubjectMatchRuleSpelling(Rule.first)
- << attr::getSubjectMatchRuleSpelling(*ParentRule) << It->second
- << FixItHint::CreateRemoval(
- replacementRangeForListElement(*this, Rule.second));
- // Keep going without removing this rule as it won't change the set of
- // declarations that receive the attribute.
- continue;
- }
- if (isNegatedAttrMatcherSubRule(Rule.first))
- RulesToFirstSpecifiedNegatedSubRule.insert(
- std::make_pair(*ParentRule, Rule));
- }
- bool IgnoreNegatedSubRules = false;
- for (const auto &Rule : Rules) {
- Optional<attr::SubjectMatchRule> ParentRule =
- getParentAttrMatcherRule(Rule.first);
- if (!ParentRule)
- continue;
- auto It = RulesToFirstSpecifiedNegatedSubRule.find(*ParentRule);
- if (It != RulesToFirstSpecifiedNegatedSubRule.end() &&
- It->second != Rule) {
- // Negated sub-rule contradicts another sub-rule.
- Diag(
- It->second.second.getBegin(),
- diag::
- err_pragma_attribute_matcher_negated_subrule_contradicts_subrule)
- << attr::getSubjectMatchRuleSpelling(It->second.first)
- << attr::getSubjectMatchRuleSpelling(Rule.first) << Rule.second
- << FixItHint::CreateRemoval(
- replacementRangeForListElement(*this, It->second.second));
- // Keep going but ignore all of the negated sub-rules.
- IgnoreNegatedSubRules = true;
- RulesToFirstSpecifiedNegatedSubRule.erase(It);
- }
- }
-
- if (!IgnoreNegatedSubRules) {
- for (const auto &Rule : Rules)
- SubjectMatchRules.push_back(Rule.first);
- } else {
- for (const auto &Rule : Rules) {
- if (!isNegatedAttrMatcherSubRule(Rule.first))
- SubjectMatchRules.push_back(Rule.first);
- }
- }
- Rules.clear();
- } else {
- for (const auto &Rule : StrictSubjectMatchRuleSet) {
- if (Rules.erase(Rule.first)) {
- // Add the rule to the set of attribute receivers only if it's supported
- // in the current language mode.
- if (Rule.second)
- SubjectMatchRules.push_back(Rule.first);
- }
- }
- }
-
- if (!Rules.empty()) {
- auto Diagnostic =
- Diag(PragmaLoc, diag::err_pragma_attribute_invalid_matchers)
- << Attribute.getName();
- SmallVector<attr::SubjectMatchRule, 2> ExtraRules;
- for (const auto &Rule : Rules) {
- ExtraRules.push_back(Rule.first);
- Diagnostic << FixItHint::CreateRemoval(
- replacementRangeForListElement(*this, Rule.second));
- }
- Diagnostic << attrMatcherRuleListToString(ExtraRules);
- }
-
- PragmaAttributeStack.push_back(
- {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false});
-}
-
-void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc) {
- if (PragmaAttributeStack.empty()) {
- Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch);
- return;
- }
- const PragmaAttributeEntry &Entry = PragmaAttributeStack.back();
- if (!Entry.IsUsed) {
- assert(Entry.Attribute && "Expected an attribute");
- Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused)
- << Entry.Attribute->getName();
- Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here);
- }
- PragmaAttributeStack.pop_back();
-}
-
-void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
- if (PragmaAttributeStack.empty())
- return;
- for (auto &Entry : PragmaAttributeStack) {
- const AttributeList *Attribute = Entry.Attribute;
- assert(Attribute && "Expected an attribute");
-
- // Ensure that the attribute can be applied to the given declaration.
- bool Applies = false;
- for (const auto &Rule : Entry.MatchRules) {
- if (Attribute->appliesToDecl(D, Rule)) {
- Applies = true;
- break;
- }
- }
- if (!Applies)
- continue;
- Entry.IsUsed = true;
- assert(!Attribute->getNext() && "Expected just one attribute");
- PragmaAttributeCurrentTargetDecl = D;
- ProcessDeclAttributeList(S, D, Attribute);
- PragmaAttributeCurrentTargetDecl = nullptr;
- }
-}
-
-void Sema::PrintPragmaAttributeInstantiationPoint() {
- assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration");
- Diags.Report(PragmaAttributeCurrentTargetDecl->getLocStart(),
- diag::note_pragma_attribute_applied_decl_here);
-}
-
-void Sema::DiagnoseUnterminatedPragmaAttribute() {
- if (PragmaAttributeStack.empty())
- return;
- Diag(PragmaAttributeStack.back().Loc, diag::err_pragma_attribute_no_pop_eof);
-}
-
void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) {
if(On)
OptimizeOffPragmaLocation = SourceLocation();
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 075e87b75cd..c6a0b0101d3 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13674,7 +13674,6 @@ CreateNewDecl:
if (Attr)
ProcessDeclAttributeList(S, New, Attr);
- AddPragmaAttributes(S, New);
// If this has an identifier, add it to the scope stack.
if (TUK == TUK_Friend) {
@@ -15186,7 +15185,6 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst,
// Process attributes.
if (Attr) ProcessDeclAttributeList(S, New, Attr);
- AddPragmaAttributes(S, New);
// Register this decl in the current scope stack.
New->setAccess(TheEnumDecl->getAccess());
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index ae941c88ca3..a1ba9de368d 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6676,9 +6676,6 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
// Finally, apply any attributes on the decl itself.
if (const AttributeList *Attrs = PD.getAttributes())
ProcessDeclAttributeList(S, D, Attrs);
-
- // Apply additional attributes specified by '#pragma clang attribute'.
- AddPragmaAttributes(S, D);
}
/// Is the given declaration allowed to use a forbidden type?
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index b543a731641..fd3f266c9a0 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -8445,7 +8445,6 @@ Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
Namespc->setInvalidDecl();
ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
- AddPragmaAttributes(DeclRegionScope, Namespc);
// FIXME: Should we be merging attributes?
if (const VisibilityAttr *Attr = Namespc->getAttr<VisibilityAttr>())
@@ -9932,7 +9931,6 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S,
NewTD->setInvalidDecl();
ProcessDeclAttributeList(S, NewTD, AttrList);
- AddPragmaAttributes(S, NewTD);
CheckTypedefForVariablyModifiedType(S, NewTD);
Invalid |= NewTD->isInvalidDecl();
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 4f51cd399c0..e50f8b20677 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -993,7 +993,6 @@ ActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc,
if (AttrList)
ProcessDeclAttributeList(TUScope, IDecl, AttrList);
- AddPragmaAttributes(TUScope, IDecl);
PushOnScopeChains(IDecl, TUScope);
// Start the definition of this class. If we're in a redefinition case, there
@@ -1177,8 +1176,7 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
if (AttrList)
ProcessDeclAttributeList(TUScope, PDecl, AttrList);
- AddPragmaAttributes(TUScope, PDecl);
-
+
// Merge attributes from previous declarations.
if (PrevDecl)
mergeDeclAttributes(PDecl, PrevDecl);
@@ -1708,8 +1706,7 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
if (attrList)
ProcessDeclAttributeList(TUScope, PDecl, attrList);
- AddPragmaAttributes(TUScope, PDecl);
-
+
if (PrevDecl)
mergeDeclAttributes(PDecl, PrevDecl);
@@ -1808,7 +1805,6 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
if (AttrList)
ProcessDeclAttributeList(TUScope, CDecl, AttrList);
- AddPragmaAttributes(TUScope, CDecl);
CheckObjCDeclScope(CDecl);
return ActOnObjCContainerStartDefinition(CDecl);
@@ -1958,7 +1954,6 @@ Decl *Sema::ActOnStartClassImplementation(
ClassName, /*typeParamList=*/nullptr,
/*PrevDecl=*/nullptr, ClassLoc,
true);
- AddPragmaAttributes(TUScope, IDecl);
IDecl->startDefinition();
if (SDecl) {
IDecl->setSuperClass(Context.getTrivialTypeSourceInfo(
@@ -3048,7 +3043,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
ClassName, TypeParams, PrevIDecl,
IdentLocs[i]);
IDecl->setAtEndRange(IdentLocs[i]);
-
+
PushOnScopeChains(IDecl, TUScope);
CheckObjCDeclScope(IDecl);
DeclsInGroup.push_back(IDecl);
@@ -4404,7 +4399,6 @@ Decl *Sema::ActOnMethodDeclaration(
// Apply the attributes to the parameter.
ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs);
- AddPragmaAttributes(TUScope, Param);
if (Param->hasAttr<BlocksAttr>()) {
Diag(Param->getLocation(), diag::err_block_on_nonlocal);
@@ -4435,7 +4429,6 @@ Decl *Sema::ActOnMethodDeclaration(
if (AttrList)
ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
- AddPragmaAttributes(TUScope, ObjCMethod);
// Add the method now.
const ObjCMethodDecl *PrevMethod = nullptr;
OpenPOWER on IntegriCloud