diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 27 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 47 |
2 files changed, 49 insertions, 25 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 571c9baa048..a359ef49311 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2175,14 +2175,15 @@ static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) { } static bool mergeDeclAttribute(Sema &S, NamedDecl *D, - const InheritableAttr *Attr, bool Override) { + const InheritableAttr *Attr, + Sema::AvailabilityMergeKind AMK) { InheritableAttr *NewAttr = nullptr; unsigned AttrSpellingListIndex = Attr->getSpellingListIndex(); if (const auto *AA = dyn_cast<AvailabilityAttr>(Attr)) NewAttr = S.mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(), AA->getIntroduced(), AA->getDeprecated(), AA->getObsoleted(), AA->getUnavailable(), - AA->getMessage(), Override, + AA->getMessage(), AMK, AttrSpellingListIndex); else if (const auto *VA = dyn_cast<VisibilityAttr>(Attr)) NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), @@ -2219,7 +2220,11 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, // AlignedAttrs are handled separately, because we need to handle all // such attributes on a declaration at the same time. NewAttr = nullptr; - else if (isa<DeprecatedAttr>(Attr) && Override) + else if (isa<DeprecatedAttr>(Attr) && + (AMK == Sema::AMK_Override || + AMK == Sema::AMK_ProtocolImplementation)) + NewAttr = nullptr; + else if (isa<UnavailableAttr>(Attr) && AMK == Sema::AMK_ProtocolImplementation) NewAttr = nullptr; else if (Attr->duplicatesAllowed() || !DeclHasAttr(D, Attr)) NewAttr = cast<InheritableAttr>(Attr->clone(S.Context)); @@ -2366,8 +2371,8 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, if (!foundAny) New->setAttrs(AttrVec()); for (auto *I : Old->specific_attrs<InheritableAttr>()) { - bool Override = false; // Ignore deprecated/unavailable/availability attributes if requested. + AvailabilityMergeKind LocalAMK = AMK_None; if (isa<DeprecatedAttr>(I) || isa<UnavailableAttr>(I) || isa<AvailabilityAttr>(I)) { @@ -2376,10 +2381,9 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, continue; case AMK_Redeclaration: - break; - case AMK_Override: - Override = true; + case AMK_ProtocolImplementation: + LocalAMK = AMK; break; } } @@ -2388,7 +2392,7 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, if (isa<UsedAttr>(I)) continue; - if (mergeDeclAttribute(*this, New, I, Override)) + if (mergeDeclAttribute(*this, New, I, LocalAMK)) foundAny = true; } @@ -3156,8 +3160,11 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod, // Merge the attributes, including deprecated/unavailable AvailabilityMergeKind MergeKind = - isa<ObjCImplDecl>(newMethod->getDeclContext()) ? AMK_Redeclaration - : AMK_Override; + isa<ObjCProtocolDecl>(oldMethod->getDeclContext()) + ? AMK_ProtocolImplementation + : isa<ObjCImplDecl>(newMethod->getDeclContext()) ? AMK_Redeclaration + : AMK_Override; + mergeDeclAttributes(newMethod, oldMethod, MergeKind); // Merge attributes from the parameters. diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 8218c20696d..3cf9567889f 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1821,12 +1821,24 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, VersionTuple Obsoleted, bool IsUnavailable, StringRef Message, - bool Override, + AvailabilityMergeKind AMK, unsigned AttrSpellingListIndex) { VersionTuple MergedIntroduced = Introduced; VersionTuple MergedDeprecated = Deprecated; VersionTuple MergedObsoleted = Obsoleted; bool FoundAny = false; + bool OverrideOrImpl = false; + switch (AMK) { + case AMK_None: + case AMK_Redeclaration: + OverrideOrImpl = false; + break; + + case AMK_Override: + case AMK_ProtocolImplementation: + OverrideOrImpl = true; + break; + } if (D->hasAttrs()) { AttrVec &Attrs = D->getAttrs(); @@ -1849,24 +1861,24 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, VersionTuple OldObsoleted = OldAA->getObsoleted(); bool OldIsUnavailable = OldAA->getUnavailable(); - if (!versionsMatch(OldIntroduced, Introduced, Override) || - !versionsMatch(Deprecated, OldDeprecated, Override) || - !versionsMatch(Obsoleted, OldObsoleted, Override) || + if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl) || + !versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl) || + !versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl) || !(OldIsUnavailable == IsUnavailable || - (Override && !OldIsUnavailable && IsUnavailable))) { - if (Override) { + (OverrideOrImpl && !OldIsUnavailable && IsUnavailable))) { + if (OverrideOrImpl) { int Which = -1; VersionTuple FirstVersion; VersionTuple SecondVersion; - if (!versionsMatch(OldIntroduced, Introduced, Override)) { + if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl)) { Which = 0; FirstVersion = OldIntroduced; SecondVersion = Introduced; - } else if (!versionsMatch(Deprecated, OldDeprecated, Override)) { + } else if (!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)) { Which = 1; FirstVersion = Deprecated; SecondVersion = OldDeprecated; - } else if (!versionsMatch(Obsoleted, OldObsoleted, Override)) { + } else if (!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)) { Which = 2; FirstVersion = Obsoleted; SecondVersion = OldObsoleted; @@ -1875,15 +1887,20 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, if (Which == -1) { Diag(OldAA->getLocation(), diag::warn_mismatched_availability_override_unavail) - << AvailabilityAttr::getPrettyPlatformName(Platform->getName()); + << AvailabilityAttr::getPrettyPlatformName(Platform->getName()) + << (AMK == AMK_Override); } else { Diag(OldAA->getLocation(), diag::warn_mismatched_availability_override) << Which << AvailabilityAttr::getPrettyPlatformName(Platform->getName()) - << FirstVersion.getAsString() << SecondVersion.getAsString(); + << FirstVersion.getAsString() << SecondVersion.getAsString() + << (AMK == AMK_Override); } - Diag(Range.getBegin(), diag::note_overridden_method); + if (AMK == AMK_Override) + Diag(Range.getBegin(), diag::note_overridden_method); + else + Diag(Range.getBegin(), diag::note_protocol_method); } else { Diag(OldAA->getLocation(), diag::warn_mismatched_availability); Diag(Range.getBegin(), diag::note_previous_attribute); @@ -1926,11 +1943,11 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, MergedObsoleted == Obsoleted) return nullptr; - // Only create a new attribute if !Override, but we want to do + // Only create a new attribute if !OverrideOrImpl, but we want to do // the checking. if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced, MergedDeprecated, MergedObsoleted) && - !Override) { + !OverrideOrImpl) { return ::new (Context) AvailabilityAttr(Range, Context, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable, Message, @@ -1971,7 +1988,7 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, Deprecated.Version, Obsoleted.Version, IsUnavailable, Str, - /*Override=*/false, + Sema::AMK_None, Index); if (NewAttr) D->addAttr(NewAttr); |