tbaeder updated this revision to Diff 334604.
tbaeder added a comment.

I know it's been a while, but here's an update on that patch.

Now that I've got https://reviews.llvm.org/D97362 and 
https://reviews.llvm.org/D97371 pushed, this is  a much simpler change and does 
not break any of the existing tests anymore.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75844/new/

https://reviews.llvm.org/D75844

Files:
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/ParsedAttr.h
  clang/lib/Parse/ParseDecl.cpp
  clang/test/AST/sourceranges.cpp
  clang/test/SemaCXX/switch-implicit-fallthrough.cpp

Index: clang/test/SemaCXX/switch-implicit-fallthrough.cpp
===================================================================
--- clang/test/SemaCXX/switch-implicit-fallthrough.cpp
+++ clang/test/SemaCXX/switch-implicit-fallthrough.cpp
@@ -185,8 +185,11 @@
       return 1;
       [[clang::fallthrough]];  // expected-warning{{fallthrough annotation in unreachable code}}
     case 222:
+      return 2;
+      __attribute__((fallthrough)); // expected-warning{{fallthrough annotation in unreachable code}}
+    case 223:
       n += 400;
-    case 223:          // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+    case 224:          // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
       ;
   }
 
@@ -341,3 +344,16 @@
   }
   return n;
 }
+
+int fallthrough_in_unreachable_code(int n) {
+  switch (n) {
+    case 1:
+#ifndef MAYBE_THIS_EXISTS
+      return -1;
+#endif
+      __attribute__((fallthrough));
+    case 2:
+      return 3;
+  }
+  return n;
+}
Index: clang/test/AST/sourceranges.cpp
===================================================================
--- clang/test/AST/sourceranges.cpp
+++ clang/test/AST/sourceranges.cpp
@@ -108,6 +108,25 @@
   }
 }
 
+// CHECK-1Z: NamespaceDecl {{.*}} attributed_case
+namespace attributed_case {
+  void f(int n) {
+    switch(n) {
+      case 0:
+        n--;
+        // CHECK: AttributedStmt {{.*}} <line:[[@LINE+2]]:9, line:[[@LINE+5]]:11>
+        // CHECK: FallThroughAttr {{.*}} <line:[[@LINE+1]]:24>
+        __attribute__((fallthrough))
+        // CHECK: FallThroughAttr {{.*}} <line:[[@LINE+1]]:26>
+          __attribute__((fallthrough))
+          ;
+      case 1:
+        n++;
+        break;
+    }
+  }
+}
+
 // CHECK: NamespaceDecl {{.*}} attributed_stmt
 namespace attributed_stmt {
   // In DO_PRAGMA and _Pragma cases, `LoopHintAttr` comes from <scratch space>
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -162,12 +162,17 @@
 ///    ',' or ')' are ignored, otherwise they produce a parse error.
 ///
 /// We follow the C++ model, but don't allow junk after the identifier.
-void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
+void Parser::ParseGNUAttributes(ParsedAttributesWithRange &attrs,
                                 SourceLocation *endLoc,
                                 LateParsedAttrList *LateAttrs,
                                 Declarator *D) {
   assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
 
+  SourceLocation StartLoc = Tok.getLocation(), Loc;
+
+  if (!endLoc)
+    endLoc = &Loc;
+
   while (Tok.is(tok::kw___attribute)) {
     SourceLocation AttrTokLoc = ConsumeToken();
     unsigned OldNumAttrs = attrs.size();
@@ -260,6 +265,8 @@
       }
     }
   }
+
+  attrs.Range = SourceRange(StartLoc, *endLoc);
 }
 
 /// Determine whether the given attribute has an identifier argument.
Index: clang/include/clang/Sema/ParsedAttr.h
===================================================================
--- clang/include/clang/Sema/ParsedAttr.h
+++ clang/include/clang/Sema/ParsedAttr.h
@@ -1034,6 +1034,27 @@
   mutable AttributePool pool;
 };
 
+struct ParsedAttributesWithRange : ParsedAttributes {
+  ParsedAttributesWithRange(AttributeFactory &factory)
+    : ParsedAttributes(factory) {}
+
+  void clear() {
+    ParsedAttributes::clear();
+    Range = SourceRange();
+  }
+
+  SourceRange Range;
+};
+struct ParsedAttributesViewWithRange : ParsedAttributesView {
+  ParsedAttributesViewWithRange() : ParsedAttributesView() {}
+  void clearListOnly() {
+    ParsedAttributesView::clearListOnly();
+    Range = SourceRange();
+  }
+
+  SourceRange Range;
+};
+
 /// These constants match the enumerated choices of
 /// err_attribute_argument_n_type and err_attribute_argument_type.
 enum AttributeArgumentNType {
Index: clang/include/clang/Parse/Parser.h
===================================================================
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -1572,27 +1572,6 @@
 
   //===--------------------------------------------------------------------===//
   // C99 6.9: External Definitions.
-  struct ParsedAttributesWithRange : ParsedAttributes {
-    ParsedAttributesWithRange(AttributeFactory &factory)
-      : ParsedAttributes(factory) {}
-
-    void clear() {
-      ParsedAttributes::clear();
-      Range = SourceRange();
-    }
-
-    SourceRange Range;
-  };
-  struct ParsedAttributesViewWithRange : ParsedAttributesView {
-    ParsedAttributesViewWithRange() : ParsedAttributesView() {}
-    void clearListOnly() {
-      ParsedAttributesView::clearListOnly();
-      Range = SourceRange();
-    }
-
-    SourceRange Range;
-  };
-
   DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
                                           ParsingDeclSpec *DS = nullptr);
   bool isDeclarationAfterDeclarator();
@@ -2725,7 +2704,19 @@
       D.takeAttributes(attrs, endLoc);
     }
   }
-  bool MaybeParseGNUAttributes(ParsedAttributes &attrs,
+
+  bool MaybeParseGNUAttributes(ParsedAttributes &attrs, SourceLocation *endLoc = nullptr,
+                                LateParsedAttrList *LateAttrs = nullptr) {
+    if (Tok.is(tok::kw___attribute)) {
+      ParsedAttributesWithRange attrsWithRange(AttrFactory);
+      ParseGNUAttributes(attrs, endLoc, LateAttrs);
+      attrs.takeAllFrom(attrsWithRange);
+      return true;
+    }
+    return false;
+  }
+
+  bool MaybeParseGNUAttributes(ParsedAttributesWithRange &attrs,
                                SourceLocation *endLoc = nullptr,
                                LateParsedAttrList *LateAttrs = nullptr) {
     if (Tok.is(tok::kw___attribute)) {
@@ -2734,7 +2725,17 @@
     }
     return false;
   }
+
   void ParseGNUAttributes(ParsedAttributes &attrs,
+                          SourceLocation *endLoc = nullptr,
+                          LateParsedAttrList *LateAttrs = nullptr,
+                          Declarator *D = nullptr) {
+    ParsedAttributesWithRange attrsWithRange(AttrFactory);
+    ParseGNUAttributes(attrsWithRange, endLoc, LateAttrs, D);
+    attrs.takeAllFrom(attrsWithRange);
+  }
+
+  void ParseGNUAttributes(ParsedAttributesWithRange &attrs,
                           SourceLocation *endLoc = nullptr,
                           LateParsedAttrList *LateAttrs = nullptr,
                           Declarator *D = nullptr);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to