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