aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Driver/ToolChains/Darwin.cpp33
-rw-r--r--clang/lib/Lex/ModuleMap.cpp69
2 files changed, 79 insertions, 23 deletions
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 0068ca3..c8700a7 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -2843,6 +2843,25 @@ bool Darwin::isAlignedAllocationUnavailable() const {
return TargetVersion < alignedAllocMinVersion(OS);
}
+static bool sdkSupportsBuiltinModules(const Darwin::DarwinPlatformKind &TargetPlatform, const std::optional<DarwinSDKInfo> &SDKInfo) {
+ if (!SDKInfo)
+ return false;
+
+ VersionTuple SDKVersion = SDKInfo->getVersion();
+ switch (TargetPlatform) {
+ case Darwin::MacOS:
+ return SDKVersion >= VersionTuple(99U);
+ case Darwin::IPhoneOS:
+ return SDKVersion >= VersionTuple(99U);
+ case Darwin::TvOS:
+ return SDKVersion >= VersionTuple(99U);
+ case Darwin::WatchOS:
+ return SDKVersion >= VersionTuple(99U);
+ default:
+ return true;
+ }
+}
+
void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
Action::OffloadKind DeviceOffloadKind) const {
@@ -2865,6 +2884,20 @@ void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
options::OPT_fvisibility_inlines_hidden_static_local_var,
options::OPT_fno_visibility_inlines_hidden_static_local_var))
CC1Args.push_back("-fvisibility-inlines-hidden-static-local-var");
+
+ // Earlier versions of the darwin SDK have the C standard library headers
+ // all together in the Darwin module. That leads to module cycles with
+ // the _Builtin_ modules. e.g. <inttypes.h> on darwin includes <stdint.h>.
+ // The builtin <stdint.h> include-nexts <stdint.h>. When both of those
+ // darwin headers are in the Darwin module, there's a module cycle Darwin ->
+ // _Builtin_stdint -> Darwin (i.e. inttypes.h (darwin) -> stdint.h (builtin) ->
+ // stdint.h (darwin)). This is fixed in later versions of the darwin SDK,
+ // but until then, the builtin headers need to join the system modules.
+ // i.e. when the builtin stdint.h is in the Darwin module too, the cycle
+ // goes away. Note that -fbuiltin-headers-in-system-modules does nothing
+ // to fix the same problem with C++ headers, and is generally fragile.
+ if (!sdkSupportsBuiltinModules(TargetPlatform, SDKInfo))
+ CC1Args.push_back("-fbuiltin-headers-in-system-modules");
}
void Darwin::addClangCC1ASTargetOptions(
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index bee3a48..4dcd911 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -253,6 +253,45 @@ OptionalFileEntryRef ModuleMap::findHeader(
return NormalHdrFile;
}
+/// Determine whether the given file name is the name of a builtin
+/// header, supplied by Clang to replace, override, or augment existing system
+/// headers.
+static bool isBuiltinHeaderName(StringRef FileName) {
+ return llvm::StringSwitch<bool>(FileName)
+ .Case("float.h", true)
+ .Case("iso646.h", true)
+ .Case("limits.h", true)
+ .Case("stdalign.h", true)
+ .Case("stdarg.h", true)
+ .Case("stdatomic.h", true)
+ .Case("stdbool.h", true)
+ .Case("stddef.h", true)
+ .Case("stdint.h", true)
+ .Case("tgmath.h", true)
+ .Case("unwind.h", true)
+ .Default(false);
+}
+
+/// Determine whether the given module name is the name of a builtin
+/// module that is cyclic with a system module on some platforms.
+static bool isBuiltInModuleName(StringRef ModuleName) {
+ return llvm::StringSwitch<bool>(ModuleName)
+ .Case("_Builtin_float", true)
+ .Case("_Builtin_inttypes", true)
+ .Case("_Builtin_iso646", true)
+ .Case("_Builtin_limits", true)
+ .Case("_Builtin_stdalign", true)
+ .Case("_Builtin_stdarg", true)
+ .Case("_Builtin_stdatomic", true)
+ .Case("_Builtin_stdbool", true)
+ .Case("_Builtin_stddef", true)
+ .Case("_Builtin_stdint", true)
+ .Case("_Builtin_stdnoreturn", true)
+ .Case("_Builtin_tgmath", true)
+ .Case("_Builtin_unwind", true)
+ .Default(false);
+}
+
void ModuleMap::resolveHeader(Module *Mod,
const Module::UnresolvedHeaderDirective &Header,
bool &NeedsFramework) {
@@ -297,7 +336,7 @@ bool ModuleMap::resolveAsBuiltinHeader(
llvm::sys::path::is_absolute(Header.FileName) ||
Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella ||
!BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
- !isBuiltinHeader(Header.FileName))
+ !LangOpts.BuiltinHeadersInSystemModules || !isBuiltinHeaderName(Header.FileName))
return false;
// This is a system module with a top-level header. This header
@@ -373,28 +412,9 @@ static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
return Name;
}
-/// Determine whether the given file name is the name of a builtin
-/// header, supplied by Clang to replace, override, or augment existing system
-/// headers.
-bool ModuleMap::isBuiltinHeader(StringRef FileName) {
- return llvm::StringSwitch<bool>(FileName)
- .Case("float.h", true)
- .Case("iso646.h", true)
- .Case("limits.h", true)
- .Case("stdalign.h", true)
- .Case("stdarg.h", true)
- .Case("stdatomic.h", true)
- .Case("stdbool.h", true)
- .Case("stddef.h", true)
- .Case("stdint.h", true)
- .Case("tgmath.h", true)
- .Case("unwind.h", true)
- .Default(false);
-}
-
bool ModuleMap::isBuiltinHeader(const FileEntry *File) {
- return File->getDir() == BuiltinIncludeDir &&
- ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()));
+ return File->getDir() == BuiltinIncludeDir && LangOpts.BuiltinHeadersInSystemModules &&
+ isBuiltinHeaderName(llvm::sys::path::filename(File->getName()));
}
ModuleMap::HeadersMap::iterator
@@ -2472,7 +2492,10 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
}
bool NeedsFramework = false;
- Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
+ // Don't add the top level headers to the builtin modules if the builtin headers
+ // belong to the system modules.
+ if (!Map.LangOpts.BuiltinHeadersInSystemModules || ActiveModule->isSubModule() || !isBuiltInModuleName(ActiveModule->Name))
+ Map.addUnresolvedHeader(ActiveModule, std::move(Header), NeedsFramework);
if (NeedsFramework)
Diags.Report(CurrModuleDeclLoc, diag::note_mmap_add_framework_keyword)