@@ -6929,16 +6929,42 @@ shouldDiagnoseAvailabilityByDefault(const ASTContext &Context,
6929
6929
DeclVersion >= ForceAvailabilityFromVersion;
6930
6930
}
6931
6931
6932
+ static NamedDecl *findEnclosingDeclToAnnotate (Decl *OrigCtx) {
6933
+ for (Decl *Ctx = OrigCtx; Ctx;
6934
+ Ctx = cast_or_null<Decl>(Ctx->getDeclContext ())) {
6935
+ if (isa<TagDecl>(Ctx) || isa<FunctionDecl>(Ctx) || isa<ObjCMethodDecl>(Ctx))
6936
+ return cast<NamedDecl>(Ctx);
6937
+ if (auto *CD = dyn_cast<ObjCContainerDecl>(Ctx)) {
6938
+ if (auto *Imp = dyn_cast<ObjCImplDecl>(Ctx))
6939
+ return Imp->getClassInterface ();
6940
+ return CD;
6941
+ }
6942
+ }
6943
+
6944
+ return dyn_cast<NamedDecl>(OrigCtx);
6945
+ }
6946
+
6947
+ // / Actually emit an availability diagnostic for a reference to an unavailable
6948
+ // / decl.
6949
+ // /
6950
+ // / \param Ctx The context that the reference occurred in
6951
+ // / \param ReferringDecl The exact declaration that was referenced.
6952
+ // / \param OffendingDecl A related decl to \c ReferringDecl that has an
6953
+ // / availability attribute corrisponding to \c K attached to it. Note that this
6954
+ // / may not be the same as ReferringDecl, i.e. if an EnumDecl is annotated and
6955
+ // / we refer to a member EnumConstantDecl, ReferringDecl is the EnumConstantDecl
6956
+ // / and OffendingDecl is the EnumDecl.
6932
6957
static void DoEmitAvailabilityWarning (Sema &S, AvailabilityResult K,
6933
- Decl *Ctx, const NamedDecl *D,
6958
+ Decl *Ctx, const NamedDecl *ReferringDecl,
6959
+ const NamedDecl *OffendingDecl,
6934
6960
StringRef Message, SourceLocation Loc,
6935
6961
const ObjCInterfaceDecl *UnknownObjCClass,
6936
6962
const ObjCPropertyDecl *ObjCProperty,
6937
6963
bool ObjCPropertyAccess) {
6938
6964
// Diagnostics for deprecated or unavailable.
6939
6965
unsigned diag, diag_message, diag_fwdclass_message;
6940
6966
unsigned diag_available_here = diag::note_availability_specified_here;
6941
- SourceLocation NoteLocation = D ->getLocation ();
6967
+ SourceLocation NoteLocation = OffendingDecl ->getLocation ();
6942
6968
6943
6969
// Matches 'diag::note_property_attribute' options.
6944
6970
unsigned property_note_select;
@@ -6947,7 +6973,7 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
6947
6973
unsigned available_here_select_kind;
6948
6974
6949
6975
VersionTuple DeclVersion;
6950
- if (const AvailabilityAttr *AA = getAttrForPlatform (S.Context , D ))
6976
+ if (const AvailabilityAttr *AA = getAttrForPlatform (S.Context , OffendingDecl ))
6951
6977
DeclVersion = AA->getIntroduced ();
6952
6978
6953
6979
if (!ShouldDiagnoseAvailabilityInContext (S, K, DeclVersion, Ctx))
@@ -6961,7 +6987,7 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
6961
6987
diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
6962
6988
property_note_select = /* deprecated */ 0 ;
6963
6989
available_here_select_kind = /* deprecated */ 2 ;
6964
- if (const auto *attr = D ->getAttr <DeprecatedAttr>())
6990
+ if (const auto *attr = OffendingDecl ->getAttr <DeprecatedAttr>())
6965
6991
NoteLocation = attr->getLocation ();
6966
6992
break ;
6967
6993
@@ -6973,13 +6999,14 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
6973
6999
property_note_select = /* unavailable */ 1 ;
6974
7000
available_here_select_kind = /* unavailable */ 0 ;
6975
7001
6976
- if (auto attr = D ->getAttr <UnavailableAttr>()) {
7002
+ if (auto attr = OffendingDecl ->getAttr <UnavailableAttr>()) {
6977
7003
if (attr->isImplicit () && attr->getImplicitReason ()) {
6978
7004
// Most of these failures are due to extra restrictions in ARC;
6979
7005
// reflect that in the primary diagnostic when applicable.
6980
7006
auto flagARCError = [&] {
6981
7007
if (S.getLangOpts ().ObjCAutoRefCount &&
6982
- S.getSourceManager ().isInSystemHeader (D->getLocation ()))
7008
+ S.getSourceManager ().isInSystemHeader (
7009
+ OffendingDecl->getLocation ()))
6983
7010
diag = diag::err_unavailable_in_arc;
6984
7011
};
6985
7012
@@ -7022,7 +7049,8 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
7022
7049
// not specified for deployment targets >= to iOS 11 or equivalent or
7023
7050
// for declarations that were introduced in iOS 11 (macOS 10.13, ...) or
7024
7051
// later.
7025
- const AvailabilityAttr *AA = getAttrForPlatform (S.getASTContext (), D);
7052
+ const AvailabilityAttr *AA =
7053
+ getAttrForPlatform (S.getASTContext (), OffendingDecl);
7026
7054
VersionTuple Introduced = AA->getIntroduced ();
7027
7055
bool NewWarning = shouldDiagnoseAvailabilityByDefault (
7028
7056
S.Context , S.Context .getTargetInfo ().getPlatformMinVersion (),
@@ -7045,9 +7073,9 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
7045
7073
CharSourceRange UseRange;
7046
7074
StringRef Replacement;
7047
7075
if (K == AR_Deprecated) {
7048
- if (auto attr = D ->getAttr <DeprecatedAttr>())
7076
+ if (auto attr = OffendingDecl ->getAttr <DeprecatedAttr>())
7049
7077
Replacement = attr->getReplacement ();
7050
- if (auto attr = getAttrForPlatform (S.Context , D ))
7078
+ if (auto attr = getAttrForPlatform (S.Context , OffendingDecl ))
7051
7079
Replacement = attr->getReplacement ();
7052
7080
7053
7081
if (!Replacement.empty ())
@@ -7056,49 +7084,58 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
7056
7084
}
7057
7085
7058
7086
if (!Message.empty ()) {
7059
- S.Diag (Loc, diag_message) << D << Message
7087
+ S.Diag (Loc, diag_message) << ReferringDecl << Message
7060
7088
<< (UseRange.isValid () ?
7061
7089
FixItHint::CreateReplacement (UseRange, Replacement) : FixItHint ());
7062
7090
if (ObjCProperty)
7063
7091
S.Diag (ObjCProperty->getLocation (), diag::note_property_attribute)
7064
7092
<< ObjCProperty->getDeclName () << property_note_select;
7065
7093
} else if (!UnknownObjCClass) {
7066
- S.Diag (Loc, diag) << D
7094
+ S.Diag (Loc, diag) << ReferringDecl
7067
7095
<< (UseRange.isValid () ?
7068
7096
FixItHint::CreateReplacement (UseRange, Replacement) : FixItHint ());
7069
7097
if (ObjCProperty)
7070
7098
S.Diag (ObjCProperty->getLocation (), diag::note_property_attribute)
7071
7099
<< ObjCProperty->getDeclName () << property_note_select;
7072
7100
} else {
7073
- S.Diag (Loc, diag_fwdclass_message) << D
7101
+ S.Diag (Loc, diag_fwdclass_message) << ReferringDecl
7074
7102
<< (UseRange.isValid () ?
7075
7103
FixItHint::CreateReplacement (UseRange, Replacement) : FixItHint ());
7076
7104
S.Diag (UnknownObjCClass->getLocation (), diag::note_forward_class);
7077
7105
}
7078
7106
7079
7107
// The declaration can have multiple availability attributes, we are looking
7080
7108
// at one of them.
7081
- const AvailabilityAttr *A = getAttrForPlatform (S.Context , D );
7109
+ const AvailabilityAttr *A = getAttrForPlatform (S.Context , OffendingDecl );
7082
7110
if (A && A->isInherited ()) {
7083
- for (const Decl *Redecl = D ->getMostRecentDecl (); Redecl;
7111
+ for (const Decl *Redecl = OffendingDecl ->getMostRecentDecl (); Redecl;
7084
7112
Redecl = Redecl->getPreviousDecl ()) {
7085
7113
const AvailabilityAttr *AForRedecl = getAttrForPlatform (S.Context ,
7086
7114
Redecl);
7087
7115
if (AForRedecl && !AForRedecl->isInherited ()) {
7088
7116
// If D is a declaration with inherited attributes, the note should
7089
7117
// point to the declaration with actual attributes.
7090
- S.Diag (Redecl->getLocation (), diag_available_here) << D
7118
+ S.Diag (Redecl->getLocation (), diag_available_here) << OffendingDecl
7091
7119
<< available_here_select_kind;
7092
7120
break ;
7093
7121
}
7094
7122
}
7095
7123
}
7096
7124
else
7097
7125
S.Diag (NoteLocation, diag_available_here)
7098
- << D << available_here_select_kind;
7126
+ << OffendingDecl << available_here_select_kind;
7099
7127
7100
7128
if (K == AR_NotYetIntroduced)
7101
- S.Diag (Loc, diag::note_partial_availability_silence) << D;
7129
+ if (const auto *Enclosing = findEnclosingDeclToAnnotate (Ctx)) {
7130
+ if (auto *TD = dyn_cast<TagDecl>(Enclosing))
7131
+ if (TD->getDeclName ().isEmpty ()) {
7132
+ S.Diag (TD->getLocation (), diag::note_partial_availability_silence)
7133
+ << /* Anonymous*/ 1 << TD->getKindName ();
7134
+ return ;
7135
+ }
7136
+ S.Diag (Enclosing->getLocation (), diag::note_partial_availability_silence)
7137
+ << /* Named*/ 0 << Enclosing;
7138
+ }
7102
7139
}
7103
7140
7104
7141
static void handleDelayedAvailabilityCheck (Sema &S, DelayedDiagnostic &DD,
@@ -7108,9 +7145,9 @@ static void handleDelayedAvailabilityCheck(Sema &S, DelayedDiagnostic &DD,
7108
7145
7109
7146
DD.Triggered = true ;
7110
7147
DoEmitAvailabilityWarning (
7111
- S, DD.getAvailabilityResult (), Ctx, DD.getAvailabilityDecl (),
7112
- DD.getAvailabilityMessage (), DD.Loc , DD.getUnknownObjCClass () ,
7113
- DD.getObjCProperty (), false );
7148
+ S, DD.getAvailabilityResult (), Ctx, DD.getAvailabilityReferringDecl (),
7149
+ DD.getAvailabilityOffendingDecl (), DD.getAvailabilityMessage () , DD.Loc ,
7150
+ DD.getUnknownObjCClass (), DD. getObjCProperty (), false );
7114
7151
}
7115
7152
7116
7153
void Sema::PopParsingDeclaration (ParsingDeclState state, Decl *decl) {
@@ -7169,22 +7206,25 @@ void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
7169
7206
}
7170
7207
7171
7208
void Sema::EmitAvailabilityWarning (AvailabilityResult AR,
7172
- NamedDecl *D, StringRef Message,
7173
- SourceLocation Loc,
7209
+ const NamedDecl *ReferringDecl,
7210
+ const NamedDecl *OffendingDecl,
7211
+ StringRef Message, SourceLocation Loc,
7174
7212
const ObjCInterfaceDecl *UnknownObjCClass,
7175
- const ObjCPropertyDecl *ObjCProperty,
7213
+ const ObjCPropertyDecl *ObjCProperty,
7176
7214
bool ObjCPropertyAccess) {
7177
7215
// Delay if we're currently parsing a declaration.
7178
7216
if (DelayedDiagnostics.shouldDelayDiagnostics ()) {
7179
- DelayedDiagnostics.add (DelayedDiagnostic::makeAvailability (
7180
- AR, Loc, D, UnknownObjCClass, ObjCProperty, Message,
7181
- ObjCPropertyAccess));
7217
+ DelayedDiagnostics.add (
7218
+ DelayedDiagnostic::makeAvailability (
7219
+ AR, Loc, ReferringDecl, OffendingDecl, UnknownObjCClass,
7220
+ ObjCProperty, Message, ObjCPropertyAccess));
7182
7221
return ;
7183
7222
}
7184
7223
7185
7224
Decl *Ctx = cast<Decl>(getCurLexicalContext ());
7186
- DoEmitAvailabilityWarning (*this , AR, Ctx, D, Message, Loc, UnknownObjCClass,
7187
- ObjCProperty, ObjCPropertyAccess);
7225
+ DoEmitAvailabilityWarning (*this , AR, Ctx, ReferringDecl, OffendingDecl,
7226
+ Message, Loc, UnknownObjCClass, ObjCProperty,
7227
+ ObjCPropertyAccess);
7188
7228
}
7189
7229
7190
7230
namespace {
@@ -7336,19 +7376,21 @@ class DiagnoseUnguardedAvailability
7336
7376
7337
7377
void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability (
7338
7378
NamedDecl *D, SourceRange Range) {
7339
-
7340
- VersionTuple ContextVersion = AvailabilityStack.back ();
7341
- if (AvailabilityResult Result =
7342
- SemaRef.ShouldDiagnoseAvailabilityOfDecl (D, nullptr )) {
7379
+ AvailabilityResult Result;
7380
+ const NamedDecl *OffendingDecl;
7381
+ std::tie (Result, OffendingDecl) =
7382
+ SemaRef.ShouldDiagnoseAvailabilityOfDecl (D, nullptr );
7383
+ if (Result != AR_Available) {
7343
7384
// All other diagnostic kinds have already been handled in
7344
7385
// DiagnoseAvailabilityOfDecl.
7345
7386
if (Result != AR_NotYetIntroduced)
7346
7387
return ;
7347
7388
7348
- const AvailabilityAttr *AA = getAttrForPlatform (SemaRef.getASTContext (), D);
7389
+ const AvailabilityAttr *AA =
7390
+ getAttrForPlatform (SemaRef.getASTContext (), OffendingDecl);
7349
7391
VersionTuple Introduced = AA->getIntroduced ();
7350
7392
7351
- if (ContextVersion >= Introduced)
7393
+ if (AvailabilityStack. back () >= Introduced)
7352
7394
return ;
7353
7395
7354
7396
// If the context of this function is less available than D, we should not
@@ -7373,8 +7415,9 @@ void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
7373
7415
SemaRef.getASTContext ().getTargetInfo ().getPlatformName ())
7374
7416
<< Introduced.getAsString ();
7375
7417
7376
- SemaRef.Diag (D->getLocation (), diag::note_availability_specified_here)
7377
- << D << /* partial */ 3 ;
7418
+ SemaRef.Diag (OffendingDecl->getLocation (),
7419
+ diag::note_availability_specified_here)
7420
+ << OffendingDecl << /* partial */ 3 ;
7378
7421
7379
7422
auto FixitDiag =
7380
7423
SemaRef.Diag (Range.getBegin (), diag::note_unguarded_available_silence)
0 commit comments