diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Driver/ToolChains/Darwin.cpp | 33 | ||||
-rw-r--r-- | clang/lib/Lex/ModuleMap.cpp | 69 |
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) |