Skip to content

[stable/20240723][Darwin][Driver][clang] apple-none-macho orders the resource directory after internal-externc-isystem when nostdlibinc is used (#122035) #9816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6551,6 +6551,8 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
TC = std::make_unique<toolchains::BareMetal>(*this, Target, Args);
else if (Target.isOSBinFormatELF())
TC = std::make_unique<toolchains::Generic_ELF>(*this, Target, Args);
else if (Target.isAppleMachO())
TC = std::make_unique<toolchains::AppleMachO>(*this, Target, Args);
else if (Target.isOSBinFormatMachO())
TC = std::make_unique<toolchains::MachO>(*this, Target, Args);
else
Expand Down
116 changes: 64 additions & 52 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1049,10 +1049,14 @@ MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
getProgramPaths().push_back(getDriver().Dir);
}

AppleMachO::AppleMachO(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
: MachO(D, Triple, Args), CudaInstallation(D, Triple, Args),
RocmInstallation(D, Triple, Args) {}

/// Darwin - Darwin tool chain for i386 and x86_64.
Darwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
: MachO(D, Triple, Args), TargetInitialized(false),
CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args) {}
: AppleMachO(D, Triple, Args), TargetInitialized(false) {}

types::ID MachO::LookupTypeForExtension(StringRef Ext) const {
types::ID Ty = ToolChain::LookupTypeForExtension(Ext);
Expand Down Expand Up @@ -1101,13 +1105,13 @@ bool Darwin::hasBlocksRuntime() const {
}
}

void Darwin::AddCudaIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
void AppleMachO::AddCudaIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
CudaInstallation->AddCudaIncludeArgs(DriverArgs, CC1Args);
}

void Darwin::AddHIPIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
void AppleMachO::AddHIPIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args);
}

Expand Down Expand Up @@ -1202,6 +1206,8 @@ VersionTuple MachO::getLinkerVersion(const llvm::opt::ArgList &Args) const {

Darwin::~Darwin() {}

AppleMachO::~AppleMachO() {}

MachO::~MachO() {}

std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
Expand Down Expand Up @@ -2619,7 +2625,7 @@ static void AppendPlatformPrefix(SmallString<128> &Path,
// Returns the effective sysroot from either -isysroot or --sysroot, plus the
// platform prefix (if any).
llvm::SmallString<128>
DarwinClang::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const {
AppleMachO::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const {
llvm::SmallString<128> Path("/");
if (DriverArgs.hasArg(options::OPT_isysroot))
Path = DriverArgs.getLastArgValue(options::OPT_isysroot);
Expand All @@ -2632,8 +2638,9 @@ DarwinClang::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const {
return Path;
}

void DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
void AppleMachO::AddClangSystemIncludeArgs(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
const Driver &D = getDriver();

llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);
Expand Down Expand Up @@ -2711,7 +2718,7 @@ bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverAr
return getVFS().exists(Base);
}

void DarwinClang::AddClangCXXStdlibIncludeArgs(
void AppleMachO::AddClangCXXStdlibIncludeArgs(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
// The implementation from a base class will pass through the -stdlib to
Expand Down Expand Up @@ -2768,55 +2775,60 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs(
}

case ToolChain::CST_Libstdcxx:
llvm::SmallString<128> UsrIncludeCxx = Sysroot;
llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++");

llvm::Triple::ArchType arch = getTriple().getArch();
bool IsBaseFound = true;
switch (arch) {
default: break;

case llvm::Triple::x86:
case llvm::Triple::x86_64:
IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
"4.2.1",
"i686-apple-darwin10",
arch == llvm::Triple::x86_64 ? "x86_64" : "");
IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
"4.0.0", "i686-apple-darwin8",
"");
break;
AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args);
break;
}
}

case llvm::Triple::arm:
case llvm::Triple::thumb:
IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
"4.2.1",
"arm-apple-darwin10",
"v7");
IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
"4.2.1",
"arm-apple-darwin10",
"v6");
break;
void AppleMachO::AddGnuCPlusPlusIncludePaths(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {}

case llvm::Triple::aarch64:
IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
"4.2.1",
"arm64-apple-darwin10",
"");
break;
}
void DarwinClang::AddGnuCPlusPlusIncludePaths(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
llvm::SmallString<128> UsrIncludeCxx = GetEffectiveSysroot(DriverArgs);
llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++");

if (!IsBaseFound) {
getDriver().Diag(diag::warn_drv_libstdcxx_not_found);
}
llvm::Triple::ArchType arch = getTriple().getArch();
bool IsBaseFound = true;
switch (arch) {
default:
break;

case llvm::Triple::x86:
case llvm::Triple::x86_64:
IsBaseFound = AddGnuCPlusPlusIncludePaths(
DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1", "i686-apple-darwin10",
arch == llvm::Triple::x86_64 ? "x86_64" : "");
IsBaseFound |= AddGnuCPlusPlusIncludePaths(
DriverArgs, CC1Args, UsrIncludeCxx, "4.0.0", "i686-apple-darwin8", "");
break;

case llvm::Triple::arm:
case llvm::Triple::thumb:
IsBaseFound =
AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
"arm-apple-darwin10", "v7");
IsBaseFound |=
AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
"arm-apple-darwin10", "v6");
break;

case llvm::Triple::aarch64:
IsBaseFound =
AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1",
"arm64-apple-darwin10", "");
break;
}

if (!IsBaseFound) {
getDriver().Diag(diag::warn_drv_libstdcxx_not_found);
}
}

void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
void AppleMachO::AddCXXStdlibLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
CXXStdlibType Type = GetCXXStdlibType(Args);

switch (Type) {
Expand Down Expand Up @@ -3717,7 +3729,7 @@ SanitizerMask Darwin::getSupportedSanitizers() const {
return Res;
}

void Darwin::printVerboseInfo(raw_ostream &OS) const {
void AppleMachO::printVerboseInfo(raw_ostream &OS) const {
CudaInstallation->print(OS);
RocmInstallation->print(OS);
}
72 changes: 47 additions & 25 deletions clang/lib/Driver/ToolChains/Darwin.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,49 @@ class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain {
/// }
};

/// Apple specific MachO extensions
class LLVM_LIBRARY_VISIBILITY AppleMachO : public MachO {
public:
AppleMachO(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
~AppleMachO() override;

/// }
/// @name Apple Specific ToolChain Implementation
/// {
void
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;

void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;

void AddClangCXXStdlibIncludeArgs(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;

void printVerboseInfo(raw_ostream &OS) const override;
/// }

LazyDetector<CudaInstallationDetector> CudaInstallation;
LazyDetector<RocmInstallationDetector> RocmInstallation;

protected:
llvm::SmallString<128>
GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const;

private:
virtual void
AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
};

/// Darwin - The base Darwin tool chain.
class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
class LLVM_LIBRARY_VISIBILITY Darwin : public AppleMachO {
public:
/// Whether the information on the target has been initialized.
//
Expand Down Expand Up @@ -329,9 +370,6 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
/// The target variant triple that was specified (if any).
mutable std::optional<llvm::Triple> TargetVariantTriple;

LazyDetector<CudaInstallationDetector> CudaInstallation;
LazyDetector<RocmInstallationDetector> RocmInstallation;

private:
void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const;

Expand All @@ -343,7 +381,7 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
types::ID InputType) const override;

/// @name Apple Specific Toolchain Implementation
/// @name Darwin Specific Toolchain Implementation
/// {

void addMinVersionArgs(const llvm::opt::ArgList &Args,
Expand Down Expand Up @@ -559,11 +597,6 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
bool hasBlocksRuntime() const override;

void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;

bool UseObjCMixedDispatch() const override {
// This is only used with the non-fragile ABI and non-legacy dispatch.

Expand Down Expand Up @@ -594,8 +627,6 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
bool SupportsEmbeddedBitcode() const override;

SanitizerMask getSupportedSanitizers() const override;

void printVerboseInfo(raw_ostream &OS) const override;
};

/// DarwinClang - The Darwin toolchain used by Clang.
Expand All @@ -613,16 +644,6 @@ class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
llvm::opt::ArgStringList &CmdArgs,
bool ForceLinkBuiltinRT = false) const override;

void AddClangCXXStdlibIncludeArgs(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;

void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;

void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;

void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;

Expand Down Expand Up @@ -651,15 +672,16 @@ class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
StringRef Sanitizer,
bool shared = true) const;

void
AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;

bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
llvm::SmallString<128> Base,
llvm::StringRef Version,
llvm::StringRef ArchDir,
llvm::StringRef BitDir) const;

llvm::SmallString<128>
GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const;
};

} // end namespace toolchains
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Frontend/InitPreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1498,6 +1498,11 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
// ELF targets define __ELF__
if (TI.getTriple().isOSBinFormatELF())
Builder.defineMacro("__ELF__");
else if (TI.getTriple().isAppleMachO())
// Apple MachO targets define __MACH__ even when not using DarwinTargetInfo.
// Hurd will also define this in some circumstances, but that's done in
// HurdTargetInfo. Windows targets don't define this.
Builder.defineMacro("__MACH__");

// Target OS macro definitions.
if (PPOpts.DefineTargetOSMacros) {
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Lex/InitHeaderSearch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ bool InitHeaderSearch::ShouldAddDefaultIncludePaths(
break;

case llvm::Triple::UnknownOS:
if (triple.isWasm())
if (triple.isWasm() || triple.isAppleMachO())
return false;
break;

Expand Down
Empty file.
Empty file.
Empty file.
45 changes: 45 additions & 0 deletions clang/test/Driver/darwin-embedded-search-paths-libcxx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// REQUIRES: default-cxx-stdlib=libc++
// UNSUPPORTED: system-windows
// Windows is unsupported because we use the Unix path separator `/` in the test.

// Unlike the Darwin driver, the MachO driver doesn't add any framework search paths,
// only the normal header ones.
// RUN: %clang -x c -target arm64-apple-none-macho -isysroot %S/Inputs/MacOSX15.1.sdk -### -c %s 2>&1 \
// RUN: | FileCheck --check-prefixes=CC1,NO-CXX,ULI,CI,UI,NO-FW -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s

// Unlike the Darwin driver, the MachO driver doesn't default to libc++, but when
// CLANG_DEFAULT_CXX_STDLIB is libc++ then the MachO driver should find the search path.
// RUN: %clang -x c++ -target arm64-apple-none-macho -isysroot %S/Inputs/MacOSX15.1.sdk -### -c %s 2>&1 \
// RUN: | FileCheck --check-prefixes=CC1,CXX,ULI,CI,UI,NO-FW -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s

// If the user requests libc++, the MachO driver should still find the search path.
// RUN: %clang -x c++ -stdlib=libc++ -target arm64-apple-none-macho -isysroot %S/Inputs/MacOSX15.1.sdk -### -c %s 2>&1 \
// RUN: | FileCheck --check-prefixes=CC1,CXX,ULI,CI,UI,NO-FW -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s

// Verify that embedded uses can swap in alternate usr/include and usr/local/include directories.
// usr/local/include is specified in the driver as -internal-isystem, however, the driver generated
// paths come before the paths in the driver arguments. In order to keep usr/local/include in the
// same position, -isystem has to be used instead of -Xclang -internal-isystem. There isn't an
// -externc-isystem, but it's ok to use -Xclang -internal-externc-isystem since the driver doesn't
// use that if -nostdlibinc or -nostdinc is passed.
// RUN: %clang -x c++ -stdlib=libc++ -target arm64-apple-none-macho -isysroot %S/Inputs/MacOSX15.1.sdk \
// RUN: -nostdlibinc -isystem %S/Inputs/MacOSX15.1.sdk/embedded/usr/local/include \
// RUN: -Xclang -internal-externc-isystem -Xclang %S/Inputs/MacOSX15.1.sdk/embedded/usr/include \
// RUN: -### -c %s 2>&1 | FileCheck --check-prefixes=CC1,NO-CXX,EULI,CI,EUI,NO-FW -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s


// The ordering of these flags doesn't matter, and so this test is a little
// fragile. i.e. all of the -internal-isystem paths will be searched before the
// -internal-externc-isystem ones, and their order on the command line doesn't
// matter. The line order here is just the current order that the driver writes
// the cc1 arguments.

// CC1: "-cc1"
// NO-CXX-NOT: "-internal-isystem" "{{.*}}/include/c++/v1"
// CXX-SAME: "-internal-isystem" "{{.*}}/include/c++/v1"
// ULI-SAME: "-internal-isystem" "[[SDKROOT]]/usr/local/include"
// EULI-SAME: "-isystem" "[[SDKROOT]]/embedded/usr/local/include"
// CI-SAME: "-internal-isystem" "{{.*}}/clang/{{[[:digit:].]*}}/include"
// UI-SAME: "-internal-externc-isystem" "[[SDKROOT]]/usr/include"
// EUI-SAME: "-internal-externc-isystem" "[[SDKROOT]]/embedded/usr/include"
// NO-FW-NOT: "-internal-iframework"
Loading