aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Driver/Driver.cpp
diff options
context:
space:
mode:
authorMichał Górny <mgorny@gentoo.org>2022-09-29 20:58:35 +0200
committerMichał Górny <mgorny@gentoo.org>2022-09-29 20:58:59 +0200
commit063e17d8b04b41cd8bd174aebb6603eb1a76d34a (patch)
tree1d36713e90bfe0fd64d67a2af49c83bebd215234 /clang/lib/Driver/Driver.cpp
parent062e515b701930a17e3d6b75b3a27cb4d9a6f984 (diff)
downloadllvm-063e17d8b04b41cd8bd174aebb6603eb1a76d34a.zip
llvm-063e17d8b04b41cd8bd174aebb6603eb1a76d34a.tar.gz
llvm-063e17d8b04b41cd8bd174aebb6603eb1a76d34a.tar.bz2
[clang] [Driver] More flexible rules for loading default configs
Change the default config file loading logic to be more flexible and more readable at the same time. The new algorithm focuses on four locations, in order: 1. <triple>-<mode>.cfg using real driver mode 2. <triple>-<mode>.cfg using executable suffix 3. <triple>.cfg + <mode>.cfg using real driver mode 4. <triple>.cfg + <mode>.cfg using executable suffix This is meant to preserve reasonable level of compatibility with the existing use, while introducing more flexibility and making the code simpler. Notably: 1. In this layout, the actual target triple is normally respected, and e.g. in `-m32` build the `x86_64-*` configs will never be used. 2. Both real driver mode (preferable) and executable suffix are supported. This permits correctly handling calls with explicit `--driver-mode=` while at the same time preserving compatibility with the existing code. 3. The first two locations provide users with the ability to override configuration per specific target+mode combinaton, while the next two make it possible to independently specify per-target and per-mode configuration. 4. All config file locations are applicable independently of whether clang is started via a prefixed executable, or bare `clang`. 5. If the target is not explicitly specified and the executable prefix does not name a valid triple, it is used instead of the actual target triple for backwards compatibility. This is particularly meant to address Gentoo's use case for configuration files: to configure the default runtimes (i.e. `-rtlib=`, `-stdlib=`) and `--gcc-install-dir=` for all the relevant drivers, as well as to make it more convenient for users to override `-W` flags to test compatibility with future versions of Clang easier. Differential Revision: https://reviews.llvm.org/D134337
Diffstat (limited to 'clang/lib/Driver/Driver.cpp')
-rw-r--r--clang/lib/Driver/Driver.cpp140
1 files changed, 77 insertions, 63 deletions
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index f2ae25d..b8ef379 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1068,79 +1068,74 @@ bool Driver::loadConfigFiles() {
bool Driver::loadDefaultConfigFiles(ArrayRef<StringRef> CfgFileSearchDirs) {
if (CLOptions && CLOptions->hasArg(options::OPT_no_default_config))
return false;
- if (ClangNameParts.TargetPrefix.empty())
- return false;
- // If config file is not specified explicitly, try to deduce configuration
- // from executable name. For instance, an executable 'armv7l-clang' will
- // search for config file 'armv7l-clang.cfg'.
- std::string CfgFileName =
- ClangNameParts.TargetPrefix + '-' + ClangNameParts.ModeSuffix;
-
- // Determine architecture part of the file name, if it is present.
- StringRef CfgFileArch = CfgFileName;
- size_t ArchPrefixLen = CfgFileArch.find('-');
- if (ArchPrefixLen == StringRef::npos)
- ArchPrefixLen = CfgFileArch.size();
- llvm::Triple CfgTriple;
- CfgFileArch = CfgFileArch.take_front(ArchPrefixLen);
- CfgTriple = llvm::Triple(llvm::Triple::normalize(CfgFileArch));
- if (CfgTriple.getArch() == llvm::Triple::ArchType::UnknownArch)
- ArchPrefixLen = 0;
-
- if (!StringRef(CfgFileName).endswith(".cfg"))
- CfgFileName += ".cfg";
-
- // If config file starts with architecture name and command line options
- // redefine architecture (with options like -m32 -LE etc), try finding new
- // config file with that architecture.
- SmallString<128> FixedConfigFile;
- size_t FixedArchPrefixLen = 0;
- if (ArchPrefixLen) {
- // Get architecture name from config file name like 'i386.cfg' or
- // 'armv7l-clang.cfg'.
- // Check if command line options changes effective triple.
- llvm::Triple EffectiveTriple =
- computeTargetTriple(*this, CfgTriple.getTriple(), *CLOptions);
- if (CfgTriple.getArch() != EffectiveTriple.getArch()) {
- FixedConfigFile = EffectiveTriple.getArchName();
- FixedArchPrefixLen = FixedConfigFile.size();
- // Append the rest of original file name so that file name transforms
- // like: i386-clang.cfg -> x86_64-clang.cfg.
- if (ArchPrefixLen < CfgFileName.size())
- FixedConfigFile += CfgFileName.substr(ArchPrefixLen);
- }
- }
-
- // Try to find config file. First try file with corrected architecture.
+ std::string RealMode = getExecutableForDriverMode(Mode);
+ std::string Triple;
+
+ // If name prefix is present, no --target= override was passed via CLOptions
+ // and the name prefix is not a valid triple, force it for backwards
+ // compatibility.
+ if (!ClangNameParts.TargetPrefix.empty() &&
+ computeTargetTriple(*this, "/invalid/", *CLOptions).str() ==
+ "/invalid/") {
+ llvm::Triple PrefixTriple{ClangNameParts.TargetPrefix};
+ if (PrefixTriple.getArch() == llvm::Triple::UnknownArch ||
+ PrefixTriple.isOSUnknown())
+ Triple = PrefixTriple.str();
+ }
+
+ // Otherwise, use the real triple as used by the driver.
+ if (Triple.empty()) {
+ llvm::Triple RealTriple =
+ computeTargetTriple(*this, TargetTriple, *CLOptions);
+ Triple = RealTriple.str();
+ assert(!Triple.empty());
+ }
+
+ // Search for config files in the following order:
+ // 1. <triple>-<mode>.cfg using real driver mode
+ // (e.g. i386-pc-linux-gnu-clang++.cfg).
+ // 2. <triple>-<mode>.cfg using executable suffix
+ // (e.g. i386-pc-linux-gnu-clang-g++.cfg for *clang-g++).
+ // 3. <triple>.cfg + <mode>.cfg using real driver mode
+ // (e.g. i386-pc-linux-gnu.cfg + clang++.cfg).
+ // 4. <triple>.cfg + <mode>.cfg using executable suffix
+ // (e.g. i386-pc-linux-gnu.cfg + clang-g++.cfg for *clang-g++).
+
+ // Try loading <triple>-<mode>.cfg, and return if we find a match.
llvm::SmallString<128> CfgFilePath;
- if (!FixedConfigFile.empty()) {
- if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile,
- getVFS()))
- return readConfigFile(CfgFilePath);
- // If 'x86_64-clang.cfg' was not found, try 'x86_64.cfg'.
- FixedConfigFile.resize(FixedArchPrefixLen);
- FixedConfigFile.append(".cfg");
- if (searchForFile(CfgFilePath, CfgFileSearchDirs, FixedConfigFile,
- getVFS()))
- return readConfigFile(CfgFilePath);
- }
-
- // Then try original file name.
+ std::string CfgFileName = Triple + '-' + RealMode + ".cfg";
if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS()))
return readConfigFile(CfgFilePath);
- // Finally try removing driver mode part: 'x86_64-clang.cfg' -> 'x86_64.cfg'.
- if (!ClangNameParts.ModeSuffix.empty() &&
- !ClangNameParts.TargetPrefix.empty()) {
- CfgFileName.assign(ClangNameParts.TargetPrefix);
- CfgFileName.append(".cfg");
+ bool TryModeSuffix = !ClangNameParts.ModeSuffix.empty() &&
+ ClangNameParts.ModeSuffix != RealMode;
+ if (TryModeSuffix) {
+ CfgFileName = Triple + '-' + ClangNameParts.ModeSuffix + ".cfg";
if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS()))
return readConfigFile(CfgFilePath);
}
+ // Try loading <mode>.cfg, and return if loading failed. If a matching file
+ // was not found, still proceed on to try <triple>.cfg.
+ CfgFileName = RealMode + ".cfg";
+ if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS())) {
+ if (readConfigFile(CfgFilePath))
+ return true;
+ } else if (TryModeSuffix) {
+ CfgFileName = ClangNameParts.ModeSuffix + ".cfg";
+ if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS()) &&
+ readConfigFile(CfgFilePath))
+ return true;
+ }
+
+ // Try loading <triple>.cfg and return if we find a match.
+ CfgFileName = Triple + ".cfg";
+ if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS()))
+ return readConfigFile(CfgFilePath);
+
// If we were unable to find a config file deduced from executable name,
- // do not report an error.
+ // that is not an error.
return false;
}
@@ -6201,6 +6196,25 @@ Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const {
return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask);
}
+const char *Driver::getExecutableForDriverMode(DriverMode Mode) {
+ switch (Mode) {
+ case GCCMode:
+ return "clang";
+ case GXXMode:
+ return "clang++";
+ case CPPMode:
+ return "clang-cpp";
+ case CLMode:
+ return "clang-cl";
+ case FlangMode:
+ return "flang";
+ case DXCMode:
+ return "clang-dxc";
+ }
+
+ llvm_unreachable("Unhandled Mode");
+}
+
bool clang::driver::isOptimizationLevelFast(const ArgList &Args) {
return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group, false);
}