mgorny updated this revision to Diff 463288.
mgorny added a comment.

Added doc update. Would use some help with release notes.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134337/new/

https://reviews.llvm.org/D134337

Files:
  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
@@ -14,107 +14,261 @@
 // 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/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/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: echo > %t/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// RUN: echo > %t/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// RUN: echo > %t/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// RUN: echo > %t/testdmode/x86_64-unknown-linux-gnu.cfg
+// RUN: echo > %t/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// RUN: echo > %t/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// RUN: echo > %t/testdmode/i386-unknown-linux-gnu-clang.cfg
+// RUN: echo > %t/testdmode/i386-unknown-linux-gnu.cfg
+// RUN: echo > %t/testdmode/clang++.cfg
+// RUN: echo > %t/testdmode/clang-g++.cfg
+// RUN: echo > %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
 //
-// FULL-NAME: Configuration file: {{.*}}/testdmode/qqq-clang-g++.cfg
-// FULL-NAME: -Wundefined-func-template
-// FULL-NAME-NOT: -Werror
+// FULL1: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// FULL1-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// FULL1-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// FULL1-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL1-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// FULL1-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// FULL1-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang.cfg
+// FULL1-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu.cfg
+// FULL1-NOT: Configuration file: {{.*}}/testdmode/clang++.cfg
+// FULL1-NOT: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL1-NOT: Configuration file: {{.*}}/testdmode/clang.cfg
+
+//--- -m32 overrides triple.
 //
-//--- 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.)
+// 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
 //
-// RUN: %t/testdmode/qqq-clang-g++ --config-system-dir= --config-user-dir=%t/testdmode -c -### %s 2>&1 | FileCheck %s -check-prefix SYMLINK
+// FULL1-I386-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// FULL1-I386-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// FULL1-I386-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// FULL1-I386-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL1-I386: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// FULL1-I386-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// FULL1-I386-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang.cfg
+// FULL1-I386-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu.cfg
+// FULL1-I386-NOT: Configuration file: {{.*}}/testdmode/clang++.cfg
+// FULL1-I386-NOT: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL1-I386-NOT: Configuration file: {{.*}}/testdmode/clang.cfg
+
+//--- -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.
 //
-// SYMLINK: Configuration file: {{.*}}/testdmode/qqq-clang-g++.cfg
+// 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.
 //
-// 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= --config i386-qqq.cfg -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix EXPLICIT
 //
-// CHECK-EXPLICIT: Configuration file: {{.*}}/testdmode/qqq-clang-g++.cfg
-// CHECK-EXPLICIT-NEXT: Configuration file: {{.*}}/Inputs/config/i386-qqq.cfg
+// EXPLICIT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// EXPLICIT-NEXT: Configuration file: {{.*}}/Inputs/config/i386-qqq.cfg
 
-//--- --no-default-config disables config search.
+//--- --no-default-config --config loads only specified file.
 //
-// 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
+// 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
 //
-// NO-DEFAULT-CONFIG-NOT: Configuration file:
+// EXPLICIT-ONLY-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// EXPLICIT-ONLY: Configuration file: {{.*}}/Inputs/config/i386-qqq.cfg
 
-//--- Explicit --config works with --no-default-config.
+//--- --no-default-config disables default filenames.
 //
-// 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-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-NO-DEFAULT-NOT: Configuration file: {{.*}}/testdmode/qqq-clang-g++.cfg
-// CHECK-EXPLICIT-NO-DEFAULT: Configuration file: {{.*}}/Inputs/config/i386-qqq.cfg
+// NO-CONFIG-NOT: Configuration file:
 
-//--- Invocation qqq-clang-g++ tries to find config file qqq.cfg if qqq-clang-g++.cfg is not found.
+//--- --driver-mode= is respected.
 //
-// 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: %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
 //
-// SHORT-NAME: Configuration file: {{.*}}/testdmode/qqq.cfg
-// SHORT-NAME: -Werror
-// SHORT-NAME-NOT: -Wundefined-func-template
+// FULL1-GCC-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// FULL1-GCC-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// FULL1-GCC: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// FULL1-GCC-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL1-GCC-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// FULL1-GCC-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// FULL1-GCC-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang.cfg
+// FULL1-GCC-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu.cfg
+// FULL1-GCC-NOT: Configuration file: {{.*}}/testdmode/clang++.cfg
+// FULL1-GCC-NOT: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL1-GCC-NOT: Configuration file: {{.*}}/testdmode/clang.cfg
 
+//--- "clang" driver symlink should yield the "*-clang" 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
 
-//--- Config files are searched for in binary directory as well.
+//--- "clang" + --driver-mode= should yield "*-clang++".
 //
-// 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 --driver-mode=g++ --config-system-dir= --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix FULL1
+
+//--- Test fallback to x86_64-unknown-linux-gnu-clang-g++.cfg.
 //
-// CHECK-BIN: Configuration file: {{.*}}/testbin/aaa.cfg
-// CHECK-BIN: -Werror
+// 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: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// FULL2: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// FULL2-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// FULL2-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL2-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// FULL2-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// FULL2-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang.cfg
+// FULL2-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu.cfg
+// FULL2-NOT: Configuration file: {{.*}}/testdmode/clang++.cfg
+// FULL2-NOT: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL2-NOT: Configuration file: {{.*}}/testdmode/clang.cfg
+
+//--- 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: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// FULL2-I386-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// FULL2-I386-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// FULL2-I386-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL2-I386-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// FULL2-I386: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// FULL2-I386-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang.cfg
+// FULL2-I386-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu.cfg
+// FULL2-I386-NOT: Configuration file: {{.*}}/testdmode/clang++.cfg
+// FULL2-I386-NOT: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL2-I386-NOT: Configuration file: {{.*}}/testdmode/clang.cfg
 
+//--- Test fallback to x86_64-unknown-linux-gnu-clang.cfg + 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
+//
+// FULL3-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// FULL3-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// FULL3-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// FULL3: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL3-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// FULL3-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// FULL3-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang.cfg
+// FULL3-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu.cfg
+// FULL3: Configuration file: {{.*}}/testdmode/clang++.cfg
+// FULL3-NOT: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL3-NOT: Configuration file: {{.*}}/testdmode/clang.cfg
 
-//--- If command line contains options that change triple (for instance, -m32), clang tries
-//    reloading config 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: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// FULL3-I386-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// FULL3-I386-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// FULL3-I386-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL3-I386-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// FULL3-I386-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// FULL3-I386-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang.cfg
+// FULL3-I386: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu.cfg
+// FULL3-I386: Configuration file: {{.*}}/testdmode/clang++.cfg
+// FULL3-I386-NOT: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL3-I386-NOT: Configuration file: {{.*}}/testdmode/clang.cfg
 
-//--- When reloading config file, x86_64-clang-g++ tries to find config i386-clang-g++.cfg first.
+//--- FULL3 + --driver-mode=.
 //
-// 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/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-RELOAD: Configuration file: {{.*}}/testreload/i386-clang-g++.cfg
-// CHECK-RELOAD: -Wundefined-func-template
-// CHECK-RELOAD-NOT: -Werror
-// CHECK-RELOAD-NOT: -Wall
+// FULL3-GCC-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// FULL3-GCC-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// FULL3-GCC-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// FULL3-GCC: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL3-GCC-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// FULL3-GCC-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// FULL3-GCC-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang.cfg
+// FULL3-GCC-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu.cfg
+// FULL3-GCC-NOT: Configuration file: {{.*}}/testdmode/clang++.cfg
+// FULL3-GCC-NOT: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL3-GCC: Configuration file: {{.*}}/testdmode/clang.cfg
 
-//--- 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: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// FULL4-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// FULL4-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// FULL4: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL4-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// FULL4-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// FULL4-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang.cfg
+// FULL4-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu.cfg
+// FULL4-NOT: Configuration file: {{.*}}/testdmode/clang++.cfg
+// FULL4: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL4-NOT: Configuration file: {{.*}}/testdmode/clang.cfg
 
-//--- `-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: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// FULL5-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// FULL5-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// FULL5-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL5-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// FULL5-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// FULL5-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang.cfg
+// FULL5-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu.cfg
+// FULL5-NOT: Configuration file: {{.*}}/testdmode/clang++.cfg
+// FULL5: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL5-NOT: Configuration file: {{.*}}/testdmode/clang.cfg
 
-//--- 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: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang++.cfg
+// FULL5-I386-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang-g++.cfg
+// FULL5-I386-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu-clang.cfg
+// FULL5-I386-NOT: Configuration file: {{.*}}/testdmode/x86_64-unknown-linux-gnu.cfg
+// FULL5-I386-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang++.cfg
+// FULL5-I386-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang-g++.cfg
+// FULL5-I386-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu-clang.cfg
+// FULL5-I386-NOT: Configuration file: {{.*}}/testdmode/i386-unknown-linux-gnu.cfg
+// FULL5-I386-NOT: Configuration file: {{.*}}/testdmode/clang++.cfg
+// FULL5-I386: Configuration file: {{.*}}/testdmode/clang-g++.cfg
+// FULL5-I386-NOT: Configuration file: {{.*}}/testdmode/clang.cfg
 
-//--- 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
@@ -1064,79 +1064,55 @@
 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.
+  llvm::Triple RealTriple =
+      computeTargetTriple(*this, TargetTriple, *CLOptions);
+  assert(!RealTriple.str().empty());
+  StringRef RealMode = getExecutableForDriverMode(Mode);
+
+  // 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).
+  // 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).
+
+  // Try loading full config (variants 1. and 2.)
   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()))
+  std::string CfgFileName = RealTriple.str() + '-' + RealMode.str() + ".cfg";
+  if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS()))
+    return readConfigFile(CfgFilePath);
+
+  bool ModeSuffixUnique = !ClangNameParts.ModeSuffix.empty() &&
+                          ClangNameParts.ModeSuffix != RealMode.str();
+  if (ModeSuffixUnique) {
+    CfgFileName = RealTriple.str() + '-' + ClangNameParts.ModeSuffix + ".cfg";
+    if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS()))
       return readConfigFile(CfgFilePath);
   }
 
-  // Then try original file name.
+  // Try loading separate config for the target (variants 3. and 4.)
+  CfgFileName = RealTriple.str() + ".cfg";
+  if (searchForFile(CfgFilePath, CfgFileSearchDirs, CfgFileName, getVFS()) &&
+      readConfigFile(CfgFilePath))
+    return true;
+
+  // Try loading separate config for the mode (second part of 3. and 4.)
+  CfgFileName = RealMode.str() + ".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");
+  if (ModeSuffixUnique) {
+    CfgFileName = ClangNameParts.ModeSuffix + ".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;
 }
 
@@ -6197,6 +6173,26 @@
   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";
+  }
+
+  assert(false && "Unhandled Mode");
+  return "clang";
+}
+
 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
@@ -753,6 +753,9 @@
   /// Compute the default -fmodule-cache-path.
   /// \return True if the system provides a default cache directory.
   static bool getDefaultModuleCachePath(SmallVectorImpl<char> &Result);
+
+  /// Return the typical executable name for the specified driver \p Mode.
+  static const char *getExecutableForDriverMode(DriverMode Mode);
 };
 
 /// \return True if the last defined optimization level is -Ofast.
Index: clang/docs/UsersManual.rst
===================================================================
--- clang/docs/UsersManual.rst
+++ clang/docs/UsersManual.rst
@@ -914,27 +914,53 @@
 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
+``<target>-<driver>.cfg`` where `target` 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 target and driver configuration files and attempt to load both.
+The former is named ``<target>.cfg`` while the latter is named
+``<driver>.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::
+
+    x86_64-pc-linux-gnu.cfg
+    clang++.cfg
 
-    x86_64-clang -m32 abc.c
+with fallback to trying::
 
-causes Clang search for a file ``i368.cfg`` first, and if no such file is found,
-Clang looks for the file ``x86_64.cfg``.
+    x86_64-pc-linux-gnu.cfg
+    clang-g++.cfg
 
 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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to