You've already forked llvm-project
mirror of
https://github.com/encounter/llvm-project.git
synced 2026-03-30 11:27:19 -07:00
[clang][Darwin] Refactor header search path logic into the driver
Summary: This commit moves the logic for determining system, resource and C++ header search paths from CC1 to the driver. This refactor has already been made for several platforms, but Darwin had been left behind. This refactor tries to implement the previous search path logic with perfect accuracy. In particular, the order of all include paths inside CC1 and all paths that were skipped because nonexistent are conserved after the refactor. This change was also tested against a code base of significant size and revealed no problems. Reviewers: jfb, arphaman Subscribers: nemanjai, javed.absar, kbarton, christof, jkorous, dexonsmith, jsji, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D61963 llvm-svn: 361278
This commit is contained in:
@@ -453,4 +453,9 @@ def warn_drv_msp430_hwmult_no_device : Warning<"no MCU device specified, but "
|
||||
"specify a MSP430 device, or -mhwmult to set hardware multiply type "
|
||||
"explicitly.">, InGroup<InvalidCommandLineArgument>;
|
||||
|
||||
def warn_drv_libstdcxx_not_found : Warning<
|
||||
"include path for libstdc++ headers not found; pass '-stdlib=libc++' on the "
|
||||
"command line to use the libc++ standard library instead">,
|
||||
InGroup<DiagGroup<"stdlibcxx-not-found">>;
|
||||
|
||||
}
|
||||
|
||||
@@ -232,11 +232,6 @@ def err_invalid_vfs_overlay : Error<
|
||||
def warn_option_invalid_ocl_version : Warning<
|
||||
"OpenCL version %0 does not support the option '%1'">, InGroup<Deprecated>;
|
||||
|
||||
def warn_stdlibcxx_not_found : Warning<
|
||||
"include path for stdlibc++ headers not found; pass '-stdlib=libc++' on the "
|
||||
"command line to use the libc++ standard library instead">,
|
||||
InGroup<DiagGroup<"stdlibcxx-not-found">>;
|
||||
|
||||
def err_builtin_needs_feature : Error<"%0 needs target feature %1">;
|
||||
def err_function_needs_feature : Error<
|
||||
"always_inline function %1 requires target feature '%2', but would "
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "CommonArgs.h"
|
||||
#include "clang/Basic/AlignedAllocation.h"
|
||||
#include "clang/Basic/ObjCRuntime.h"
|
||||
#include "clang/Config/config.h"
|
||||
#include "clang/Driver/Compilation.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Driver/DriverDiagnostic.h"
|
||||
@@ -1804,6 +1805,84 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
|
||||
}
|
||||
}
|
||||
|
||||
void DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const {
|
||||
const Driver &D = getDriver();
|
||||
|
||||
llvm::StringRef Sysroot = "/";
|
||||
if (const Arg *A = DriverArgs.getLastArg(options::OPT_isysroot))
|
||||
Sysroot = A->getValue();
|
||||
|
||||
bool NoStdInc = DriverArgs.hasArg(options::OPT_nostdinc);
|
||||
bool NoStdlibInc = DriverArgs.hasArg(options::OPT_nostdlibinc);
|
||||
bool NoBuiltinInc = DriverArgs.hasArg(options::OPT_nobuiltininc);
|
||||
|
||||
// Add <sysroot>/usr/local/include
|
||||
if (!NoStdInc && !NoStdlibInc) {
|
||||
SmallString<128> P(Sysroot);
|
||||
llvm::sys::path::append(P, "usr", "local", "include");
|
||||
addSystemInclude(DriverArgs, CC1Args, P);
|
||||
}
|
||||
|
||||
// Add the Clang builtin headers (<resource>/include)
|
||||
if (!NoStdInc && !NoBuiltinInc) {
|
||||
SmallString<128> P(D.ResourceDir);
|
||||
llvm::sys::path::append(P, "include");
|
||||
addSystemInclude(DriverArgs, CC1Args, P);
|
||||
}
|
||||
|
||||
if (NoStdInc || NoStdlibInc)
|
||||
return;
|
||||
|
||||
// Check for configure-time C include directories.
|
||||
llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS);
|
||||
if (!CIncludeDirs.empty()) {
|
||||
llvm::SmallVector<llvm::StringRef, 5> dirs;
|
||||
CIncludeDirs.split(dirs, ":");
|
||||
for (llvm::StringRef dir : dirs) {
|
||||
llvm::StringRef Prefix =
|
||||
llvm::sys::path::is_absolute(dir) ? llvm::StringRef(Sysroot) : "";
|
||||
addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
|
||||
}
|
||||
} else {
|
||||
// Otherwise, add <sysroot>/usr/include.
|
||||
SmallString<128> P(Sysroot);
|
||||
llvm::sys::path::append(P, "usr", "include");
|
||||
addExternCSystemInclude(DriverArgs, CC1Args, P.str());
|
||||
}
|
||||
}
|
||||
|
||||
bool DarwinClang::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::sys::path::append(Base, Version);
|
||||
|
||||
// Add the base dir
|
||||
addSystemInclude(DriverArgs, CC1Args, Base);
|
||||
|
||||
// Add the multilib dirs
|
||||
{
|
||||
llvm::SmallString<128> P = Base;
|
||||
if (!ArchDir.empty())
|
||||
llvm::sys::path::append(P, ArchDir);
|
||||
if (!BitDir.empty())
|
||||
llvm::sys::path::append(P, BitDir);
|
||||
addSystemInclude(DriverArgs, CC1Args, P);
|
||||
}
|
||||
|
||||
// Add the backward dir
|
||||
{
|
||||
llvm::SmallString<128> P = Base;
|
||||
llvm::sys::path::append(P, "backward");
|
||||
addSystemInclude(DriverArgs, CC1Args, P);
|
||||
}
|
||||
|
||||
return getVFS().exists(Base);
|
||||
}
|
||||
|
||||
void DarwinClang::AddClangCXXStdlibIncludeArgs(
|
||||
const llvm::opt::ArgList &DriverArgs,
|
||||
llvm::opt::ArgStringList &CC1Args) const {
|
||||
@@ -1811,29 +1890,95 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs(
|
||||
// CC1Args.
|
||||
// FIXME: this should not be necessary, remove usages in the frontend
|
||||
// (e.g. HeaderSearchOptions::UseLibcxx) and don't pipe -stdlib.
|
||||
// Also check whether this is used for setting library search paths.
|
||||
ToolChain::AddClangCXXStdlibIncludeArgs(DriverArgs, CC1Args);
|
||||
|
||||
if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
|
||||
DriverArgs.hasArg(options::OPT_nostdincxx))
|
||||
return;
|
||||
|
||||
llvm::SmallString<128> Sysroot;
|
||||
if (const Arg *A = DriverArgs.getLastArg(options::OPT_isysroot)) {
|
||||
Sysroot = A->getValue();
|
||||
} else {
|
||||
Sysroot = "/";
|
||||
}
|
||||
|
||||
switch (GetCXXStdlibType(DriverArgs)) {
|
||||
case ToolChain::CST_Libcxx: {
|
||||
llvm::StringRef InstallDir = getDriver().getInstalledDir();
|
||||
if (InstallDir.empty())
|
||||
break;
|
||||
// On Darwin, libc++ may be installed alongside the compiler in
|
||||
// include/c++/v1.
|
||||
// Get from 'foo/bin' to 'foo/include/c++/v1'.
|
||||
SmallString<128> P = InstallDir;
|
||||
// Note that InstallDir can be relative, so we have to '..' and not
|
||||
// parent_path.
|
||||
llvm::sys::path::append(P, "..", "include", "c++", "v1");
|
||||
addSystemInclude(DriverArgs, CC1Args, P);
|
||||
// On Darwin, libc++ is installed alongside the compiler in
|
||||
// include/c++/v1, so get from '<install>/bin' to '<install>/include/c++/v1'.
|
||||
{
|
||||
llvm::SmallString<128> P = llvm::StringRef(getDriver().getInstalledDir());
|
||||
// Note that P can be relative, so we have to '..' and not parent_path.
|
||||
llvm::sys::path::append(P, "..", "include", "c++", "v1");
|
||||
addSystemInclude(DriverArgs, CC1Args, P);
|
||||
}
|
||||
// Also add <sysroot>/usr/include/c++/v1 unless -nostdinc is used,
|
||||
// to match the legacy behavior in CC1.
|
||||
if (!DriverArgs.hasArg(options::OPT_nostdinc)) {
|
||||
llvm::SmallString<128> P = Sysroot;
|
||||
llvm::sys::path::append(P, "usr", "include", "c++", "v1");
|
||||
addSystemInclude(DriverArgs, CC1Args, P);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ToolChain::CST_Libstdcxx:
|
||||
// FIXME: should we do something about it?
|
||||
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::ppc:
|
||||
case llvm::Triple::ppc64:
|
||||
IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
|
||||
"4.2.1",
|
||||
"powerpc-apple-darwin10",
|
||||
arch == llvm::Triple::ppc64 ? "ppc64" : "");
|
||||
IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx,
|
||||
"4.0.0", "powerpc-apple-darwin10",
|
||||
arch == llvm::Triple::ppc64 ? "ppc64" : "");
|
||||
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);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -503,6 +503,9 @@ public:
|
||||
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;
|
||||
|
||||
@@ -529,6 +532,13 @@ private:
|
||||
llvm::opt::ArgStringList &CmdArgs,
|
||||
StringRef Sanitizer,
|
||||
bool shared = true) const;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
} // end namespace toolchains
|
||||
|
||||
@@ -210,6 +210,10 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
|
||||
const HeaderSearchOptions &HSOpts) {
|
||||
llvm::Triple::OSType os = triple.getOS();
|
||||
|
||||
if (triple.isOSDarwin()) {
|
||||
llvm_unreachable("Include management is handled in the driver.");
|
||||
}
|
||||
|
||||
if (HSOpts.UseStandardSystemIncludes) {
|
||||
switch (os) {
|
||||
case llvm::Triple::CloudABI:
|
||||
@@ -365,49 +369,7 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(
|
||||
// FIXME: temporary hack: hard-coded paths.
|
||||
|
||||
if (triple.isOSDarwin()) {
|
||||
bool IsBaseFound = true;
|
||||
switch (triple.getArch()) {
|
||||
default: break;
|
||||
|
||||
case llvm::Triple::ppc:
|
||||
case llvm::Triple::ppc64:
|
||||
IsBaseFound = AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
|
||||
"powerpc-apple-darwin10", "",
|
||||
"ppc64", triple);
|
||||
IsBaseFound |= AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
|
||||
"powerpc-apple-darwin10", "",
|
||||
"ppc64", triple);
|
||||
break;
|
||||
|
||||
case llvm::Triple::x86:
|
||||
case llvm::Triple::x86_64:
|
||||
IsBaseFound = AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
|
||||
"i686-apple-darwin10", "",
|
||||
"x86_64", triple);
|
||||
IsBaseFound |= AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/include/c++/4.0.0", "i686-apple-darwin8", "", "", triple);
|
||||
break;
|
||||
|
||||
case llvm::Triple::arm:
|
||||
case llvm::Triple::thumb:
|
||||
IsBaseFound = AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/include/c++/4.2.1", "arm-apple-darwin10", "v7", "", triple);
|
||||
IsBaseFound |= AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/include/c++/4.2.1", "arm-apple-darwin10", "v6", "", triple);
|
||||
break;
|
||||
|
||||
case llvm::Triple::aarch64:
|
||||
IsBaseFound = AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/include/c++/4.2.1", "arm64-apple-darwin10", "", "", triple);
|
||||
break;
|
||||
}
|
||||
// Warn when compiling pure C++ / Objective-C++ only.
|
||||
if (!IsBaseFound &&
|
||||
!(LangOpts.CUDA || LangOpts.OpenCL || LangOpts.RenderScript)) {
|
||||
Headers.getDiags().Report(SourceLocation(),
|
||||
diag::warn_stdlibcxx_not_found);
|
||||
}
|
||||
return;
|
||||
llvm_unreachable("Include management is handled in the driver.");
|
||||
}
|
||||
|
||||
switch (os) {
|
||||
@@ -464,6 +426,16 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
|
||||
break;
|
||||
}
|
||||
|
||||
// All header search logic is handled in the Driver for Darwin.
|
||||
if (triple.isOSDarwin()) {
|
||||
if (HSOpts.UseStandardSystemIncludes) {
|
||||
// Add the default framework include paths on Darwin.
|
||||
AddPath("/System/Library/Frameworks", System, true);
|
||||
AddPath("/Library/Frameworks", System, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Lang.CPlusPlus && !Lang.AsmPreprocessor &&
|
||||
HSOpts.UseStandardCXXIncludes && HSOpts.UseStandardSystemIncludes) {
|
||||
if (HSOpts.UseLibcxx) {
|
||||
@@ -474,14 +446,6 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
|
||||
}
|
||||
|
||||
AddDefaultCIncludePaths(triple, HSOpts);
|
||||
|
||||
// Add the default framework include paths on Darwin.
|
||||
if (HSOpts.UseStandardSystemIncludes) {
|
||||
if (triple.isOSDarwin()) {
|
||||
AddPath("/System/Library/Frameworks", System, true);
|
||||
AddPath("/Library/Frameworks", System, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// RemoveDuplicates - If there are duplicate directory entries in the specified
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user