Implement Sema iosmac support - #218843
ian-twilightcoder wants to merge 1 commit into
Conversation
|
@llvm/pr-subscribers-clangd @llvm/pr-subscribers-clang-codegen Author: Ian Anderson (ian-twilightcoder) Changesrdar://38885683 apple-llvm-split-commit: 40aab84d831ddfc623de95fbbca06de6f0baf0a6 Patch is 121.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/218843.diff 33 Files Affected:
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index 9d233be282dbb..bab32734519c9 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -758,6 +758,13 @@ class alignas(8) Decl {
VersionTuple EnclosingVersion = VersionTuple(),
StringRef *RealizedPlatform = nullptr) const;
+ /// Determine the availability of the given declaration for the given
+ /// target platform and its minimum version.
+ AvailabilityResult getAvailability(StringRef Platform,
+ const VersionTuple &PlatformMinVersion,
+ std::string *Message = nullptr,
+ StringRef *RealizedPlatform = nullptr) const;
+
/// Retrieve the version of the target platform in which this
/// declaration was introduced.
///
@@ -766,14 +773,13 @@ class alignas(8) Decl {
/// attribute otherwise.
VersionTuple getVersionIntroduced() const;
- /// Determine whether this declaration is marked 'deprecated'.
+ /// \brief Determine whether this declaration is marked 'deprecated' in any
+ /// target platform that we're compiling for.
///
/// \param Message If non-NULL and the declaration is deprecated,
/// this will be set to the message describing why the declaration
/// was deprecated (which may be empty).
- bool isDeprecated(std::string *Message = nullptr) const {
- return getAvailability(Message) == AR_Deprecated;
- }
+ bool isDeprecatedInAnyTargetPlatform(std::string *Message = nullptr) const;
/// Determine whether this declaration is marked 'unavailable'.
///
@@ -784,6 +790,10 @@ class alignas(8) Decl {
return getAvailability(Message) == AR_Unavailable;
}
+ /// \brief Determine whether this declaration is marked 'deprecated' for
+ /// all target platforms that we're compiling for.
+ bool isUnavailabledForAllTargetPlatforms() const;
+
/// Determine whether this is a weak-imported symbol.
///
/// Weak-imported symbols are typically marked with the
diff --git a/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h
index b424530c8447c..39f22c961ce96 100644
--- a/clang/include/clang/AST/ExprObjC.h
+++ b/clang/include/clang/AST/ExprObjC.h
@@ -1736,13 +1736,18 @@ class ObjCAvailabilityCheckExpr : public Expr {
friend class ASTStmtReader;
VersionTuple VersionToCheck;
+ VersionTuple VariantVersionToCheck;
SourceLocation AtLoc, RParen;
public:
- ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc,
- SourceLocation RParen, QualType Ty)
+ ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck,
+ VersionTuple VariantVersionToCheck,
+ SourceLocation AtLoc, SourceLocation RParen,
+ QualType Ty)
: Expr(ObjCAvailabilityCheckExprClass, Ty, VK_PRValue, OK_Ordinary),
- VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {
+ VersionToCheck(VersionToCheck),
+ VariantVersionToCheck(VariantVersionToCheck), AtLoc(AtLoc),
+ RParen(RParen) {
setDependence(ExprDependence::None);
}
@@ -1757,6 +1762,10 @@ class ObjCAvailabilityCheckExpr : public Expr {
bool hasVersion() const { return !VersionToCheck.empty(); }
VersionTuple getVersion() const { return VersionToCheck; }
+ bool hasVariantVersion() const { return !VariantVersionToCheck.empty(); }
+
+ VersionTuple getVariantVersion() const { return VariantVersionToCheck; }
+
child_range children() {
return child_range(child_iterator(), child_iterator());
}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index cfb2ee3368201..c6b237c883a2b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4300,6 +4300,9 @@ def warn_unguarded_availability_new :
def warn_unguarded_availability_unavailable_new :
Warning<warn_unguarded_availability_unavailable.Summary>,
InGroup<UnguardedAvailabilityNew>;
+def warn_zippered_unguarded_availability :
+ Warning<"%0 is only available on %1 %2 and %3 %4 or newer">,
+ InGroup<UnguardedAvailabilityNew>;
def note_decl_unguarded_availability_silence : Note<
"annotate %select{%1|anonymous %1}0 with an availability attribute to silence this warning">;
def note_unguarded_available_silence : Note<
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 5a541aaf797fe..66a7ba2bd096f 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -260,6 +260,8 @@ class TargetInfo : public TransferrableTargetInfo,
mutable StringRef PlatformName;
mutable VersionTuple PlatformMinVersion;
+ mutable StringRef TargetVariantPlatform;
+ mutable VersionTuple TargetVariantPlatformMinVersion;
LLVM_PREFERRED_TYPE(bool)
unsigned HasAlignMac68kSupport : 1;
@@ -1737,6 +1739,28 @@ class TargetInfo : public TransferrableTargetInfo,
/// which the program should be compiled.
VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; }
+ /// Returns true when are building for an auxillary target variant platform.
+ bool hasTargetVariantPlatform() const {
+ return !TargetVariantPlatform.empty();
+ }
+
+ /// Retrieve the name of the target variant platform as it is used in the
+ /// availability attribute.
+ StringRef getTargetVariantPlatform() const {
+ assert(hasTargetVariantPlatform() &&
+ "no target variant platform specified");
+ return TargetVariantPlatform;
+ }
+
+ /// Retrieve the minimum desired deployment version of the target variant
+ /// platform,
+ /// for which the program should be compiled.
+ VersionTuple getTargetVariantPlatformMinVersion() const {
+ assert(hasTargetVariantPlatform() &&
+ "no target variant platform specified");
+ return TargetVariantPlatformMinVersion;
+ }
+
bool isBigEndian() const { return BigEndian; }
bool isLittleEndian() const { return !BigEndian; }
diff --git a/clang/include/clang/Sema/DelayedDiagnostic.h b/clang/include/clang/Sema/DelayedDiagnostic.h
index 0105089a393f1..5e45c3459f151 100644
--- a/clang/include/clang/Sema/DelayedDiagnostic.h
+++ b/clang/include/clang/Sema/DelayedDiagnostic.h
@@ -134,14 +134,13 @@ class DelayedDiagnostic {
void Destroy();
- static DelayedDiagnostic makeAvailability(AvailabilityResult AR,
- ArrayRef<SourceLocation> Locs,
- const NamedDecl *ReferringDecl,
- const NamedDecl *OffendingDecl,
- const ObjCInterfaceDecl *UnknownObjCClass,
- const ObjCPropertyDecl *ObjCProperty,
- StringRef Msg,
- bool ObjCPropertyAccess);
+ static DelayedDiagnostic
+ makeAvailability(AvailabilityResult AR, ArrayRef<SourceLocation> Locs,
+ const NamedDecl *ReferringDecl,
+ const NamedDecl *OffendingDecl,
+ const ObjCInterfaceDecl *UnknownObjCClass,
+ const ObjCPropertyDecl *ObjCProperty, StringRef Msg,
+ bool ObjCPropertyAccess, bool IsTargetVariantPlatform);
static DelayedDiagnostic makeAccess(SourceLocation Loc,
const AccessedEntity &Entity) {
@@ -232,6 +231,10 @@ class DelayedDiagnostic {
return AvailabilityData.ObjCPropertyAccess;
}
+ bool isTargetVariantPlatform() const {
+ return AvailabilityData.IsTargetVariantPlatform;
+ }
+
private:
struct AD {
const NamedDecl *ReferringDecl;
@@ -244,6 +247,7 @@ class DelayedDiagnostic {
size_t NumSelectorLocs;
AvailabilityResult AR;
bool ObjCPropertyAccess;
+ bool IsTargetVariantPlatform;
};
struct FTD {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index dcf112fd8eaa4..c7e4db0f49a30 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2466,6 +2466,10 @@ class Sema final : public SemaBase {
void handleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
+ void handleZipperedDelayedAvailabilityCheck(
+ sema::DelayedDiagnostic &DD, sema::DelayedDiagnostic &VariantDD,
+ Decl *Ctx);
+
/// Retrieve the current function, if any, that should be analyzed for
/// potential availability violations.
sema::FunctionScopeInfo *getCurFunctionAvailabilityContext();
@@ -2479,7 +2483,9 @@ class Sema final : public SemaBase {
void DiagnoseAvailabilityOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs);
std::pair<AvailabilityResult, const NamedDecl *>
- ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message,
+ ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, StringRef Platform,
+ const VersionTuple &PlatformVersion,
+ std::string *Message,
ObjCInterfaceDecl *ClassReceiver);
///@}
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 70f61fa57a682..b8dd2772977bd 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -674,15 +674,12 @@ static StringRef getRealizedPlatform(const AvailabilityAttr *A,
static AvailabilityResult CheckAvailability(ASTContext &Context,
const AvailabilityAttr *A,
std::string *Message,
+ StringRef TargetPlatform,
VersionTuple EnclosingVersion) {
- if (EnclosingVersion.empty())
- EnclosingVersion = Context.getTargetInfo().getPlatformMinVersion();
-
if (EnclosingVersion.empty())
return AR_Available;
StringRef ActualPlatform = A->getPlatform()->getName();
- StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
// Match the platform name.
if (getRealizedPlatform(A, Context) != TargetPlatform)
@@ -779,9 +776,21 @@ static AvailabilityResult CheckAvailability(ASTContext &Context,
AvailabilityResult Decl::getAvailability(std::string *Message,
VersionTuple EnclosingVersion,
StringRef *RealizedPlatform) const {
+ const TargetInfo &TI = getASTContext().getTargetInfo();
+ return getAvailability(TI.getPlatformName(),
+ EnclosingVersion.empty() ? TI.getPlatformMinVersion()
+ : EnclosingVersion,
+ Message, RealizedPlatform);
+}
+
+AvailabilityResult Decl::getAvailability(StringRef Platform,
+ const VersionTuple &PlatformMinVersion,
+ std::string *Message,
+ StringRef *RealizedPlatform) const {
if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this))
- return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,
- RealizedPlatform);
+ return FTD->getTemplatedDecl()->getAvailability(
+ Platform, PlatformMinVersion, Message, RealizedPlatform);
+
AvailabilityResult Result = AR_Available;
std::string ResultMessage;
@@ -806,8 +815,8 @@ AvailabilityResult Decl::getAvailability(std::string *Message,
if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
Availability = Availability->getEffectiveAttr();
- AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,
- Message, EnclosingVersion);
+ AvailabilityResult AR = CheckAvailability(
+ getASTContext(), Availability, Message, Platform, PlatformMinVersion);
if (AR == AR_Unavailable) {
if (RealizedPlatform)
@@ -844,6 +853,26 @@ VersionTuple Decl::getVersionIntroduced() const {
return {};
}
+bool Decl::isDeprecatedInAnyTargetPlatform(std::string *Message) const {
+ const TargetInfo &TI = getASTContext().getTargetInfo();
+ return getAvailability(TI.getPlatformName(), TI.getPlatformMinVersion()) ==
+ AR_Deprecated ||
+ (TI.hasTargetVariantPlatform() &&
+ getAvailability(TI.getTargetVariantPlatform(),
+ TI.getTargetVariantPlatformMinVersion()) ==
+ AR_Deprecated);
+}
+
+bool Decl::isUnavailabledForAllTargetPlatforms() const {
+ const TargetInfo &TI = getASTContext().getTargetInfo();
+ return getAvailability(TI.getPlatformName(), TI.getPlatformMinVersion()) ==
+ AR_Unavailable &&
+ (!getASTContext().getTargetInfo().hasTargetVariantPlatform() ||
+ getAvailability(TI.getTargetVariantPlatform(),
+ TI.getTargetVariantPlatformMinVersion()) ==
+ AR_Unavailable);
+}
+
bool Decl::canBeWeakImported(bool &IsDefinition) const {
IsDefinition = false;
@@ -878,6 +907,7 @@ bool Decl::isWeakImported() const {
if (!canBeWeakImported(IsDefinition))
return false;
+ const TargetInfo &TI = getASTContext().getTargetInfo();
for (const auto *A : getMostRecentDecl()->attrs()) {
if (isa<WeakImportAttr>(A))
return true;
@@ -885,7 +915,13 @@ bool Decl::isWeakImported() const {
if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
Availability = Availability->getEffectiveAttr();
if (CheckAvailability(getASTContext(), Availability, nullptr,
- VersionTuple()) == AR_NotYetIntroduced)
+ TI.getPlatformName(), TI.getPlatformMinVersion()) ==
+ AR_NotYetIntroduced ||
+ (TI.hasTargetVariantPlatform() &&
+ CheckAvailability(getASTContext(), Availability, nullptr,
+ TI.getTargetVariantPlatform(),
+ TI.getTargetVariantPlatformMinVersion()) ==
+ AR_NotYetIntroduced))
return true;
}
}
diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp
index 8d6e8d6990e80..0cd4b705bbcb9 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -1558,5 +1558,7 @@ DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
const llvm::Triple &Triple,
MacroBuilder &Builder) const {
- getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
+ getDarwinDefines(Builder, Opts, Triple, /*TargetVariantTriple=*/"",
+ PlatformName, PlatformMinVersion, TargetVariantPlatform,
+ TargetVariantPlatformMinVersion);
}
diff --git a/clang/lib/Basic/Targets/OSTargets.cpp b/clang/lib/Basic/Targets/OSTargets.cpp
index 04d9e13d3c9a6..91f98595dbbf5 100644
--- a/clang/lib/Basic/Targets/OSTargets.cpp
+++ b/clang/lib/Basic/Targets/OSTargets.cpp
@@ -55,8 +55,10 @@ void getAppleMachODefines(MacroBuilder &Builder, const LangOptions &Opts,
}
void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
- const llvm::Triple &Triple, StringRef &PlatformName,
- VersionTuple &PlatformMinVersion) {
+ const llvm::Triple &Triple, StringRef TargetVariantTriple,
+ StringRef &PlatformName, VersionTuple &PlatformMinVersion,
+ StringRef &TargetVariantPlatformName,
+ VersionTuple &TargetVariantPlatformMinVersion) {
getAppleMachODefines(Builder, Opts, Triple);
// Darwin's libc doesn't have threads.h
@@ -67,6 +69,14 @@ void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
if (Triple.isMacOSX()) {
Triple.getMacOSXVersion(OsVersion);
PlatformName = "macos";
+ if (!TargetVariantTriple.empty()) {
+ llvm::Triple TVT(TargetVariantTriple);
+ if (TVT.getOS() == llvm::Triple::IOS &&
+ TVT.getEnvironment() == llvm::Triple::MacABI) {
+ TargetVariantPlatformName = "maccatalyst";
+ TargetVariantPlatformMinVersion = TVT.getiOSVersion();
+ }
+ }
} else {
OsVersion = Triple.getOSVersion();
PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h
index fb5c17cefc004..d5aa067d9eabf 100644
--- a/clang/lib/Basic/Targets/OSTargets.h
+++ b/clang/lib/Basic/Targets/OSTargets.h
@@ -38,8 +38,10 @@ void getAppleMachODefines(MacroBuilder &Builder, const LangOptions &Opts,
const llvm::Triple &Triple);
void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
- const llvm::Triple &Triple, StringRef &PlatformName,
- VersionTuple &PlatformMinVersion);
+ const llvm::Triple &Triple, StringRef TargetVariantTriple,
+ StringRef &PlatformName, VersionTuple &PlatformMinVersion,
+ StringRef &TargetVariantPlatformName,
+ VersionTuple &TargetVariantPlatform);
template <typename Target>
class LLVM_LIBRARY_VISIBILITY AppleMachOTargetInfo
@@ -77,8 +79,10 @@ class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo
protected:
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
MacroBuilder &Builder) const override {
- getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
- this->PlatformMinVersion);
+ getDarwinDefines(Builder, Opts, Triple, TargetVariantTriple,
+ this->PlatformName, this->PlatformMinVersion,
+ this->TargetVariantPlatform,
+ this->TargetVariantPlatformMinVersion);
}
public:
@@ -87,6 +91,7 @@ class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo
// By default, no TLS, and we list permitted architecture/OS
// combinations.
this->TLSSupported = false;
+ TargetVariantTriple = Opts.DarwinTargetVariantTriple;
if (Triple.isMacOSX())
this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7);
@@ -185,6 +190,15 @@ class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo
bool areDefaultedSMFStillPOD(const LangOptions &) const override {
return false;
}
+
+ /// Darwin does not support protected visibility. Darwin's "default"
+ /// is very similar to ELF's "protected"; Darwin requires a "weak"
+ /// attribute on declarations that can be dynamically replaced.
+ bool hasProtectedVisibility() const override { return false; }
+
+private:
+ std::string TargetVariantTriple;
+
};
// DragonFlyBSD Target
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 173931213ce68..5f46849ccc956 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -635,13 +635,19 @@ class ScalarExprEmitter
Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
VersionTuple Version = E->getVersion();
+ VersionTuple VariantVersion = E->getVariantVersion();
// If we're checking for a platform older than our minimum deployment
// target, we can fold the check away.
- if (Version <= CGF.CGM.getTarget().getPlatformMinVersion())
+ if ((Version.empty() && VariantVersion.empty()) || (!Version.empty() &&
+ Version <= CGF.CGM.getTarget().getPlatformMinVersion() &&
+ (!CGF.CGM.getTarget().hasTargetVariantPlatform() ||
+ (!VariantVersion.empty() &&
+ VariantVersion <=
+ CGF.CGM.getTarget().getTargetVariantPlatformMinVersion()))))
return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
- return CGF.EmitBuiltinAvailable(Version);
+ return CGF.EmitBuiltinAvailable(Version, VariantVersion);
}
Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index b9cbf593fb1c4..73b1cdba09514 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -40...
[truncated]
|
|
@llvm/pr-subscribers-clang-modules Author: Ian Anderson (ian-twilightcoder) Changesrdar://38885683 apple-llvm-split-commit: 40aab84d831ddfc623de95fbbca06de6f0baf0a6 Patch is 121.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/218843.diff 33 Files Affected:
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index 9d233be282dbb..bab32734519c9 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -758,6 +758,13 @@ class alignas(8) Decl {
VersionTuple EnclosingVersion = VersionTuple(),
StringRef *RealizedPlatform = nullptr) const;
+ /// Determine the availability of the given declaration for the given
+ /// target platform and its minimum version.
+ AvailabilityResult getAvailability(StringRef Platform,
+ const VersionTuple &PlatformMinVersion,
+ std::string *Message = nullptr,
+ StringRef *RealizedPlatform = nullptr) const;
+
/// Retrieve the version of the target platform in which this
/// declaration was introduced.
///
@@ -766,14 +773,13 @@ class alignas(8) Decl {
/// attribute otherwise.
VersionTuple getVersionIntroduced() const;
- /// Determine whether this declaration is marked 'deprecated'.
+ /// \brief Determine whether this declaration is marked 'deprecated' in any
+ /// target platform that we're compiling for.
///
/// \param Message If non-NULL and the declaration is deprecated,
/// this will be set to the message describing why the declaration
/// was deprecated (which may be empty).
- bool isDeprecated(std::string *Message = nullptr) const {
- return getAvailability(Message) == AR_Deprecated;
- }
+ bool isDeprecatedInAnyTargetPlatform(std::string *Message = nullptr) const;
/// Determine whether this declaration is marked 'unavailable'.
///
@@ -784,6 +790,10 @@ class alignas(8) Decl {
return getAvailability(Message) == AR_Unavailable;
}
+ /// \brief Determine whether this declaration is marked 'deprecated' for
+ /// all target platforms that we're compiling for.
+ bool isUnavailabledForAllTargetPlatforms() const;
+
/// Determine whether this is a weak-imported symbol.
///
/// Weak-imported symbols are typically marked with the
diff --git a/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h
index b424530c8447c..39f22c961ce96 100644
--- a/clang/include/clang/AST/ExprObjC.h
+++ b/clang/include/clang/AST/ExprObjC.h
@@ -1736,13 +1736,18 @@ class ObjCAvailabilityCheckExpr : public Expr {
friend class ASTStmtReader;
VersionTuple VersionToCheck;
+ VersionTuple VariantVersionToCheck;
SourceLocation AtLoc, RParen;
public:
- ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc,
- SourceLocation RParen, QualType Ty)
+ ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck,
+ VersionTuple VariantVersionToCheck,
+ SourceLocation AtLoc, SourceLocation RParen,
+ QualType Ty)
: Expr(ObjCAvailabilityCheckExprClass, Ty, VK_PRValue, OK_Ordinary),
- VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {
+ VersionToCheck(VersionToCheck),
+ VariantVersionToCheck(VariantVersionToCheck), AtLoc(AtLoc),
+ RParen(RParen) {
setDependence(ExprDependence::None);
}
@@ -1757,6 +1762,10 @@ class ObjCAvailabilityCheckExpr : public Expr {
bool hasVersion() const { return !VersionToCheck.empty(); }
VersionTuple getVersion() const { return VersionToCheck; }
+ bool hasVariantVersion() const { return !VariantVersionToCheck.empty(); }
+
+ VersionTuple getVariantVersion() const { return VariantVersionToCheck; }
+
child_range children() {
return child_range(child_iterator(), child_iterator());
}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index cfb2ee3368201..c6b237c883a2b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4300,6 +4300,9 @@ def warn_unguarded_availability_new :
def warn_unguarded_availability_unavailable_new :
Warning<warn_unguarded_availability_unavailable.Summary>,
InGroup<UnguardedAvailabilityNew>;
+def warn_zippered_unguarded_availability :
+ Warning<"%0 is only available on %1 %2 and %3 %4 or newer">,
+ InGroup<UnguardedAvailabilityNew>;
def note_decl_unguarded_availability_silence : Note<
"annotate %select{%1|anonymous %1}0 with an availability attribute to silence this warning">;
def note_unguarded_available_silence : Note<
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 5a541aaf797fe..66a7ba2bd096f 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -260,6 +260,8 @@ class TargetInfo : public TransferrableTargetInfo,
mutable StringRef PlatformName;
mutable VersionTuple PlatformMinVersion;
+ mutable StringRef TargetVariantPlatform;
+ mutable VersionTuple TargetVariantPlatformMinVersion;
LLVM_PREFERRED_TYPE(bool)
unsigned HasAlignMac68kSupport : 1;
@@ -1737,6 +1739,28 @@ class TargetInfo : public TransferrableTargetInfo,
/// which the program should be compiled.
VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; }
+ /// Returns true when are building for an auxillary target variant platform.
+ bool hasTargetVariantPlatform() const {
+ return !TargetVariantPlatform.empty();
+ }
+
+ /// Retrieve the name of the target variant platform as it is used in the
+ /// availability attribute.
+ StringRef getTargetVariantPlatform() const {
+ assert(hasTargetVariantPlatform() &&
+ "no target variant platform specified");
+ return TargetVariantPlatform;
+ }
+
+ /// Retrieve the minimum desired deployment version of the target variant
+ /// platform,
+ /// for which the program should be compiled.
+ VersionTuple getTargetVariantPlatformMinVersion() const {
+ assert(hasTargetVariantPlatform() &&
+ "no target variant platform specified");
+ return TargetVariantPlatformMinVersion;
+ }
+
bool isBigEndian() const { return BigEndian; }
bool isLittleEndian() const { return !BigEndian; }
diff --git a/clang/include/clang/Sema/DelayedDiagnostic.h b/clang/include/clang/Sema/DelayedDiagnostic.h
index 0105089a393f1..5e45c3459f151 100644
--- a/clang/include/clang/Sema/DelayedDiagnostic.h
+++ b/clang/include/clang/Sema/DelayedDiagnostic.h
@@ -134,14 +134,13 @@ class DelayedDiagnostic {
void Destroy();
- static DelayedDiagnostic makeAvailability(AvailabilityResult AR,
- ArrayRef<SourceLocation> Locs,
- const NamedDecl *ReferringDecl,
- const NamedDecl *OffendingDecl,
- const ObjCInterfaceDecl *UnknownObjCClass,
- const ObjCPropertyDecl *ObjCProperty,
- StringRef Msg,
- bool ObjCPropertyAccess);
+ static DelayedDiagnostic
+ makeAvailability(AvailabilityResult AR, ArrayRef<SourceLocation> Locs,
+ const NamedDecl *ReferringDecl,
+ const NamedDecl *OffendingDecl,
+ const ObjCInterfaceDecl *UnknownObjCClass,
+ const ObjCPropertyDecl *ObjCProperty, StringRef Msg,
+ bool ObjCPropertyAccess, bool IsTargetVariantPlatform);
static DelayedDiagnostic makeAccess(SourceLocation Loc,
const AccessedEntity &Entity) {
@@ -232,6 +231,10 @@ class DelayedDiagnostic {
return AvailabilityData.ObjCPropertyAccess;
}
+ bool isTargetVariantPlatform() const {
+ return AvailabilityData.IsTargetVariantPlatform;
+ }
+
private:
struct AD {
const NamedDecl *ReferringDecl;
@@ -244,6 +247,7 @@ class DelayedDiagnostic {
size_t NumSelectorLocs;
AvailabilityResult AR;
bool ObjCPropertyAccess;
+ bool IsTargetVariantPlatform;
};
struct FTD {
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index dcf112fd8eaa4..c7e4db0f49a30 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2466,6 +2466,10 @@ class Sema final : public SemaBase {
void handleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
+ void handleZipperedDelayedAvailabilityCheck(
+ sema::DelayedDiagnostic &DD, sema::DelayedDiagnostic &VariantDD,
+ Decl *Ctx);
+
/// Retrieve the current function, if any, that should be analyzed for
/// potential availability violations.
sema::FunctionScopeInfo *getCurFunctionAvailabilityContext();
@@ -2479,7 +2483,9 @@ class Sema final : public SemaBase {
void DiagnoseAvailabilityOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs);
std::pair<AvailabilityResult, const NamedDecl *>
- ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message,
+ ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, StringRef Platform,
+ const VersionTuple &PlatformVersion,
+ std::string *Message,
ObjCInterfaceDecl *ClassReceiver);
///@}
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 70f61fa57a682..b8dd2772977bd 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -674,15 +674,12 @@ static StringRef getRealizedPlatform(const AvailabilityAttr *A,
static AvailabilityResult CheckAvailability(ASTContext &Context,
const AvailabilityAttr *A,
std::string *Message,
+ StringRef TargetPlatform,
VersionTuple EnclosingVersion) {
- if (EnclosingVersion.empty())
- EnclosingVersion = Context.getTargetInfo().getPlatformMinVersion();
-
if (EnclosingVersion.empty())
return AR_Available;
StringRef ActualPlatform = A->getPlatform()->getName();
- StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
// Match the platform name.
if (getRealizedPlatform(A, Context) != TargetPlatform)
@@ -779,9 +776,21 @@ static AvailabilityResult CheckAvailability(ASTContext &Context,
AvailabilityResult Decl::getAvailability(std::string *Message,
VersionTuple EnclosingVersion,
StringRef *RealizedPlatform) const {
+ const TargetInfo &TI = getASTContext().getTargetInfo();
+ return getAvailability(TI.getPlatformName(),
+ EnclosingVersion.empty() ? TI.getPlatformMinVersion()
+ : EnclosingVersion,
+ Message, RealizedPlatform);
+}
+
+AvailabilityResult Decl::getAvailability(StringRef Platform,
+ const VersionTuple &PlatformMinVersion,
+ std::string *Message,
+ StringRef *RealizedPlatform) const {
if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this))
- return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,
- RealizedPlatform);
+ return FTD->getTemplatedDecl()->getAvailability(
+ Platform, PlatformMinVersion, Message, RealizedPlatform);
+
AvailabilityResult Result = AR_Available;
std::string ResultMessage;
@@ -806,8 +815,8 @@ AvailabilityResult Decl::getAvailability(std::string *Message,
if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
Availability = Availability->getEffectiveAttr();
- AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,
- Message, EnclosingVersion);
+ AvailabilityResult AR = CheckAvailability(
+ getASTContext(), Availability, Message, Platform, PlatformMinVersion);
if (AR == AR_Unavailable) {
if (RealizedPlatform)
@@ -844,6 +853,26 @@ VersionTuple Decl::getVersionIntroduced() const {
return {};
}
+bool Decl::isDeprecatedInAnyTargetPlatform(std::string *Message) const {
+ const TargetInfo &TI = getASTContext().getTargetInfo();
+ return getAvailability(TI.getPlatformName(), TI.getPlatformMinVersion()) ==
+ AR_Deprecated ||
+ (TI.hasTargetVariantPlatform() &&
+ getAvailability(TI.getTargetVariantPlatform(),
+ TI.getTargetVariantPlatformMinVersion()) ==
+ AR_Deprecated);
+}
+
+bool Decl::isUnavailabledForAllTargetPlatforms() const {
+ const TargetInfo &TI = getASTContext().getTargetInfo();
+ return getAvailability(TI.getPlatformName(), TI.getPlatformMinVersion()) ==
+ AR_Unavailable &&
+ (!getASTContext().getTargetInfo().hasTargetVariantPlatform() ||
+ getAvailability(TI.getTargetVariantPlatform(),
+ TI.getTargetVariantPlatformMinVersion()) ==
+ AR_Unavailable);
+}
+
bool Decl::canBeWeakImported(bool &IsDefinition) const {
IsDefinition = false;
@@ -878,6 +907,7 @@ bool Decl::isWeakImported() const {
if (!canBeWeakImported(IsDefinition))
return false;
+ const TargetInfo &TI = getASTContext().getTargetInfo();
for (const auto *A : getMostRecentDecl()->attrs()) {
if (isa<WeakImportAttr>(A))
return true;
@@ -885,7 +915,13 @@ bool Decl::isWeakImported() const {
if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
Availability = Availability->getEffectiveAttr();
if (CheckAvailability(getASTContext(), Availability, nullptr,
- VersionTuple()) == AR_NotYetIntroduced)
+ TI.getPlatformName(), TI.getPlatformMinVersion()) ==
+ AR_NotYetIntroduced ||
+ (TI.hasTargetVariantPlatform() &&
+ CheckAvailability(getASTContext(), Availability, nullptr,
+ TI.getTargetVariantPlatform(),
+ TI.getTargetVariantPlatformMinVersion()) ==
+ AR_NotYetIntroduced))
return true;
}
}
diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp
index 8d6e8d6990e80..0cd4b705bbcb9 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -1558,5 +1558,7 @@ DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
const llvm::Triple &Triple,
MacroBuilder &Builder) const {
- getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
+ getDarwinDefines(Builder, Opts, Triple, /*TargetVariantTriple=*/"",
+ PlatformName, PlatformMinVersion, TargetVariantPlatform,
+ TargetVariantPlatformMinVersion);
}
diff --git a/clang/lib/Basic/Targets/OSTargets.cpp b/clang/lib/Basic/Targets/OSTargets.cpp
index 04d9e13d3c9a6..91f98595dbbf5 100644
--- a/clang/lib/Basic/Targets/OSTargets.cpp
+++ b/clang/lib/Basic/Targets/OSTargets.cpp
@@ -55,8 +55,10 @@ void getAppleMachODefines(MacroBuilder &Builder, const LangOptions &Opts,
}
void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
- const llvm::Triple &Triple, StringRef &PlatformName,
- VersionTuple &PlatformMinVersion) {
+ const llvm::Triple &Triple, StringRef TargetVariantTriple,
+ StringRef &PlatformName, VersionTuple &PlatformMinVersion,
+ StringRef &TargetVariantPlatformName,
+ VersionTuple &TargetVariantPlatformMinVersion) {
getAppleMachODefines(Builder, Opts, Triple);
// Darwin's libc doesn't have threads.h
@@ -67,6 +69,14 @@ void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
if (Triple.isMacOSX()) {
Triple.getMacOSXVersion(OsVersion);
PlatformName = "macos";
+ if (!TargetVariantTriple.empty()) {
+ llvm::Triple TVT(TargetVariantTriple);
+ if (TVT.getOS() == llvm::Triple::IOS &&
+ TVT.getEnvironment() == llvm::Triple::MacABI) {
+ TargetVariantPlatformName = "maccatalyst";
+ TargetVariantPlatformMinVersion = TVT.getiOSVersion();
+ }
+ }
} else {
OsVersion = Triple.getOSVersion();
PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h
index fb5c17cefc004..d5aa067d9eabf 100644
--- a/clang/lib/Basic/Targets/OSTargets.h
+++ b/clang/lib/Basic/Targets/OSTargets.h
@@ -38,8 +38,10 @@ void getAppleMachODefines(MacroBuilder &Builder, const LangOptions &Opts,
const llvm::Triple &Triple);
void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
- const llvm::Triple &Triple, StringRef &PlatformName,
- VersionTuple &PlatformMinVersion);
+ const llvm::Triple &Triple, StringRef TargetVariantTriple,
+ StringRef &PlatformName, VersionTuple &PlatformMinVersion,
+ StringRef &TargetVariantPlatformName,
+ VersionTuple &TargetVariantPlatform);
template <typename Target>
class LLVM_LIBRARY_VISIBILITY AppleMachOTargetInfo
@@ -77,8 +79,10 @@ class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo
protected:
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
MacroBuilder &Builder) const override {
- getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
- this->PlatformMinVersion);
+ getDarwinDefines(Builder, Opts, Triple, TargetVariantTriple,
+ this->PlatformName, this->PlatformMinVersion,
+ this->TargetVariantPlatform,
+ this->TargetVariantPlatformMinVersion);
}
public:
@@ -87,6 +91,7 @@ class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo
// By default, no TLS, and we list permitted architecture/OS
// combinations.
this->TLSSupported = false;
+ TargetVariantTriple = Opts.DarwinTargetVariantTriple;
if (Triple.isMacOSX())
this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7);
@@ -185,6 +190,15 @@ class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo
bool areDefaultedSMFStillPOD(const LangOptions &) const override {
return false;
}
+
+ /// Darwin does not support protected visibility. Darwin's "default"
+ /// is very similar to ELF's "protected"; Darwin requires a "weak"
+ /// attribute on declarations that can be dynamically replaced.
+ bool hasProtectedVisibility() const override { return false; }
+
+private:
+ std::string TargetVariantTriple;
+
};
// DragonFlyBSD Target
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 173931213ce68..5f46849ccc956 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -635,13 +635,19 @@ class ScalarExprEmitter
Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
VersionTuple Version = E->getVersion();
+ VersionTuple VariantVersion = E->getVariantVersion();
// If we're checking for a platform older than our minimum deployment
// target, we can fold the check away.
- if (Version <= CGF.CGM.getTarget().getPlatformMinVersion())
+ if ((Version.empty() && VariantVersion.empty()) || (!Version.empty() &&
+ Version <= CGF.CGM.getTarget().getPlatformMinVersion() &&
+ (!CGF.CGM.getTarget().hasTargetVariantPlatform() ||
+ (!VariantVersion.empty() &&
+ VariantVersion <=
+ CGF.CGM.getTarget().getTargetVariantPlatformMinVersion()))))
return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
- return CGF.EmitBuiltinAvailable(Version);
+ return CGF.EmitBuiltinAvailable(Version, VariantVersion);
}
Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index b9cbf593fb1c4..73b1cdba09514 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -40...
[truncated]
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
|
First commit in a series of upstreaming |
0344fcd to
2808a5b
Compare
🪟 Windows x64 Test Results
✅ The build succeeded and all tests passed. |
cor3ntin
left a comment
There was a problem hiding this comment.
Please make sure the description is a minimum useful.
https://llvm.org/docs/DeveloperPolicy.html#commit-messages
Sure, I'll add the summary of what I'm trying to do: upstream some Mac Catalyst support that was missed and has been causing merge conflicts for awhile now. |
rdar://38885683 apple-llvm-split-commit: 40aab84d831ddfc623de95fbbca06de6f0baf0a6 apple-llvm-split-dir: clang/
2808a5b to
167e143
Compare
|
Does that need an RFC? |
I don't think so, it's 8 years relied upon Mac Catalyst behavior, but @ahatanak what do you think? |
|
@Fznamznon I do agree. The community do try to be accommodating but there is certainly no blanket policy to accept arbitrary downstream extensions without discussion. That it has been deployed downstream for some years isn't really relevant. So an RFC that describes the behavior of this PR would be useful. This PR would further need to come with a sensible description, documentation (and a release note) before we can meaningfully review it. Thanks |
I really have to reinforce this message. As a reviewer I expect the summary to explain the problem, what the approach is, anything that may warrant attention and minimize the amount of context switching I need to do to understand the code I am about to review. Especially for large sets of changes. |
ojhunt
left a comment
There was a problem hiding this comment.
Ok, a few change requests, but I think the PR as a whole should be split up. A large amount of the change is churn around diagnostic generation and code location. I think splitting that out into a separate PR will make it easier to reason about the behavioural changes.
It's a significant enough change that we should update the documentation around availability and targets.
Finally, this is functionally a feature addition so the PR/commit message does need to be quite detailed as to what is being changed and why.
Someone said an RFC may be appropriate (@shafik maybe?). I'm not sure that that is actually necessary here, but to avoid the appearance of favouritism I'll defer to the maintainers.
More details about what this change is, what it supports, and why it is structured how it is will help folk without the downstream context will help folk determine whether or not an RFC is warranted.
| (!Version.empty() && | ||
| Version <= CGF.CGM.getTarget().getPlatformMinVersion() && | ||
| (!CGF.CGM.getTarget().hasTargetVariantPlatform() || | ||
| (!VariantVersion.empty() && | ||
| VariantVersion <= | ||
| CGF.CGM.getTarget().getTargetVariantPlatformMinVersion())))) |
There was a problem hiding this comment.
I really think the complexity of this condition warrants breaking it into separate flags, e.g.
bool FoldCheck = false;
if (Version.empty() && VariantVersion.empty())
FoldCheck = true;
else if (....) FoldCheck = true;
else if (...) FoldCzech = true;
...
if (FoldhCeck)
return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);| if (!Args.empty()) { | ||
| Check = EmitNounwindRuntimeCall(CGM.IsOSVersionAtLeastFn, Args); | ||
| } |
| if (!VariantArgs.empty()) { | ||
| VariantCheck = EmitNounwindRuntimeCall( | ||
| CGM.IsTargetVariantOSVersionAtLeastFn, VariantArgs); | ||
| } |
There was a problem hiding this comment.
nit: again -- will refrain from more :D
| VariantCheck = EmitNounwindRuntimeCall( | ||
| CGM.IsTargetVariantOSVersionAtLeastFn, VariantArgs); | ||
| } | ||
| llvm::Value *IsNativeCheck = nullptr; |
There was a problem hiding this comment.
Does this need to be outside the if block?
| // FIXME: Take min of target and target-variant AR for better Xcode | ||
| // experience? |
There was a problem hiding this comment.
I'm unsure if this comment is relevant to llvm.org? Would depend on existing precedence
| /* TO_UPSTREAM(iosmac) ON*/ | ||
| Result = D->getAvailability(Platform, PlatformVersion, Message); | ||
| /* TO_UPSTREAM(iosmac) OFF*/ |
| bool isDeprecated(std::string *Message = nullptr) const { | ||
| return getAvailability(Message) == AR_Deprecated; | ||
| } |
There was a problem hiding this comment.
isDeprecated should be able to just do the right thing - it has access to the target info via the ASTContext. There does not appear to be a strong reason to change its behavior - there are places where we want to be more lax and say "is deprecated on any platform", but that seems to be atypical. The common case should remain isDeprecated.
The analogous isUnavailable has not been removed, but should also remain and continue to do the correct thing by default.
| // at one of them. | ||
| const AvailabilityAttr *A = | ||
| getAttrForPlatform(S.Context, Platform, OffendingDecl); | ||
| if (A && A->isInherited()) { |
There was a problem hiding this comment.
consider writing as
SourceLocation OriginalOffendingLocation = OffendingDecl->getLocation();
if (!A || !A->isInherited())
return OriginalOffendingLocation;
// for loop here
...
//
return OriginalOffendingLocation;Not a blocker in any way - I simply prefer early returns in these cases
|
Alright, let me circle back my teammates on how to best approach this. My end goal is to upstream some missing Mac Catalyst code, which comprises 21 commits downstream. I wanted to preserve the Git history as close as possible so that it lines up with the downstream repo, and because it's mostly not my code. It's from 8 years ago and the original author isn't at Apple anymore, which is the main reason I did it myself. I didn't want to do a giant mega review with 21 commits for people who did want to look at some of this beyond "yep it's what the Xcode clang has been doing for many years and it works fine". But it's also not very helpful to have people review code that the next 20 commits is just going to change anyway. So for now I'm going to close the review and come up with a better strategy so this isn't terrible for everyone who's looking at it, sorry for the commotion. |
First commit in a series of upstreaming
-target-variantsupport in Sema.rdar://38885683
apple-llvm-split-commit: 40aab84d831ddfc623de95fbbca06de6f0baf0a6
apple-llvm-split-dir: clang/