sepavloff created this revision.
sepavloff added reviewers: rnk, ddunbar.
sepavloff added a subscriber: cfe-commits.

The implementation follows the discussion in mail list
(http://lists.llvm.org/pipermail/cfe-dev/2016-September/050776.html).
Main part of the config file support is implemented in llvm source tree,
in CommandLine library, see D24926 and D24917.

https://reviews.llvm.org/D24933

Files:
  include/clang/Driver/Driver.h
  lib/Driver/Driver.cpp
  test/Driver/Inputs/config-1.cfg
  test/Driver/Inputs/config-2.cfg
  test/Driver/config-file.c
  tools/driver/driver.cpp

Index: tools/driver/driver.cpp
===================================================================
--- tools/driver/driver.cpp
+++ tools/driver/driver.cpp
@@ -330,6 +330,14 @@
   llvm::BumpPtrAllocator A;
   llvm::StringSaver Saver(A);
 
+  // Try reading options from configuration file.
+  static const char * const SearchDirs[] = { "~/.llvm", "/etc/llvm" };
+  llvm::SmallString<128> ConfigFile;
+  auto SRes = llvm::cl::findConfigFile(ConfigFile, argv, SearchDirs, "clang");
+  llvm::cl::reportConfigFileSearchError(SRes, ConfigFile, SearchDirs, ProgName);
+  if (SRes == llvm::cl::CfgFileSearch::Successful)
+    llvm::cl::readConfigFile(ConfigFile, Saver, argv);
+
   // Parse response files using the GNU syntax, unless we're in CL mode. There
   // are two ways to put clang in CL compatibility mode: argv[0] is either
   // clang-cl or cl, or --driver-mode=cl is on the command line. The normal
@@ -446,6 +454,8 @@
   ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
 
   Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
+  if (!ConfigFile.empty())
+    TheDriver.setConfigFile(ConfigFile.str());
   SetInstallDir(argv, TheDriver, CanonicalPrefixes);
 
   insertTargetAndModeArgs(TargetAndMode.first, TargetAndMode.second, argv,
Index: test/Driver/config-file.c
===================================================================
--- /dev/null
+++ test/Driver/config-file.c
@@ -0,0 +1,30 @@
+// RUN: %clang --config %S/Inputs/config-1.cfg -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-HHH
+// CHECK-HHH: Target: x86_64-apple-darwin
+// CHECK-HHH: Configuration file: {{.*}}/Inputs/config-1.cfg
+// CHECK-HHH: -Werror
+// CHECK-HHH: -std=c99
+
+// RUN: not %clang --config %S/Inputs/inexistent.cfg -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-INEX
+// CHECK-INEX: Configuration file {{.*}}/Inputs/inexistent.cfg' specified by option '--config' cannot be found
+
+// RUN: not %clang --config inexistent.cfg -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-INEX-NOSEARCH
+// CHECK-INEX-NOSEARCH: Configuration {{.*}}inexistent.cfg' specified by option '--config' cannot be found in directories:
+// CHECK-INEX-NOSEARCH: ~/.llvm
+// CHECK-INEX-NOSEARCH: /etc/llvm
+
+// RUN: %clang --config %S/Inputs/config-2.cfg -### 2>&1 | FileCheck %s -check-prefix CHECK-HHH-NOFILE
+// CHECK-HHH-NOFILE: Target: x86_64-unknown-linux
+// CHECK-HHH-NOFILE: Configuration file: {{.*}}/Inputs/config-2.cfg
+
+// RUN: %clang --config %S/Inputs/config-1.cfg -c %s -v 2>&1 | FileCheck %s -check-prefix CHECK-V
+// CHECK-V: Target: x86_64-apple-darwin
+// CHECK-V: Configuration file: {{.*}}/Inputs/config-1.cfg
+// CHECK-V: -triple{{.*}}x86_64-apple-
+
+// RUN: env CLANGCFG=%S/Inputs/config-1.cfg %clang -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-ENV
+// CHECK-ENV: Target: x86_64-apple-darwin
+// CHECK-ENV: Configuration file: {{.*}}/Inputs/config-1.cfg
+// CHECK-ENV: -Werror
+
+// RUN: env CLANGCFG=inexistent.cfg not %clang -c %s -### 2>&1 | FileCheck %s -check-prefix CHECK-ENV-INEX
+// CHECK-ENV-INEX: Configuration file 'inexistent.cfg' specified by environment variable cannot be found
Index: test/Driver/Inputs/config-2.cfg
===================================================================
--- /dev/null
+++ test/Driver/Inputs/config-2.cfg
@@ -0,0 +1,2 @@
+# target
+-target x86_64-unknown-linux-gnu
Index: test/Driver/Inputs/config-1.cfg
===================================================================
--- /dev/null
+++ test/Driver/Inputs/config-1.cfg
@@ -0,0 +1,7 @@
+
+    
+# Empty lines and line started with # are ignored
+-Werror -std=\
+c99
+    # Target
+    -target x86_64-apple-darwin
\ No newline at end of file
Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -895,6 +895,10 @@
 
   // Print out the install directory.
   OS << "InstalledDir: " << InstalledDir << '\n';
+
+  // If configuration file was used, print its path.
+  if (!ConfigFile.empty())
+    OS << "Configuration file: " << ConfigFile << '\n';
 }
 
 /// PrintDiagnosticCategories - Implement the --print-diagnostic-categories
Index: include/clang/Driver/Driver.h
===================================================================
--- include/clang/Driver/Driver.h
+++ include/clang/Driver/Driver.h
@@ -187,6 +187,9 @@
   /// Name to use when invoking gcc/g++.
   std::string CCCGenericGCCName;
 
+  /// Name of configuration file if used.
+  std::string ConfigFile;
+
   /// Whether to check that input files exist when constructing compilation
   /// jobs.
   unsigned CheckInputsExist : 1;
@@ -238,6 +241,9 @@
   /// Name to use when invoking gcc/g++.
   const std::string &getCCCGenericGCCName() const { return CCCGenericGCCName; }
 
+  const std::string &getConfigFile() const { return ConfigFile; }
+  void setConfigFile(StringRef x) { ConfigFile = x; }
+
   const llvm::opt::OptTable &getOpts() const { return *Opts; }
 
   const DiagnosticsEngine &getDiags() const { return Diags; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to