This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG063e17d8b04b: [clang] [Driver] More flexible rules for
loading default configs (authored by mgorny).
Herald added a project: clang.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D134337/new/
https://reviews.llvm.org/D134337
Files:
clang/docs/ReleaseNotes.rst
clang/docs/UsersManual.rst
clang/include/clang/Driver/Driver.h
clang/lib/Driver/Driver.cpp
clang/test/Driver/config-file3.c
Index: clang/test/Driver/config-file3.c
===================================================================
--- clang/test/Driver/config-file3.c
+++ clang/test/Driver/config-file3.c
@@ -9,112 +9,256 @@
// RUN: echo "@subdir/cfg-s2" > %t/workdir/cfg-1
// RUN: echo "-Wundefined-var-template" > %t/workdir/subdir/cfg-s2
//
-// RUN: ( cd %t && %clang --config workdir/cfg-1 -c -### %s 2>&1 | FileCheck %s -check-prefix CHECK-REL )
+// RUN: ( cd %t && %clang --config=workdir/cfg-1 -c -### %s 2>&1 | FileCheck %s -check-prefix CHECK-REL )
//
// CHECK-REL: Configuration file: {{.*}}/workdir/cfg-1
// CHECK-REL: -Wundefined-var-template
+//--- Config files are searched for in binary directory as well.
+//
+// RUN: mkdir %t/testbin
+// RUN: ln -s %clang %t/testbin/clang
+// RUN: echo "-Werror" > %t/testbin/aaa.cfg
+// RUN: %t/testbin/clang --config-system-dir= --config-user-dir= --config=aaa.cfg -c -no-canonical-prefixes -### %s 2>&1 | FileCheck %s -check-prefix CHECK-BIN
+//
+// CHECK-BIN: Configuration file: {{.*}}/testbin/aaa.cfg
+// CHECK-BIN: -Werror
-//--- Invocation qqq-clang-g++ tries to find config file qqq-clang-g++.cfg first.
+//--- Invocation x86_64-unknown-linux-gnu-clang-g++ tries x86_64-unknown-linux-gnu-clang++.cfg first.
//
// RUN: mkdir %t/testdmode
+// RUN: ln -s %clang %t/testdmode/cheribsd-riscv64-hybrid-clang++
// RUN: ln -s %clang %t/testdmode/qqq-clang-g++
-// RUN: echo "-Wundefined-func-template" > %t/testdmode/qqq-clang-g++.cfg
-// RUN: echo "-Werror" > %t/testdmode/qqq.cfg
-// RUN: %t/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir= -c -no-canonical-prefixes -### %s 2>&1 | FileCheck %s -check-prefix FULL-NAME
+// RUN: ln -s %clang %t/testdmode/x86_64-clang
+// RUN: ln -s %clang %t/testdmode/i386-unknown-linux-gnu-clang-g++
+// RUN: ln -s %clang %t/testdmode/x86_64-unknown-linux-gnu-clang-g++
+// RUN: ln -s %clang %t/testdmode/x86_64-unknown-linux-gnu-clang
+// RUN: touch %t/testdmode/cheribsd-riscv64-hybrid-clang++.cfg
+// RUN: touch %t/testdmode/cheribsd-riscv64-hybrid.cfg
+// RUN: touch %t/testdmode/qqq-clang-g++.cfg
+// RUN: touch %t/testdmode/qqq.cfg
+// RUN: touch %t/testdmode/x86_64-clang.cfg
+// RUN: touch %t/testdmode/x86_64.cfg
+// RUN: touch %t/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// RUN: touch %t/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// RUN: touch %t/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// RUN: touch %t/testdmode/x86_64-unknown-linux-gnu.cfg
+// RUN: touch %t/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// RUN: touch %t/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// RUN: touch %t/testdmode/i386-unknown-linux-gnu-clang.cfg
+// RUN: touch %t/testdmode/i386-unknown-linux-gnu.cfg
+// RUN: touch %t/testdmode/clang++.cfg
+// RUN: touch %t/testdmode/clang-g++.cfg
+// RUN: touch %t/testdmode/clang.cfg
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL1
+//
+// FULL1-NOT: Configuration file:
+// FULL1: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// FULL1-NOT: Configuration file:
+
+//--- -m32 overrides triple.
+//
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ -m32 --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL1-I386
+//
+// FULL1-I386-NOT: Configuration file:
+// FULL1-I386: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// FULL1-I386-NOT: Configuration file:
+
+//--- --target= also works for overriding triple.
+//
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ --target=i386-unknown-linux-gnu --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL1-I386
+
+//--- With --target= + -m64, -m64 takes precedence.
+//
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ --target=i386-unknown-linux-gnu -m64 --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL1
+
+//--- i386 prefix also works for 32-bit.
+//
+// RUN: %t/testdmode/i386-unknown-linux-gnu-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL1-I386
+
+//--- i386 prefix + -m64 also works for 64-bit.
+//
+// RUN: %t/testdmode/i386-unknown-linux-gnu-clang-g++ -m64 --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL1
+
+//--- File specified by --config= is loaded after the one inferred from the executable.
//
-// FULL-NAME: Configuration file: {{.*}}/testdmode/qqq-clang-g++.cfg
-// FULL-NAME: -Wundefined-func-template
-// FULL-NAME-NOT: -Werror
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ --config-system-dir=%S/Inputs/config --config-user-dir= --config=i386-qqq.cfg -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix EXPLICIT
//
-//--- Invocation qqq-clang-g++ tries to find config file qqq-clang-g++.cfg even without -no-canonical-prefixes.
-// (As the clang executable and symlink are in different directories, this
-// requires specifying the path via --config-*-dir= though.)
+// EXPLICIT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// EXPLICIT-NEXT: Configuration file: {{.*}}/Inputs/config/i386-qqq.cfg
+
+//--- --no-default-config --config= loads only specified file.
//
-// RUN: %t/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir=%t/testdmode -c -### %s 2>&1 | FileCheck %s -check-prefix SYMLINK
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ --config-system-dir=%S/Inputs/config --config-user-dir= --no-default-config --config=i386-qqq.cfg -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix EXPLICIT-ONLY
//
-// SYMLINK: Configuration file: {{.*}}/testdmode/qqq-clang-g++.cfg
+// EXPLICIT-ONLY-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// EXPLICIT-ONLY: Configuration file: {{.*}}/Inputs/config/i386-qqq.cfg
-//--- File specified by --config is loaded after the one inferred from the executable.
+//--- --no-default-config disables default filenames.
//
-// RUN: %t/testdmode/qqq-clang-g++ --config-system-dir=%S/Inputs/config --config-user-dir= --config i386-qqq.cfg -c -no-canonical-prefixes -### %s 2>&1 | FileCheck %s -check-prefix CHECK-EXPLICIT
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ --config-system-dir=%S/Inputs/config --config-user-dir= --no-default-config -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix NO-CONFIG
//
-// CHECK-EXPLICIT: Configuration file: {{.*}}/testdmode/qqq-clang-g++.cfg
-// CHECK-EXPLICIT-NEXT: Configuration file: {{.*}}/Inputs/config/i386-qqq.cfg
+// NO-CONFIG-NOT: Configuration file:
-//--- --no-default-config disables config search.
+//--- --driver-mode= is respected.
+//
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ --driver-mode=gcc --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL1-GCC
//
-// RUN: %t/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir=%t/testdmode --no-default-config -c -### %s 2>&1 | FileCheck %s -check-prefix NO-DEFAULT-CONFIG
+// FULL1-GCC-NOT: Configuration file:
+// FULL1-GCC: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// FULL1-GCC-NOT: Configuration file:
+
+//--- "clang" driver symlink should yield the "*-clang" configuration file.
//
-// NO-DEFAULT-CONFIG-NOT: Configuration file:
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL1-GCC
-//--- Explicit --config works with --no-default-config.
+//--- "clang" + --driver-mode= should yield "*-clang++".
//
-// RUN: %t/testdmode/qqq-clang-g++ --config-system-dir=%S/Inputs/config --config-user-dir= --no-default-config --config i386-qqq.cfg -c -no-canonical-prefixes -### %s 2>&1 | FileCheck %s -check-prefix CHECK-EXPLICIT-NO-DEFAULT
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang --driver-mode=g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL1
+
+//--- Clang started via name prefix that is not valid is forcing that prefix instead of target triple.
+//
+// RUN: %t/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix QQQ
+//
+// QQQ-NOT: Configuration file:
+// QQQ: Configuration file: {{.*}}/testdmode/qqq-clang-g++.cfg
+// QQQ-NOT: Configuration file:
+
+//--- Explicit --target= overrides the triple even with non-standard name prefix.
//
-// CHECK-EXPLICIT-NO-DEFAULT-NOT: Configuration file: {{.*}}/testdmode/qqq-clang-g++.cfg
-// CHECK-EXPLICIT-NO-DEFAULT: Configuration file: {{.*}}/Inputs/config/i386-qqq.cfg
+// RUN: %t/testdmode/qqq-clang-g++ --target=x86_64-unknown-linux-gnu --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL1
-//--- Invocation qqq-clang-g++ tries to find config file qqq.cfg if qqq-clang-g++.cfg is not found.
+//--- "x86_64" prefix does not form a valid triple either.
//
+// RUN: %t/testdmode/x86_64-clang --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix X86_64
+//
+// X86_64-NOT: Configuration file:
+// X86_64: Configuration file: {{.*}}/testdmode/x86_64-clang.cfg
+// X86_64-NOT: Configuration file:
+
+//--- Try cheribsd prefix using misordered triple components.
+//
+// RUN: %t/testdmode/cheribsd-riscv64-hybrid-clang++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix CHERIBSD
+//
+// CHERIBSD-NOT: Configuration file:
+// CHERIBSD: Configuration file: {{.*}}/testdmode/cheribsd-riscv64-hybrid-clang++.cfg
+// CHERIBSD-NOT: Configuration file:
+
+//--- Test fallback to x86_64-unknown-linux-gnu-clang-g++.cfg.
+//
+// RUN: rm %t/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// RUN: rm %t/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL2
+//
+// FULL2-NOT: Configuration file:
+// FULL2: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// FULL2-NOT: Configuration file:
+
+//--- FULL2 + -m32.
+//
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ -m32 --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL2-I386
+//
+// FULL2-I386-NOT: Configuration file:
+// FULL2-I386: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// FULL2-I386-NOT: Configuration file:
+
+//--- Test fallback to x86_64-unknown-linux-gnu-clang.cfg + clang++.cfg.
+//
+// RUN: rm %t/testdmode/cheribsd-riscv64-hybrid-clang++.cfg
// RUN: rm %t/testdmode/qqq-clang-g++.cfg
-// RUN: %t/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir= -c -no-canonical-prefixes -### %s 2>&1 | FileCheck %s -check-prefix SHORT-NAME
+// RUN: rm %t/testdmode/x86_64-clang.cfg
+// RUN: rm %t/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// RUN: rm %t/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// RUN: rm %t/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// RUN: rm %t/testdmode/i386-unknown-linux-gnu-clang.cfg
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL3
//
-// SHORT-NAME: Configuration file: {{.*}}/testdmode/qqq.cfg
-// SHORT-NAME: -Werror
-// SHORT-NAME-NOT: -Wundefined-func-template
+// FULL3-NOT: Configuration file:
+// FULL3: Configuration file: {{.*}}/testdmode/clang++.cfg
+// FULL3-NOT: Configuration file:
+// FULL3: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL3-NOT: Configuration file:
+//--- FULL3 + -m32.
+//
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ -m32 --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL3-I386
+//
+// FULL3-I386-NOT: Configuration file:
+// FULL3-I386: Configuration file: {{.*}}/testdmode/clang++.cfg
+// FULL3-I386-NOT: Configuration file:
+// FULL3-I386: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu.cfg
+// FULL3-I386-NOT: Configuration file:
-//--- Config files are searched for in binary directory as well.
+//--- FULL3 + --driver-mode=.
//
-// RUN: mkdir %t/testbin
-// RUN: ln -s %clang %t/testbin/clang
-// RUN: echo "-Werror" > %t/testbin/aaa.cfg
-// RUN: %t/testbin/clang --config-system-dir= --config-user-dir= --config aaa.cfg -c -no-canonical-prefixes -### %s 2>&1 | FileCheck %s -check-prefix CHECK-BIN
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ --driver-mode=gcc --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL3-GCC
//
-// CHECK-BIN: Configuration file: {{.*}}/testbin/aaa.cfg
-// CHECK-BIN: -Werror
+// FULL3-GCC-NOT: Configuration file:
+// FULL3-GCC: Configuration file: {{.*}}/testdmode/clang.cfg
+// FULL3-GCC-NOT: Configuration file:
+// FULL3-GCC: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL3-GCC-NOT: Configuration file:
+//--- QQQ fallback.
+//
+// RUN: %t/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix QQQ-FALLBACK
+//
+// QQQ-FALLBACK-NOT: Configuration file:
+// QQQ-FALLBACK: Configuration file: {{.*}}/testdmode/clang++.cfg
+// QQQ-FALLBACK-NOT: Configuration file:
+// QQQ-FALLBACK: Configuration file: {{.*}}/testdmode/qqq.cfg
+// QQQ-FALLBACK-NOT: Configuration file:
-//--- If command line contains options that change triple (for instance, -m32), clang tries
-// reloading config file.
+//--- "x86_64" falback.
+//
+// RUN: %t/testdmode/x86_64-clang --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix X86_64-FALLBACK
+//
+// X86_64-FALLBACK-NOT: Configuration file:
+// X86_64-FALLBACK: Configuration file: {{.*}}/testdmode/clang.cfg
+// X86_64-FALLBACK-NOT: Configuration file:
+// X86_64-FALLBACK: Configuration file: {{.*}}/testdmode/x86_64.cfg
+// X86_64-FALLBACK-NOT: Configuration file:
-//--- When reloading config file, x86_64-clang-g++ tries to find config i386-clang-g++.cfg first.
+//--- cheribsd fallback.
//
-// RUN: mkdir %t/testreload
-// RUN: ln -s %clang %t/testreload/x86_64-clang-g++
-// RUN: echo "-Wundefined-func-template" > %t/testreload/i386-clang-g++.cfg
-// RUN: echo "-Werror" > %t/testreload/i386.cfg
-// RUN: echo "-Wall" > %t/testreload/x86_64-clang-g++.cfg
-// RUN: %t/testreload/x86_64-clang-g++ --config-system-dir= --config-user-dir= -c -m32 -no-canonical-prefixes -### %s 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD
+// RUN: %t/testdmode/cheribsd-riscv64-hybrid-clang++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix CHERIBSD-FALLBACK
//
-// CHECK-RELOAD: Configuration file: {{.*}}/testreload/i386-clang-g++.cfg
-// CHECK-RELOAD: -Wundefined-func-template
-// CHECK-RELOAD-NOT: -Werror
-// CHECK-RELOAD-NOT: -Wall
+// CHERIBSD-FALLBACK-NOT: Configuration file:
+// CHERIBSD-FALLBACK: Configuration file: {{.*}}/testdmode/clang++.cfg
+// CHERIBSD-FALLBACK-NOT: Configuration file:
+// CHERIBSD-FALLBACK: Configuration file: {{.*}}/testdmode/cheribsd-riscv64-hybrid.cfg
+// CHERIBSD-FALLBACK-NOT: Configuration file:
-//--- Same for -target in place of -m32.
-// RUN: %t/testreload/x86_64-clang-g++ --config-system-dir= --config-user-dir= -c -target i386 -no-canonical-prefixes -### %s 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD
+//--- Test fallback to x86_64-unknown-linux-gnu.cfg + clang-g++.cfg.
+//
+// RUN: rm %t/testdmode/clang++.cfg
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL4
+//
+// FULL4-NOT: Configuration file:
+// FULL4: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL4-NOT: Configuration file:
+// FULL4: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL4-NOT: Configuration file:
-//--- `-target i386 -m64` should load the 64-bit config.
-// RUN: %t/testreload/x86_64-clang-g++ --config-system-dir= --config-user-dir= -c -target i386 -m64 -no-canonical-prefixes -### %s 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1a
+//--- Test fallback to clang-g++.cfg if x86_64-unknown-linux-gnu-clang.cfg does not exist.
+//
+// RUN: rm %t/testdmode/x86_64-unknown-linux-gnu.cfg
+// RUN: rm %t/testdmode/i386-unknown-linux-gnu.cfg
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL5
//
-// CHECK-RELOAD1a: Configuration file: {{.*}}/testreload/x86_64-clang-g++.cfg
-// CHECK-RELOAD1a: -Wall
-// CHECK-RELOAD1a-NOT: -Werror
-// CHECK-RELOAD1a-NOT: -Wundefined-func-template
+// FULL5-NOT: Configuration file:
+// FULL5: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL5-NOT: Configuration file:
-//--- x86_64-clang-g++ tries to find config i386.cfg if i386-clang-g++.cfg is not found.
+//--- FULL5 + -m32.
//
-// RUN: rm %t/testreload/i386-clang-g++.cfg
-// RUN: %t/testreload/x86_64-clang-g++ --config-system-dir= --config-user-dir= -c -m32 -no-canonical-prefixes -### %s 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1d
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ -m32 --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL5-I386
//
-// CHECK-RELOAD1d: Configuration file: {{.*}}/testreload/i386.cfg
-// CHECK-RELOAD1d: -Werror
-// CHECK-RELOAD1d-NOT: -Wundefined-func-template
-// CHECK-RELOAD1d-NOT: -Wall
+// FULL5-I386-NOT: Configuration file:
+// FULL5-I386: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL5-I386-NOT: Configuration file:
-//--- x86_64-clang-g++ uses x86_64-clang-g++.cfg if i386*.cfg are not found.
+//--- Test that incorrect driver mode config file is not used.
//
-// RUN: rm %t/testreload/i386.cfg
-// RUN: %t/testreload/x86_64-clang-g++ --config-system-dir= --config-user-dir= -c -m32 -no-canonical-prefixes -### %s 2>&1 | FileCheck %s -check-prefix CHECK-RELOAD1a
+// RUN: rm %t/testdmode/clang-g++.cfg
+// RUN: %t/testdmode/x86_64-unknown-linux-gnu-clang-g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix NO-CONFIG
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -1068,79 +1068,74 @@
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 @@
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);
}
Index: clang/include/clang/Driver/Driver.h
===================================================================
--- clang/include/clang/Driver/Driver.h
+++ clang/include/clang/Driver/Driver.h
@@ -731,6 +731,9 @@
&CachedResults,
Action::OffloadKind TargetDeviceOffloadKind) const;
+ /// Return the typical executable name for the specified driver \p Mode.
+ static const char *getExecutableForDriverMode(DriverMode Mode);
+
public:
/// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and
/// return the grouped values as integers. Numbers which are not
Index: clang/docs/UsersManual.rst
===================================================================
--- clang/docs/UsersManual.rst
+++ clang/docs/UsersManual.rst
@@ -914,27 +914,55 @@
configuration files can be disabled entirely via passing
the ``--no-default-config`` flag.
-The name of the default configuration file is deduced from the clang executable
-name. For example, if the Clang executable is named ``armv7l-clang`` (it may
-be a symbolic link to ``clang``), then Clang will search for file
-``armv7l.cfg`` in the directory where Clang resides.
+First, the algorithm searches for a configuration file named
+``<triple>-<driver>.cfg`` where `triple` is the triple for the target being
+built for, and `driver` is the name of the currently used driver. The algorithm
+first attempts to use the canonical name for the driver used, then falls back
+to the one found in the executable name.
-If a driver mode is specified in invocation, Clang tries to find a file specific
-for the specified mode. For example, if the executable file is named
-``x86_64-clang-cl``, Clang first looks for ``x86_64-clang-cl.cfg`` and if it is
-not found, looks for ``x86_64.cfg``.
+The following canonical driver names are used:
-If the command line contains options that effectively change target architecture
-(these are ``-m32``, ``-EL``, and some others) and the configuration file starts
-with an architecture name, Clang tries to load the configuration file for the
-effective architecture. For example, invocation:
+- ``clang`` for the ``gcc`` driver (used to compile C programs)
+- ``clang++`` for the ``gxx`` driver (used to compile C++ programs)
+- ``clang-cpp`` for the ``cpp`` driver (pure preprocessor)
+- ``clang-cl`` for the ``cl`` driver
+- ``flang`` for the ``flang`` driver
+- ``clang-dxc`` for the ``dxc`` driver
-::
+For example, when calling ``x86_64-pc-linux-gnu-clang-g++``,
+the driver will first attempt to use the configuration file named::
+
+ x86_64-pc-linux-gnu-clang++.cfg
+
+If this file is not found, it will attempt to use the name found
+in the executable instead::
+
+ x86_64-pc-linux-gnu-clang-g++.cfg
+
+Note that options such as ``--driver-mode=``, ``--target=``, ``-m32`` affect
+the search algorithm. For example, the aforementioned executable called with
+``-m32`` argument will instead search for::
+
+ i386-pc-linux-gnu-clang++.cfg
+
+If none of the aforementioned files are found, the driver will instead search
+for separate driver and target configuration files and attempt to load both.
+The former is named ``<driver>.cfg`` while the latter is named
+``<triple>.cfg``. Similarly to the previous variants, the canonical driver name
+will be preferred, and the compiler will fall back to the actual name.
+
+For example, ``x86_64-pc-linux-gnu-clang-g++`` will attempt to load two
+configuration files named respectively::
+
+ clang++.cfg
+ x86_64-pc-linux-gnu.cfg
+
+with fallback to trying::
- x86_64-clang -m32 abc.c
+ clang-g++.cfg
+ x86_64-pc-linux-gnu.cfg
-causes Clang search for a file ``i368.cfg`` first, and if no such file is found,
-Clang looks for the file ``x86_64.cfg``.
+It is not an error if either of these files is not found.
The configuration file consists of command-line options specified on one or
more lines. Lines composed of whitespace characters only are ignored as well as
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -242,6 +242,21 @@
- Unicode support has been updated to support Unicode 15.0.
New unicode codepoints are supported as appropriate in diagnostics,
C and C++ identifiers, and escape sequences.
+- Clang now supports loading multiple configuration files. The files from
+ default configuration paths are loaded first, unless ``--no-default-config``
+ option is used. All files explicitly specified using ``--config=`` option
+ are loaded afterwards.
+- When loading default configuration files, clang now unconditionally uses
+ the real target triple (respecting options such as ``--target=`` and ``-m32``)
+ rather than the executable prefix. The respective configuration files are
+ also loaded when clang is called via an executable without a prefix (e.g.
+ plain ``clang``).
+- Default configuration paths were partially changed. Clang now attempts to load
+ ``<triple>-<driver>.cfg`` first, and falls back to loading both
+ ``<driver>.cfg`` and ``<triple>.cfg`` if the former is not found. `Triple`
+ is the target triple and `driver` first tries the canonical name
+ for the driver (respecting ``--driver-mode=``), and then the name found
+ in the executable.
New Compiler Flags
------------------
@@ -257,12 +272,16 @@
`::operator new(size_Ât, std::aligned_val_t, nothrow_Ât)` if there is
`get_Âreturn_Âobject_Âon_Âallocation_Âfailure`. We feel this is more consistent
with the intention.
+- Added ``--no-default-config`` to disable automatically loading configuration
+ files using default paths.
Deprecated Compiler Flags
-------------------------
Modified Compiler Flags
-----------------------
+- Clang now permits specifying ``--config=`` multiple times, to load multiple
+ configuration files.
Removed Compiler Flags
-------------------------
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits