r345487 - Revert "Support for groups of attributes in #pragma clang attribute"

Erik Pilkington via cfe-commits cfe-commits at lists.llvm.org
Sun Oct 28 20:24:16 PDT 2018


Author: epilk
Date: Sun Oct 28 20:24:16 2018
New Revision: 345487

URL: http://llvm.org/viewvc/llvm-project?rev=345487&view=rev
Log:
Revert "Support for groups of attributes in #pragma clang attribute"

This reverts commit r345486.

Looks like it causes some old versions of GCC to crash, I'll see if I can
work around it and recommit...

Modified:
    cfe/trunk/docs/LanguageExtensions.rst
    cfe/trunk/docs/ReleaseNotes.rst
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParsePragma.cpp
    cfe/trunk/lib/Sema/SemaAttr.cpp
    cfe/trunk/test/Parser/pragma-attribute.cpp
    cfe/trunk/test/Sema/pragma-attribute.c

Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=345487&r1=345486&r2=345487&view=diff
==============================================================================
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Sun Oct 28 20:24:16 2018
@@ -2651,19 +2651,17 @@ Specifying an attribute for multiple dec
 
 The ``#pragma clang attribute`` directive can be used to apply an attribute to
 multiple declarations. The ``#pragma clang attribute push`` variation of the
-directive pushes a new "scope" of ``#pragma clang attribute`` that attributes
-can be added to. The ``#pragma clang attribute (...)`` variation adds an
-attribute to that scope, and the ``#pragma clang attribute pop`` variation pops
-the scope. You can also use ``#pragma clang attribute push (...)``, which is a
-shorthand for when you want to add one attribute to a new scope. Multiple push
-directives can be nested inside each other.
+directive pushes a new attribute to the attribute stack. The declarations that
+follow the pragma receive the attributes that are on the attribute stack, until
+the stack is cleared using a ``#pragma clang attribute pop`` directive. Multiple
+push directives can be nested inside each other.
 
 The attributes that are used in the ``#pragma clang attribute`` directives
 can be written using the GNU-style syntax:
 
 .. code-block:: c++
 
-  #pragma clang attribute push (__attribute__((annotate("custom"))), apply_to = function)
+  #pragma clang attribute push(__attribute__((annotate("custom"))), apply_to = function)
 
   void function(); // The function now has the annotate("custom") attribute
 
@@ -2673,7 +2671,7 @@ The attributes can also be written using
 
 .. code-block:: c++
 
-  #pragma clang attribute push ([[noreturn]], apply_to = function)
+  #pragma clang attribute push([[noreturn]], apply_to = function)
 
   void function(); // The function now has the [[noreturn]] attribute
 
@@ -2683,7 +2681,7 @@ The ``__declspec`` style syntax is also
 
 .. code-block:: c++
 
-  #pragma clang attribute push (__declspec(dllexport), apply_to = function)
+  #pragma clang attribute push(__declspec(dllexport), apply_to = function)
 
   void function(); // The function now has the __declspec(dllexport) attribute
 

Modified: cfe/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.rst?rev=345487&r1=345486&r2=345487&view=diff
==============================================================================
--- cfe/trunk/docs/ReleaseNotes.rst (original)
+++ cfe/trunk/docs/ReleaseNotes.rst Sun Oct 28 20:24:16 2018
@@ -86,8 +86,8 @@ Modified Compiler Flags
 New Pragmas in Clang
 --------------------
 
-- Clang now supports adding multiple ``#pragma clang attribute`` attributes into
-  a "scope" of ``push``ed attributes.
+Clang now supports the ...
+
 
 Attribute Changes in Clang
 --------------------------

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=345487&r1=345486&r2=345487&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Sun Oct 28 20:24:16 2018
@@ -1032,8 +1032,8 @@ def err_pragma_optimize_invalid_argument
 def err_pragma_optimize_extra_argument : Error<
   "unexpected extra argument '%0' to '#pragma clang optimize'">;
 // - #pragma clang attribute
-def err_pragma_attribute_expected_push_pop_paren : Error<
-  "expected 'push', 'pop', or '(' after '#pragma clang attribute'">;
+def err_pragma_attribute_expected_push_pop : Error<
+  "expected 'push' or 'pop' after '#pragma clang attribute'">;
 def err_pragma_attribute_invalid_argument : Error<
   "unexpected argument '%0' to '#pragma clang attribute'; "
   "expected 'push' or 'pop'">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=345487&r1=345486&r2=345487&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Oct 28 20:24:16 2018
@@ -851,9 +851,6 @@ def err_pragma_attribute_no_pop_eof : Er
   "'#pragma clang attribute push' at end of file">;
 def note_pragma_attribute_applied_decl_here : Note<
   "when applied to this declaration">;
-def err_pragma_attr_attr_no_push : Error<
-  "'#pragma clang attribute' attribute with no matching "
-  "'#pragma clang attribute push'">;
 
 /// Objective-C parser diagnostics
 def err_duplicate_class_def : Error<

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=345487&r1=345486&r2=345487&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sun Oct 28 20:24:16 2018
@@ -491,22 +491,15 @@ public:
   /// VisContext - Manages the stack for \#pragma GCC visibility.
   void *VisContext; // Really a "PragmaVisStack*"
 
-  /// This an attribute introduced by \#pragma clang attribute.
+  /// This represents the stack of attributes that were pushed by
+  /// \#pragma clang attribute.
   struct PragmaAttributeEntry {
     SourceLocation Loc;
     ParsedAttr *Attribute;
     SmallVector<attr::SubjectMatchRule, 4> MatchRules;
     bool IsUsed;
   };
-
-  /// A push'd group of PragmaAttributeEntries.
-  struct PragmaAttributeGroup {
-    /// The location of the push attribute.
-    SourceLocation Loc;
-    SmallVector<PragmaAttributeEntry, 2> Entries;
-  };
-
-  SmallVector<PragmaAttributeGroup, 2> PragmaAttributeStack;
+  SmallVector<PragmaAttributeEntry, 2> PragmaAttributeStack;
 
   /// The declaration that is currently receiving an attribute from the
   /// #pragma attribute stack.
@@ -8477,10 +8470,9 @@ public:
   /// the appropriate attribute.
   void AddCFAuditedAttribute(Decl *D);
 
-  void ActOnPragmaAttributeAttribute(ParsedAttr &Attribute,
-                                     SourceLocation PragmaLoc,
-                                     attr::ParsedSubjectMatchRuleSet Rules);
-  void ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc);
+  /// Called on well-formed '\#pragma clang attribute push'.
+  void ActOnPragmaAttributePush(ParsedAttr &Attribute, SourceLocation PragmaLoc,
+                                attr::ParsedSubjectMatchRuleSet Rules);
 
   /// Called on well-formed '\#pragma clang attribute pop'.
   void ActOnPragmaAttributePop(SourceLocation PragmaLoc);

Modified: cfe/trunk/lib/Parse/ParsePragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=345487&r1=345486&r2=345487&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParsePragma.cpp (original)
+++ cfe/trunk/lib/Parse/ParsePragma.cpp Sun Oct 28 20:24:16 2018
@@ -1133,7 +1133,7 @@ bool Parser::HandlePragmaLoopHint(LoopHi
 
 namespace {
 struct PragmaAttributeInfo {
-  enum ActionType { Push, Pop, Attribute };
+  enum ActionType { Push, Pop };
   ParsedAttributes &Attributes;
   ActionType Action;
   ArrayRef<Token> Tokens;
@@ -1394,16 +1394,8 @@ void Parser::HandlePragmaAttribute() {
     return;
   }
   // Parse the actual attribute with its arguments.
-  assert(Info->Action == PragmaAttributeInfo::Push ||
-         Info->Action == PragmaAttributeInfo::Attribute &&
-             "Unexpected #pragma attribute command");
-
-  if (Info->Action == PragmaAttributeInfo::Push && Info->Tokens.empty()) {
-    ConsumeAnnotationToken();
-    Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc);
-    return;
-  }
-
+  assert(Info->Action == PragmaAttributeInfo::Push &&
+         "Unexpected #pragma attribute command");
   PP.EnterTokenStream(Info->Tokens, /*DisableMacroExpansion=*/false);
   ConsumeAnnotationToken();
 
@@ -1550,12 +1542,8 @@ void Parser::HandlePragmaAttribute() {
   // Consume the eof terminator token.
   ConsumeToken();
 
-  // Handle a mixed push/attribute by desurging to a push, then an attribute.
-  if (Info->Action == PragmaAttributeInfo::Push)
-    Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc);
-
-  Actions.ActOnPragmaAttributeAttribute(Attribute, PragmaLoc,
-                                        std::move(SubjectMatchRules));
+  Actions.ActOnPragmaAttributePush(Attribute, PragmaLoc,
+                                   std::move(SubjectMatchRules));
 }
 
 // #pragma GCC visibility comes in two variants:
@@ -3116,8 +3104,6 @@ void PragmaForceCUDAHostDeviceHandler::H
 /// The syntax is:
 /// \code
 ///  #pragma clang attribute push(attribute, subject-set)
-///  #pragma clang attribute push
-///  #pragma clang attribute (attribute, subject-set)
 ///  #pragma clang attribute pop
 /// \endcode
 ///
@@ -3136,33 +3122,25 @@ void PragmaAttributeHandler::HandlePragm
   auto *Info = new (PP.getPreprocessorAllocator())
       PragmaAttributeInfo(AttributesForPragmaAttribute);
 
-  if (!Tok.isOneOf(tok::identifier, tok::l_paren)) {
-    PP.Diag(Tok.getLocation(),
-            diag::err_pragma_attribute_expected_push_pop_paren);
+  // Parse the 'push' or 'pop'.
+  if (Tok.isNot(tok::identifier)) {
+    PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_push_pop);
     return;
   }
-
-  // Determine what action this pragma clang attribute represents.
-  if (Tok.is(tok::l_paren))
-    Info->Action = PragmaAttributeInfo::Attribute;
+  const auto *II = Tok.getIdentifierInfo();
+  if (II->isStr("push"))
+    Info->Action = PragmaAttributeInfo::Push;
+  else if (II->isStr("pop"))
+    Info->Action = PragmaAttributeInfo::Pop;
   else {
-    const IdentifierInfo *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);
+    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 && Tok.isNot(tok::eod)) ||
-      Info->Action == PragmaAttributeInfo::Attribute) {
+  if (Info->Action == PragmaAttributeInfo::Push) {
     if (Tok.isNot(tok::l_paren)) {
       PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
       return;

Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=345487&r1=345486&r2=345487&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Sun Oct 28 20:24:16 2018
@@ -520,9 +520,9 @@ attrMatcherRuleListToString(ArrayRef<att
 
 } // end anonymous namespace
 
-void Sema::ActOnPragmaAttributeAttribute(
-    ParsedAttr &Attribute, SourceLocation PragmaLoc,
-    attr::ParsedSubjectMatchRuleSet Rules) {
+void Sema::ActOnPragmaAttributePush(ParsedAttr &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>
@@ -622,64 +622,48 @@ void Sema::ActOnPragmaAttributeAttribute
     Diagnostic << attrMatcherRuleListToString(ExtraRules);
   }
 
-  if (PragmaAttributeStack.empty()) {
-    Diag(PragmaLoc, diag::err_pragma_attr_attr_no_push);
-    return;
-  }
-
-  PragmaAttributeStack.back().Entries.push_back(
+  PragmaAttributeStack.push_back(
       {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false});
 }
 
-void Sema::ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc) {
-  PragmaAttributeStack.emplace_back();
-  PragmaAttributeStack.back().Loc = PragmaLoc;
-}
-
 void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc) {
   if (PragmaAttributeStack.empty()) {
     Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch);
     return;
   }
-
-  for (const PragmaAttributeEntry &Entry :
-       PragmaAttributeStack.back().Entries) {
-    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);
-    }
+  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 &Group : PragmaAttributeStack) {
-    for (auto &Entry : Group.Entries) {
-      ParsedAttr *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;
-        }
+  for (auto &Entry : PragmaAttributeStack) {
+    ParsedAttr *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;
-      PragmaAttributeCurrentTargetDecl = D;
-      ParsedAttributesView Attrs;
-      Attrs.addAtEnd(Attribute);
-      ProcessDeclAttributeList(S, D, Attrs);
-      PragmaAttributeCurrentTargetDecl = nullptr;
     }
+    if (!Applies)
+      continue;
+    Entry.IsUsed = true;
+    PragmaAttributeCurrentTargetDecl = D;
+    ParsedAttributesView Attrs;
+    Attrs.addAtEnd(Attribute);
+    ProcessDeclAttributeList(S, D, Attrs);
+    PragmaAttributeCurrentTargetDecl = nullptr;
   }
 }
 

Modified: cfe/trunk/test/Parser/pragma-attribute.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/pragma-attribute.cpp?rev=345487&r1=345486&r2=345487&view=diff
==============================================================================
--- cfe/trunk/test/Parser/pragma-attribute.cpp (original)
+++ cfe/trunk/test/Parser/pragma-attribute.cpp Sun Oct 28 20:24:16 2018
@@ -100,12 +100,11 @@ void function();
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(unless(is_parameter)), variable(unless(is_parameter)) )) // expected-error {{duplicate attribute subject matcher 'variable(unless(is_parameter))'}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(unless(is_parameter)), variable(unless(is_parameter)), enum, variable(unless(is_parameter)) )) // expected-error 2 {{duplicate attribute subject matcher 'variable(unless(is_parameter))'}}
 
-#pragma clang attribute // expected-error {{expected 'push', 'pop', or '(' after '#pragma clang attribute'}}
-#pragma clang attribute 42 // expected-error {{expected 'push', 'pop', or '(' after '#pragma clang attribute'}}
+#pragma clang attribute // expected-error {{expected 'push' or 'pop' after '#pragma clang attribute'}}
+#pragma clang attribute 42 // expected-error {{expected 'push' or 'pop' after '#pragma clang attribute'}}
 #pragma clang attribute pushpop // expected-error {{unexpected argument 'pushpop' to '#pragma clang attribute'; expected 'push' or 'pop'}}
 
-#pragma clang attribute push
-#pragma clang attribute pop
+#pragma clang attribute push // expected-error {{expected '('}}
 #pragma clang attribute push ( // expected-error {{expected an attribute after '('}}
 #pragma clang attribute push (__attribute__((annotate)) // expected-error {{expected ')'}}
 #pragma clang attribute push () // expected-error {{expected an attribute after '('}}

Modified: cfe/trunk/test/Sema/pragma-attribute.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/pragma-attribute.c?rev=345487&r1=345486&r2=345487&view=diff
==============================================================================
--- cfe/trunk/test/Sema/pragma-attribute.c (original)
+++ cfe/trunk/test/Sema/pragma-attribute.c Sun Oct 28 20:24:16 2018
@@ -38,29 +38,6 @@ __attribute__((always_inline)) void optn
 
 #pragma clang attribute pop
 
-#pragma clang attribute push (__attribute__((annotate())), apply_to = function) // expected-error{{'annotate' attribute takes one argument}}
-#pragma clang attribute (__attribute__((annotate())), apply_to = function) // expected-error{{'annotate' attribute takes one argument}}
-
-void fun(); // expected-note 2 {{when applied to this declaration}}
-
-#pragma clang attribute pop
-#pragma clang attribute pop // expected-error{{'#pragma clang attribute pop' with no matching '#pragma clang attribute push'}}
-
-
-#pragma clang attribute push
-#pragma clang attribute (__attribute__((annotate())), apply_to = function) // expected-error 2 {{'annotate' attribute takes one argument}}
-
-void fun2(); // expected-note {{when applied to this declaration}}
-
-#pragma clang attribute push (__attribute__((annotate())), apply_to = function) // expected-error{{'annotate' attribute takes one argument}}
-void fun3(); // expected-note 2 {{when applied to this declaration}}
-#pragma clang attribute pop
-
-#pragma clang attribute pop
-#pragma clang attribute pop // expected-error{{'#pragma clang attribute pop' with no matching '#pragma clang attribute push'}}
-
-#pragma clang attribute (__attribute__((annotate)), apply_to = function) // expected-error{{'#pragma clang attribute' attribute with no matching '#pragma clang attribute push}}
-
 #pragma clang attribute push ([[]], apply_to = function) // A noop
 
 #pragma clang attribute pop // expected-error {{'#pragma clang attribute pop' with no matching '#pragma clang attribute push'}}




More information about the cfe-commits mailing list