Skip to content

Commit 0344fcd

Browse files
hypian-twilightcoder
authored andcommitted
Implement Sema iosmac support
rdar://38885683 apple-llvm-split-commit: 40aab84d831ddfc623de95fbbca06de6f0baf0a6 apple-llvm-split-dir: clang/
1 parent 519a53e commit 0344fcd

33 files changed

Lines changed: 1366 additions & 471 deletions

‎clang/include/clang/AST/DeclBase.h‎

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,13 @@ class alignas(8) Decl {
758758
VersionTuple EnclosingVersion = VersionTuple(),
759759
StringRef *RealizedPlatform = nullptr) const;
760760

761+
/// Determine the availability of the given declaration for the given
762+
/// target platform and its minimum version.
763+
AvailabilityResult getAvailability(StringRef Platform,
764+
const VersionTuple &PlatformMinVersion,
765+
std::string *Message = nullptr,
766+
StringRef *RealizedPlatform = nullptr) const;
767+
761768
/// Retrieve the version of the target platform in which this
762769
/// declaration was introduced.
763770
///
@@ -766,14 +773,13 @@ class alignas(8) Decl {
766773
/// attribute otherwise.
767774
VersionTuple getVersionIntroduced() const;
768775

769-
/// Determine whether this declaration is marked 'deprecated'.
776+
/// \brief Determine whether this declaration is marked 'deprecated' in any
777+
/// target platform that we're compiling for.
770778
///
771779
/// \param Message If non-NULL and the declaration is deprecated,
772780
/// this will be set to the message describing why the declaration
773781
/// was deprecated (which may be empty).
774-
bool isDeprecated(std::string *Message = nullptr) const {
775-
return getAvailability(Message) == AR_Deprecated;
776-
}
782+
bool isDeprecatedInAnyTargetPlatform(std::string *Message = nullptr) const;
777783

778784
/// Determine whether this declaration is marked 'unavailable'.
779785
///
@@ -784,6 +790,10 @@ class alignas(8) Decl {
784790
return getAvailability(Message) == AR_Unavailable;
785791
}
786792

793+
/// \brief Determine whether this declaration is marked 'deprecated' for
794+
/// all target platforms that we're compiling for.
795+
bool isUnavailabledForAllTargetPlatforms() const;
796+
787797
/// Determine whether this is a weak-imported symbol.
788798
///
789799
/// Weak-imported symbols are typically marked with the

‎clang/include/clang/AST/ExprObjC.h‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,13 +1736,18 @@ class ObjCAvailabilityCheckExpr : public Expr {
17361736
friend class ASTStmtReader;
17371737

17381738
VersionTuple VersionToCheck;
1739+
VersionTuple VariantVersionToCheck;
17391740
SourceLocation AtLoc, RParen;
17401741

17411742
public:
1742-
ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc,
1743-
SourceLocation RParen, QualType Ty)
1743+
ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck,
1744+
VersionTuple VariantVersionToCheck,
1745+
SourceLocation AtLoc, SourceLocation RParen,
1746+
QualType Ty)
17441747
: Expr(ObjCAvailabilityCheckExprClass, Ty, VK_PRValue, OK_Ordinary),
1745-
VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {
1748+
VersionToCheck(VersionToCheck),
1749+
VariantVersionToCheck(VariantVersionToCheck), AtLoc(AtLoc),
1750+
RParen(RParen) {
17461751
setDependence(ExprDependence::None);
17471752
}
17481753

@@ -1757,6 +1762,10 @@ class ObjCAvailabilityCheckExpr : public Expr {
17571762
bool hasVersion() const { return !VersionToCheck.empty(); }
17581763
VersionTuple getVersion() const { return VersionToCheck; }
17591764

1765+
bool hasVariantVersion() const { return !VariantVersionToCheck.empty(); }
1766+
1767+
VersionTuple getVariantVersion() const { return VariantVersionToCheck; }
1768+
17601769
child_range children() {
17611770
return child_range(child_iterator(), child_iterator());
17621771
}

‎clang/include/clang/Basic/DiagnosticSemaKinds.td‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4300,6 +4300,9 @@ def warn_unguarded_availability_new :
43004300
def warn_unguarded_availability_unavailable_new :
43014301
Warning<warn_unguarded_availability_unavailable.Summary>,
43024302
InGroup<UnguardedAvailabilityNew>;
4303+
def warn_zippered_unguarded_availability :
4304+
Warning<"%0 is only available on %1 %2 and %3 %4 or newer">,
4305+
InGroup<UnguardedAvailabilityNew>;
43034306
def note_decl_unguarded_availability_silence : Note<
43044307
"annotate %select{%1|anonymous %1}0 with an availability attribute to silence this warning">;
43054308
def note_unguarded_available_silence : Note<

‎clang/include/clang/Basic/TargetInfo.h‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ class TargetInfo : public TransferrableTargetInfo,
260260

261261
mutable StringRef PlatformName;
262262
mutable VersionTuple PlatformMinVersion;
263+
mutable StringRef TargetVariantPlatform;
264+
mutable VersionTuple TargetVariantPlatformMinVersion;
263265

264266
LLVM_PREFERRED_TYPE(bool)
265267
unsigned HasAlignMac68kSupport : 1;
@@ -1737,6 +1739,28 @@ class TargetInfo : public TransferrableTargetInfo,
17371739
/// which the program should be compiled.
17381740
VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; }
17391741

1742+
/// Returns true when are building for an auxillary target variant platform.
1743+
bool hasTargetVariantPlatform() const {
1744+
return !TargetVariantPlatform.empty();
1745+
}
1746+
1747+
/// Retrieve the name of the target variant platform as it is used in the
1748+
/// availability attribute.
1749+
StringRef getTargetVariantPlatform() const {
1750+
assert(hasTargetVariantPlatform() &&
1751+
"no target variant platform specified");
1752+
return TargetVariantPlatform;
1753+
}
1754+
1755+
/// Retrieve the minimum desired deployment version of the target variant
1756+
/// platform,
1757+
/// for which the program should be compiled.
1758+
VersionTuple getTargetVariantPlatformMinVersion() const {
1759+
assert(hasTargetVariantPlatform() &&
1760+
"no target variant platform specified");
1761+
return TargetVariantPlatformMinVersion;
1762+
}
1763+
17401764
bool isBigEndian() const { return BigEndian; }
17411765
bool isLittleEndian() const { return !BigEndian; }
17421766

‎clang/include/clang/Sema/DelayedDiagnostic.h‎

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,13 @@ class DelayedDiagnostic {
134134

135135
void Destroy();
136136

137-
static DelayedDiagnostic makeAvailability(AvailabilityResult AR,
138-
ArrayRef<SourceLocation> Locs,
139-
const NamedDecl *ReferringDecl,
140-
const NamedDecl *OffendingDecl,
141-
const ObjCInterfaceDecl *UnknownObjCClass,
142-
const ObjCPropertyDecl *ObjCProperty,
143-
StringRef Msg,
144-
bool ObjCPropertyAccess);
137+
static DelayedDiagnostic
138+
makeAvailability(AvailabilityResult AR, ArrayRef<SourceLocation> Locs,
139+
const NamedDecl *ReferringDecl,
140+
const NamedDecl *OffendingDecl,
141+
const ObjCInterfaceDecl *UnknownObjCClass,
142+
const ObjCPropertyDecl *ObjCProperty, StringRef Msg,
143+
bool ObjCPropertyAccess, bool IsTargetVariantPlatform);
145144

146145
static DelayedDiagnostic makeAccess(SourceLocation Loc,
147146
const AccessedEntity &Entity) {
@@ -232,6 +231,10 @@ class DelayedDiagnostic {
232231
return AvailabilityData.ObjCPropertyAccess;
233232
}
234233

234+
bool isTargetVariantPlatform() const {
235+
return AvailabilityData.IsTargetVariantPlatform;
236+
}
237+
235238
private:
236239
struct AD {
237240
const NamedDecl *ReferringDecl;
@@ -244,6 +247,7 @@ class DelayedDiagnostic {
244247
size_t NumSelectorLocs;
245248
AvailabilityResult AR;
246249
bool ObjCPropertyAccess;
250+
bool IsTargetVariantPlatform;
247251
};
248252

249253
struct FTD {

‎clang/include/clang/Sema/Sema.h‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2466,6 +2466,10 @@ class Sema final : public SemaBase {
24662466

24672467
void handleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
24682468

2469+
void handleZipperedDelayedAvailabilityCheck(
2470+
sema::DelayedDiagnostic &DD, sema::DelayedDiagnostic &VariantDD,
2471+
Decl *Ctx);
2472+
24692473
/// Retrieve the current function, if any, that should be analyzed for
24702474
/// potential availability violations.
24712475
sema::FunctionScopeInfo *getCurFunctionAvailabilityContext();
@@ -2479,7 +2483,9 @@ class Sema final : public SemaBase {
24792483
void DiagnoseAvailabilityOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs);
24802484

24812485
std::pair<AvailabilityResult, const NamedDecl *>
2482-
ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message,
2486+
ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, StringRef Platform,
2487+
const VersionTuple &PlatformVersion,
2488+
std::string *Message,
24832489
ObjCInterfaceDecl *ClassReceiver);
24842490
///@}
24852491

‎clang/lib/AST/DeclBase.cpp‎

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -674,15 +674,12 @@ static StringRef getRealizedPlatform(const AvailabilityAttr *A,
674674
static AvailabilityResult CheckAvailability(ASTContext &Context,
675675
const AvailabilityAttr *A,
676676
std::string *Message,
677+
StringRef TargetPlatform,
677678
VersionTuple EnclosingVersion) {
678-
if (EnclosingVersion.empty())
679-
EnclosingVersion = Context.getTargetInfo().getPlatformMinVersion();
680-
681679
if (EnclosingVersion.empty())
682680
return AR_Available;
683681

684682
StringRef ActualPlatform = A->getPlatform()->getName();
685-
StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
686683

687684
// Match the platform name.
688685
if (getRealizedPlatform(A, Context) != TargetPlatform)
@@ -779,9 +776,21 @@ static AvailabilityResult CheckAvailability(ASTContext &Context,
779776
AvailabilityResult Decl::getAvailability(std::string *Message,
780777
VersionTuple EnclosingVersion,
781778
StringRef *RealizedPlatform) const {
779+
const TargetInfo &TI = getASTContext().getTargetInfo();
780+
return getAvailability(TI.getPlatformName(),
781+
EnclosingVersion.empty() ? TI.getPlatformMinVersion()
782+
: EnclosingVersion,
783+
Message, RealizedPlatform);
784+
}
785+
786+
AvailabilityResult Decl::getAvailability(StringRef Platform,
787+
const VersionTuple &PlatformMinVersion,
788+
std::string *Message,
789+
StringRef *RealizedPlatform) const {
782790
if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this))
783-
return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,
784-
RealizedPlatform);
791+
return FTD->getTemplatedDecl()->getAvailability(
792+
Platform, PlatformMinVersion, Message, RealizedPlatform);
793+
785794

786795
AvailabilityResult Result = AR_Available;
787796
std::string ResultMessage;
@@ -806,8 +815,8 @@ AvailabilityResult Decl::getAvailability(std::string *Message,
806815

807816
if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
808817
Availability = Availability->getEffectiveAttr();
809-
AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,
810-
Message, EnclosingVersion);
818+
AvailabilityResult AR = CheckAvailability(
819+
getASTContext(), Availability, Message, Platform, PlatformMinVersion);
811820

812821
if (AR == AR_Unavailable) {
813822
if (RealizedPlatform)
@@ -844,6 +853,26 @@ VersionTuple Decl::getVersionIntroduced() const {
844853
return {};
845854
}
846855

856+
bool Decl::isDeprecatedInAnyTargetPlatform(std::string *Message) const {
857+
const TargetInfo &TI = getASTContext().getTargetInfo();
858+
return getAvailability(TI.getPlatformName(), TI.getPlatformMinVersion()) ==
859+
AR_Deprecated ||
860+
(TI.hasTargetVariantPlatform() &&
861+
getAvailability(TI.getTargetVariantPlatform(),
862+
TI.getTargetVariantPlatformMinVersion()) ==
863+
AR_Deprecated);
864+
}
865+
866+
bool Decl::isUnavailabledForAllTargetPlatforms() const {
867+
const TargetInfo &TI = getASTContext().getTargetInfo();
868+
return getAvailability(TI.getPlatformName(), TI.getPlatformMinVersion()) ==
869+
AR_Unavailable &&
870+
(!getASTContext().getTargetInfo().hasTargetVariantPlatform() ||
871+
getAvailability(TI.getTargetVariantPlatform(),
872+
TI.getTargetVariantPlatformMinVersion()) ==
873+
AR_Unavailable);
874+
}
875+
847876
bool Decl::canBeWeakImported(bool &IsDefinition) const {
848877
IsDefinition = false;
849878

@@ -878,14 +907,21 @@ bool Decl::isWeakImported() const {
878907
if (!canBeWeakImported(IsDefinition))
879908
return false;
880909

910+
const TargetInfo &TI = getASTContext().getTargetInfo();
881911
for (const auto *A : getMostRecentDecl()->attrs()) {
882912
if (isa<WeakImportAttr>(A))
883913
return true;
884914

885915
if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
886916
Availability = Availability->getEffectiveAttr();
887917
if (CheckAvailability(getASTContext(), Availability, nullptr,
888-
VersionTuple()) == AR_NotYetIntroduced)
918+
TI.getPlatformName(), TI.getPlatformMinVersion()) ==
919+
AR_NotYetIntroduced ||
920+
(TI.hasTargetVariantPlatform() &&
921+
CheckAvailability(getASTContext(), Availability, nullptr,
922+
TI.getTargetVariantPlatform(),
923+
TI.getTargetVariantPlatformMinVersion()) ==
924+
AR_NotYetIntroduced))
889925
return true;
890926
}
891927
}

‎clang/lib/Basic/Targets/ARM.cpp‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1558,5 +1558,7 @@ DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
15581558
void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
15591559
const llvm::Triple &Triple,
15601560
MacroBuilder &Builder) const {
1561-
getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1561+
getDarwinDefines(Builder, Opts, Triple, /*TargetVariantTriple=*/"",
1562+
PlatformName, PlatformMinVersion, TargetVariantPlatform,
1563+
TargetVariantPlatformMinVersion);
15621564
}

‎clang/lib/Basic/Targets/OSTargets.cpp‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@ void getAppleMachODefines(MacroBuilder &Builder, const LangOptions &Opts,
5555
}
5656

5757
void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
58-
const llvm::Triple &Triple, StringRef &PlatformName,
59-
VersionTuple &PlatformMinVersion) {
58+
const llvm::Triple &Triple, StringRef TargetVariantTriple,
59+
StringRef &PlatformName, VersionTuple &PlatformMinVersion,
60+
StringRef &TargetVariantPlatformName,
61+
VersionTuple &TargetVariantPlatformMinVersion) {
6062
getAppleMachODefines(Builder, Opts, Triple);
6163

6264
// Darwin's libc doesn't have threads.h
@@ -67,6 +69,14 @@ void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
6769
if (Triple.isMacOSX()) {
6870
Triple.getMacOSXVersion(OsVersion);
6971
PlatformName = "macos";
72+
if (!TargetVariantTriple.empty()) {
73+
llvm::Triple TVT(TargetVariantTriple);
74+
if (TVT.getOS() == llvm::Triple::IOS &&
75+
TVT.getEnvironment() == llvm::Triple::MacABI) {
76+
TargetVariantPlatformName = "maccatalyst";
77+
TargetVariantPlatformMinVersion = TVT.getiOSVersion();
78+
}
79+
}
7080
} else {
7181
OsVersion = Triple.getOSVersion();
7282
PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());

‎clang/lib/Basic/Targets/OSTargets.h‎

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ void getAppleMachODefines(MacroBuilder &Builder, const LangOptions &Opts,
3838
const llvm::Triple &Triple);
3939

4040
void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
41-
const llvm::Triple &Triple, StringRef &PlatformName,
42-
VersionTuple &PlatformMinVersion);
41+
const llvm::Triple &Triple, StringRef TargetVariantTriple,
42+
StringRef &PlatformName, VersionTuple &PlatformMinVersion,
43+
StringRef &TargetVariantPlatformName,
44+
VersionTuple &TargetVariantPlatform);
4345

4446
template <typename Target>
4547
class LLVM_LIBRARY_VISIBILITY AppleMachOTargetInfo
@@ -77,8 +79,10 @@ class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo
7779
protected:
7880
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
7981
MacroBuilder &Builder) const override {
80-
getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
81-
this->PlatformMinVersion);
82+
getDarwinDefines(Builder, Opts, Triple, TargetVariantTriple,
83+
this->PlatformName, this->PlatformMinVersion,
84+
this->TargetVariantPlatform,
85+
this->TargetVariantPlatformMinVersion);
8286
}
8387

8488
public:
@@ -87,6 +91,7 @@ class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo
8791
// By default, no TLS, and we list permitted architecture/OS
8892
// combinations.
8993
this->TLSSupported = false;
94+
TargetVariantTriple = Opts.DarwinTargetVariantTriple;
9095

9196
if (Triple.isMacOSX())
9297
this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7);
@@ -185,6 +190,15 @@ class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo
185190
bool areDefaultedSMFStillPOD(const LangOptions &) const override {
186191
return false;
187192
}
193+
194+
/// Darwin does not support protected visibility. Darwin's "default"
195+
/// is very similar to ELF's "protected"; Darwin requires a "weak"
196+
/// attribute on declarations that can be dynamically replaced.
197+
bool hasProtectedVisibility() const override { return false; }
198+
199+
private:
200+
std::string TargetVariantTriple;
201+
188202
};
189203

190204
// DragonFlyBSD Target

0 commit comments

Comments
 (0)