@@ -252,7 +252,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
252
252
253
253
void visitImplementationOnlyAttr (ImplementationOnlyAttr *attr);
254
254
void visitNonEphemeralAttr (NonEphemeralAttr *attr);
255
- void checkOriginalDefinedInAttrs (ArrayRef<OriginallyDefinedInAttr*> Attrs);
255
+ void checkOriginalDefinedInAttrs (Decl *D, ArrayRef<OriginallyDefinedInAttr*> Attrs);
256
256
};
257
257
} // end anonymous namespace
258
258
@@ -1070,7 +1070,7 @@ void TypeChecker::checkDeclAttributes(Decl *D) {
1070
1070
else
1071
1071
Checker.diagnoseAndRemoveAttr (attr, diag::invalid_decl_attribute, attr);
1072
1072
}
1073
- Checker.checkOriginalDefinedInAttrs (ODIAttrs);
1073
+ Checker.checkOriginalDefinedInAttrs (D, ODIAttrs);
1074
1074
}
1075
1075
1076
1076
// / Returns true if the given method is an valid implementation of a
@@ -2631,21 +2631,48 @@ void TypeChecker::checkParameterAttributes(ParameterList *params) {
2631
2631
}
2632
2632
}
2633
2633
2634
- void
2635
- AttributeChecker::checkOriginalDefinedInAttrs (
2634
+ void AttributeChecker::checkOriginalDefinedInAttrs (Decl *D,
2636
2635
ArrayRef<OriginallyDefinedInAttr*> Attrs) {
2637
- llvm::SmallSet<PlatformKind, 4 > AllPlatforms;
2636
+ if (Attrs.empty ())
2637
+ return ;
2638
+ auto &Ctx = D->getASTContext ();
2639
+ OriginallyDefinedInAttr* theAttr = nullptr ;
2638
2640
// Attrs are in the reverse order of the source order. We need to visit them
2639
2641
// in source order to diagnose the later attribute.
2640
- for (auto It = Attrs. rbegin (), End = Attrs. rend (); It != End; ++ It ) {
2641
- auto * Attr = *It;
2642
- auto CurPlat = Attr-> Platform ;
2643
- if (!AllPlatforms. insert (CurPlat). second ) {
2642
+ for (auto *Attr: Attrs) {
2643
+ if (! Attr-> isActivePlatform (Ctx))
2644
+ continue ;
2645
+ if (theAttr ) {
2644
2646
// Only one version number is allowed for one platform name.
2645
- diagnose (Attr ->AtLoc , diag::originally_defined_in_dupe_platform,
2647
+ diagnose (theAttr ->AtLoc , diag::originally_defined_in_dupe_platform,
2646
2648
platformString (Attr->Platform ));
2649
+ return ;
2650
+ } else {
2651
+ theAttr = Attr;
2647
2652
}
2648
2653
}
2654
+ if (!theAttr)
2655
+ return ;
2656
+ assert (theAttr);
2657
+ static StringRef AttrName = " _originallyDefinedIn" ;
2658
+ auto AtLoc = theAttr->AtLoc ;
2659
+ if (!D->getDeclContext ()->isModuleScopeContext ()) {
2660
+ diagnose (AtLoc, diag::originally_definedin_topleve_decl, AttrName);
2661
+ return ;
2662
+ }
2663
+ auto AvailRange = AvailabilityInference::availableRange (D, Ctx);
2664
+ if (!AvailRange.getOSVersion ().hasLowerEndpoint ()) {
2665
+ diagnose (AtLoc, diag::originally_definedin_need_available,
2666
+ AttrName);
2667
+ return ;
2668
+ }
2669
+ auto AvailBegin = AvailRange.getOSVersion ().getLowerEndpoint ();
2670
+ if (AvailBegin >= theAttr->MovedVersion ) {
2671
+ diagnose (AtLoc,
2672
+ diag::originally_definedin_must_after_available_version,
2673
+ AttrName);
2674
+ return ;
2675
+ }
2649
2676
}
2650
2677
2651
2678
Type TypeChecker::checkReferenceOwnershipAttr (VarDecl *var, Type type,
0 commit comments