]> granicus.if.org Git - clang/commitdiff
Batch up access-related diagnostics on enum constants until the whole enum is parsed.
authorJordan Rose <jordan_rose@apple.com>
Thu, 30 Apr 2015 17:20:30 +0000 (17:20 +0000)
committerJordan Rose <jordan_rose@apple.com>
Thu, 30 Apr 2015 17:20:30 +0000 (17:20 +0000)
That way we can take any trailing availability attributes into account.

rdar://problem/20713550

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236241 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/DelayedDiagnostic.h
lib/Parse/ParseDecl.cpp
lib/Parse/RAIIObjectsForParser.h
test/Sema/attr-availability.c

index e19d1115f03d8390616089800f575f00bb75f9eb..155b3aa72d70a66b028abf17678fb50b48d660ea 100644 (file)
@@ -250,6 +250,17 @@ public:
       i->Destroy();
   }
 
+  DelayedDiagnosticPool(DelayedDiagnosticPool &&Other)
+    : Parent(Other.Parent), Diagnostics(std::move(Other.Diagnostics)) {
+    Other.Diagnostics.clear();
+  }
+  DelayedDiagnosticPool &operator=(DelayedDiagnosticPool &&Other) {
+    Parent = Other.Parent;
+    Diagnostics = std::move(Other.Diagnostics);
+    Other.Diagnostics.clear();
+    return *this;
+  }
+
   const DelayedDiagnosticPool *getParent() const { return Parent; }
 
   /// Does this pool, or any of its ancestors, contain any diagnostics?
index c64421793c6549269ea10fb4cae4813d42321be2..16639f04cea16c56e7698023754ba0ffb0d12af3 100644 (file)
@@ -3974,6 +3974,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
     Diag(Tok, diag::error_empty_enum);
 
   SmallVector<Decl *, 32> EnumConstantDecls;
+  SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
 
   Decl *LastEnumConstDecl = nullptr;
 
@@ -4004,7 +4005,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
 
     SourceLocation EqualLoc;
     ExprResult AssignedVal;
-    ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
+    EnumAvailabilityDiags.emplace_back(*this);
 
     if (TryConsumeToken(tok::equal, EqualLoc)) {
       AssignedVal = ParseConstantExpression();
@@ -4018,7 +4019,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
                                                     IdentLoc, Ident,
                                                     attrs.getList(), EqualLoc,
                                                     AssignedVal.get());
-    PD.complete(EnumConstDecl);
+    EnumAvailabilityDiags.back().done();
 
     EnumConstantDecls.push_back(EnumConstDecl);
     LastEnumConstDecl = EnumConstDecl;
@@ -4074,6 +4075,14 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
                         getCurScope(),
                         attrs.getList());
 
+  // Now handle enum constant availability diagnostics.
+  assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
+  for (size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
+    ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
+    EnumAvailabilityDiags[i].redelay();
+    PD.complete(EnumConstantDecls[i]);
+  }
+
   EnumScope.Exit();
   Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl,
                                    T.getCloseLocation());
index 71cfec47048a9a95fde1a39495d2b0a861ea235a..c2f498041958be7dae004c317ef407a6abcb50d2 100644 (file)
@@ -58,6 +58,12 @@ namespace clang {
         Active = false;
       }
     }
+    SuppressAccessChecks(SuppressAccessChecks &&Other)
+      : S(Other.S), DiagnosticPool(std::move(Other.DiagnosticPool)),
+        State(Other.State), Active(Other.Active) {
+      Other.Active = false;
+    }
+    void operator=(SuppressAccessChecks &&Other) = delete;
 
     void done() {
       assert(Active && "trying to end an inactive suppression");
index 48bdf26598c94e808fedf8b475d76e257efbd57d..ce64fab398390fdcbc6e04640e0719d1bfb48def 100644 (file)
@@ -79,3 +79,84 @@ void f8() {
 
 extern int x2 __attribute__((availability(macosx,introduced=10.2))); // expected-note {{previous attribute is here}}
 extern int x2 __attribute__((availability(macosx,introduced=10.5))); // expected-warning {{availability does not match previous declaration}}
+
+
+enum Original {
+  OriginalDeprecated __attribute__((availability(macosx, deprecated=10.2))), // expected-note + {{'OriginalDeprecated' has been explicitly marked deprecated here}}
+  OriginalUnavailable __attribute__((availability(macosx, unavailable))) // expected-note + {{'OriginalUnavailable' has been explicitly marked unavailable here}}
+};
+
+enum AllDeprecated {
+  AllDeprecatedCase, // expected-note + {{'AllDeprecatedCase' has been explicitly marked deprecated here}}
+  AllDeprecatedUnavailable __attribute__((availability(macosx, unavailable))) // expected-note + {{'AllDeprecatedUnavailable' has been explicitly marked unavailable here}}
+} __attribute__((availability(macosx, deprecated=10.2)));
+
+enum AllUnavailable {
+  AllUnavailableCase, // expected-note + {{'AllUnavailableCase' has been explicitly marked unavailable here}}
+} __attribute__((availability(macosx, unavailable)));
+
+enum User {
+  UserOD = OriginalDeprecated, // expected-warning {{deprecated}}
+  UserODDeprecated __attribute__((availability(macosx, deprecated=10.2))) = OriginalDeprecated,
+  UserODUnavailable __attribute__((availability(macosx, unavailable))) = OriginalDeprecated, // expected-warning {{deprecated}}
+
+  UserOU = OriginalUnavailable, // expected-error {{unavailable}}
+  UserOUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = OriginalUnavailable, // expected-error {{unavailable}}
+  UserOUUnavailable __attribute__((availability(macosx, unavailable))) = OriginalUnavailable,
+
+  UserAD = AllDeprecatedCase, // expected-warning {{deprecated}}
+  UserADDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllDeprecatedCase,
+  UserADUnavailable __attribute__((availability(macosx, unavailable))) = AllDeprecatedCase, // expected-warning {{deprecated}}
+
+  UserADU = AllDeprecatedUnavailable, // expected-error {{unavailable}}
+  UserADUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllDeprecatedUnavailable, // expected-error {{unavailable}}
+  UserADUUnavailable __attribute__((availability(macosx, unavailable))) = AllDeprecatedUnavailable,
+
+  UserAU = AllUnavailableCase, // expected-error {{unavailable}}
+  UserAUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllUnavailableCase, // expected-error {{unavailable}}
+  UserAUUnavailable __attribute__((availability(macosx, unavailable))) = AllUnavailableCase,
+};
+
+enum UserDeprecated {
+  UserDeprecatedOD = OriginalDeprecated,
+  UserDeprecatedODDeprecated __attribute__((availability(macosx, deprecated=10.2))) = OriginalDeprecated,
+  UserDeprecatedODUnavailable __attribute__((availability(macosx, unavailable))) = OriginalDeprecated,
+
+  UserDeprecatedOU = OriginalUnavailable, // expected-error {{unavailable}}
+  UserDeprecatedOUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = OriginalUnavailable, // expected-error {{unavailable}}
+  UserDeprecatedOUUnavailable __attribute__((availability(macosx, unavailable))) = OriginalUnavailable,
+
+  UserDeprecatedAD = AllDeprecatedCase,
+  UserDeprecatedADDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllDeprecatedCase,
+  UserDeprecatedADUnavailable __attribute__((availability(macosx, unavailable))) = AllDeprecatedCase,
+
+  UserDeprecatedADU = AllDeprecatedUnavailable, // expected-error {{unavailable}}
+  UserDeprecatedADUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllDeprecatedUnavailable, // expected-error {{unavailable}}
+  UserDeprecatedADUUnavailable __attribute__((availability(macosx, unavailable))) = AllDeprecatedUnavailable,
+
+  UserDeprecatedAU = AllUnavailableCase, // expected-error {{unavailable}}
+  UserDeprecatedAUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllUnavailableCase, // expected-error {{unavailable}}
+  UserDeprecatedAUUnavailable __attribute__((availability(macosx, unavailable))) = AllUnavailableCase,
+} __attribute__((availability(macosx, deprecated=10.2)));
+
+enum UserUnavailable {
+  UserUnavailableOD = OriginalDeprecated, // expected-warning {{deprecated}}
+  UserUnavailableODDeprecated __attribute__((availability(macosx, deprecated=10.2))) = OriginalDeprecated,
+  UserUnavailableODUnavailable __attribute__((availability(macosx, unavailable))) = OriginalDeprecated, // expected-warning {{deprecated}}
+
+  UserUnavailableOU = OriginalUnavailable,
+  UserUnavailableOUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = OriginalUnavailable,
+  UserUnavailableOUUnavailable __attribute__((availability(macosx, unavailable))) = OriginalUnavailable,
+
+  UserUnavailableAD = AllDeprecatedCase, // expected-warning {{deprecated}}
+  UserUnavailableADDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllDeprecatedCase,
+  UserUnavailableADUnavailable __attribute__((availability(macosx, unavailable))) = AllDeprecatedCase, // expected-warning {{deprecated}}
+
+  UserUnavailableADU = AllDeprecatedUnavailable,
+  UserUnavailableADUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllDeprecatedUnavailable,
+  UserUnavailableADUUnavailable __attribute__((availability(macosx, unavailable))) = AllDeprecatedUnavailable,
+
+  UserUnavailableAU = AllUnavailableCase,
+  UserUnavailableAUDeprecated __attribute__((availability(macosx, deprecated=10.2))) = AllUnavailableCase,
+  UserUnavailableAUUnavailable __attribute__((availability(macosx, unavailable))) = AllUnavailableCase,
+} __attribute__((availability(macosx, unavailable)));