Index: include/clang/Sema/DelayedDiagnostic.h =================================================================== --- include/clang/Sema/DelayedDiagnostic.h +++ include/clang/Sema/DelayedDiagnostic.h @@ -113,9 +113,9 @@ /// the complete parsing of the current declaration. class DelayedDiagnostic { public: - enum DDKind { Deprecation, Unavailable, Access, ForbiddenType }; + enum DDKind : unsigned char { Availability, Access, ForbiddenType }; - unsigned char Kind; // actually a DDKind + DDKind Kind; bool Triggered; SourceLocation Loc; @@ -165,16 +165,18 @@ } const NamedDecl *getDeprecationDecl() const { - assert((Kind == Deprecation || Kind == Unavailable) && - "Not a deprecation diagnostic."); + assert(Kind == Availability && "Not an availability diagnostic."); return DeprecationData.Decl; } StringRef getDeprecationMessage() const { - assert((Kind == Deprecation || Kind == Unavailable) && - "Not a deprecation diagnostic."); - return StringRef(DeprecationData.Message, - DeprecationData.MessageLen); + assert(Kind == Availability && "Not an availability diagnostic."); + return StringRef(DeprecationData.Message, DeprecationData.MessageLen); + } + + AvailabilityResult getAvailabilityResult() const { + assert(Kind == Availability && "Not an availability diagnostic."); + return DeprecationData.AR; } /// The diagnostic ID to emit. Used like so: @@ -216,6 +218,7 @@ const ObjCPropertyDecl *ObjCProperty; const char *Message; size_t MessageLen; + AvailabilityResult AR; bool ObjCPropertyAccess; }; Index: lib/Sema/DelayedDiagnostic.cpp =================================================================== --- lib/Sema/DelayedDiagnostic.cpp +++ lib/Sema/DelayedDiagnostic.cpp @@ -20,7 +20,7 @@ using namespace sema; DelayedDiagnostic -DelayedDiagnostic::makeAvailability(AvailabilityResult AD, +DelayedDiagnostic::makeAvailability(AvailabilityResult AR, SourceLocation Loc, const NamedDecl *D, const ObjCInterfaceDecl *UnknownObjCClass, @@ -28,16 +28,7 @@ StringRef Msg, bool ObjCPropertyAccess) { DelayedDiagnostic DD; - switch (AD) { - case AR_Deprecated: - DD.Kind = Deprecation; - break; - case AR_Unavailable: - DD.Kind = Unavailable; - break; - default: - llvm_unreachable("partial diags should not be delayed"); - } + DD.Kind = Availability; DD.Triggered = false; DD.Loc = Loc; DD.DeprecationData.Decl = D; @@ -51,18 +42,18 @@ DD.DeprecationData.Message = MessageData; DD.DeprecationData.MessageLen = Msg.size(); + DD.DeprecationData.AR = AR; DD.DeprecationData.ObjCPropertyAccess = ObjCPropertyAccess; return DD; } void DelayedDiagnostic::Destroy() { - switch (static_cast(Kind)) { + switch (Kind) { case Access: getAccessData().~AccessedEntity(); break; - case Deprecation: - case Unavailable: + case Availability: delete [] DeprecationData.Message; break; Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -6464,9 +6464,6 @@ break; case AR_NotYetIntroduced: - assert(!S.getCurFunctionOrMethodDecl() && - "Function-level partial availablity should not be diagnosed here!"); - diag = diag::warn_partial_availability; diag_message = diag::warn_partial_message; diag_fwdclass_message = diag::warn_partial_fwdclass_message; @@ -6539,15 +6536,14 @@ static void handleDelayedAvailabilityCheck(Sema &S, DelayedDiagnostic &DD, Decl *Ctx) { - assert(DD.Kind == DelayedDiagnostic::Deprecation || - DD.Kind == DelayedDiagnostic::Unavailable); - AvailabilityResult AR = DD.Kind == DelayedDiagnostic::Deprecation - ? AR_Deprecated - : AR_Unavailable; + assert(DD.Kind == DelayedDiagnostic::Availability && + "Expected an availability diagnostic here"); + DD.Triggered = true; - DoEmitAvailabilityWarning( - S, AR, Ctx, DD.getDeprecationDecl(), DD.getDeprecationMessage(), DD.Loc, - DD.getUnknownObjCClass(), DD.getObjCProperty(), false); + DoEmitAvailabilityWarning(S, DD.getAvailabilityResult(), Ctx, + DD.getDeprecationDecl(), DD.getDeprecationMessage(), + DD.Loc, DD.getUnknownObjCClass(), + DD.getObjCProperty(), false); } void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) { @@ -6577,8 +6573,7 @@ continue; switch (diag.Kind) { - case DelayedDiagnostic::Deprecation: - case DelayedDiagnostic::Unavailable: + case DelayedDiagnostic::Availability: // Don't bother giving deprecation/unavailable diagnostics if // the decl is invalid. if (!decl->isInvalidDecl()) @@ -6613,8 +6608,7 @@ const ObjCPropertyDecl *ObjCProperty, bool ObjCPropertyAccess) { // Delay if we're currently parsing a declaration. - if (DelayedDiagnostics.shouldDelayDiagnostics() && - AR != AR_NotYetIntroduced) { + if (DelayedDiagnostics.shouldDelayDiagnostics()) { DelayedDiagnostics.add(DelayedDiagnostic::makeAvailability( AR, Loc, D, UnknownObjCClass, ObjCProperty, Message, ObjCPropertyAccess)); Index: test/SemaObjC/unguarded-availability.m =================================================================== --- test/SemaObjC/unguarded-availability.m +++ test/SemaObjC/unguarded-availability.m @@ -63,7 +63,7 @@ #ifdef OBJCPP // expected-note@+2 {{marked partial here}} #endif -typedef int int_10_12 AVAILABLE_10_12; // expected-note 3 {{'int_10_12' has been explicitly marked partial here}} +typedef int int_10_12 AVAILABLE_10_12; // expected-note 2 {{'int_10_12' has been explicitly marked partial here}} void use_typedef() { int_10_11 x; // expected-warning{{'int_10_11' is only available on macOS 10.11 or newer}} expected-note{{enclose 'int_10_11' in an @available check to silence this warning}} @@ -127,8 +127,7 @@ void test_params(int_10_12 x); // expected-warning {{'int_10_12' is partial: introduced in macOS 10.12}} expected-note{{redeclare}} -// FIXME: This should be fine! -void test_params2(int_10_12 x) AVAILABLE_10_12; // expected-warning {{'int_10_12' is partial: introduced in macOS 10.12}} expected-note{{redeclare}} +void test_params2(int_10_12 x) AVAILABLE_10_12; // no warn #ifdef OBJCPP