bruno updated this revision to Diff 80981.
bruno added a comment.

Update after Mehdi's review!


https://reviews.llvm.org/D27604

Files:
  docs/UsersManual.rst
  include/clang/Basic/DiagnosticDriverKinds.td
  include/clang/Driver/Driver.h
  include/clang/Driver/Options.td
  lib/Driver/Driver.cpp
  test/Driver/crash-report-crashfile.m
  tools/driver/driver.cpp

Index: tools/driver/driver.cpp
===================================================================
--- tools/driver/driver.cpp
+++ tools/driver/driver.cpp
@@ -460,8 +460,11 @@
     Res = TheDriver.ExecuteCompilation(*C, FailingCommands);
 
   // Force a crash to test the diagnostics.
-  if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) {
-    Diags.Report(diag::err_drv_force_crash) << "FORCE_CLANG_DIAGNOSTICS_CRASH";
+  if (TheDriver.GenReproducer) {
+    Diags.Report(diag::err_drv_force_crash)
+        << (!::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")
+                ? "option '-gen-reproducer'"
+                : "environment variable 'FORCE_CLANG_DIAGNOSTICS_CRASH'");
 
     // Pretend that every command failed.
     FailingCommands.clear();
Index: test/Driver/crash-report-crashfile.m
===================================================================
--- test/Driver/crash-report-crashfile.m
+++ test/Driver/crash-report-crashfile.m
@@ -3,15 +3,32 @@
 // RUN: mkdir -p %t/i %t/m %t
 
 // RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
-// RUN: %clang -fsyntax-only %s -I %S/Inputs/module -isysroot %/t/i/    \
-// RUN: -fmodules -fmodules-cache-path=%t/m/ -DFOO=BAR 2>&1 | FileCheck %s
+// RUN: %clang -fsyntax-only %s \
+// RUN:   -I %S/Inputs/module -isysroot %/t/i/ \
+// RUN:   -fmodules -fmodules-cache-path=%t/m/ -DFOO=BAR 2>&1 | \
+// RUN:   FileCheck -check-prefix=CRASH_ENV %s
+
+// RUN: not env TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -gen-reproducer -fsyntax-only %s \
+// RUN:   -I %S/Inputs/module -isysroot %/t/i/ \
+// RUN:   -fmodules -fmodules-cache-path=%t/m/ -DFOO=BAR 2>&1 | \
+// RUN:   FileCheck -check-prefix=CRASH_FLAG %s
 
 @import simple;
 const int x = MODULE_MACRO;
 
-// CHECK: Preprocessed source(s) and associated run script(s) are located at:
-// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
-// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
-// CHECK-NEXT: note: diagnostic msg: {{.*}}.sh
-// CHECK-NEXT: note: diagnostic msg: Crash backtrace is located in
-// CHECK-NEXT: note: diagnostic msg: {{.*}}Library/Logs/DiagnosticReports{{.*}}
+// CRASH_ENV: failing because environment variable 'FORCE_CLANG_DIAGNOSTICS_CRASH' is set
+// CRASH_ENV: Preprocessed source(s) and associated run script(s) are located at:
+// CRASH_ENV-NEXT: note: diagnostic msg: {{.*}}.m
+// CRASH_ENV-NEXT: note: diagnostic msg: {{.*}}.cache
+// CRASH_ENV-NEXT: note: diagnostic msg: {{.*}}.sh
+// CRASH_ENV-NEXT: note: diagnostic msg: Crash backtrace is located in
+// CRASH_ENV-NEXT: note: diagnostic msg: {{.*}}Library/Logs/DiagnosticReports{{.*}}
+
+// CRASH_FLAG: failing because option '-gen-reproducer' is set
+// CRASH_FLAG: Preprocessed source(s) and associated run script(s) are located at:
+// CRASH_FLAG-NEXT: note: diagnostic msg: {{.*}}.m
+// CRASH_FLAG-NEXT: note: diagnostic msg: {{.*}}.cache
+// CRASH_FLAG-NEXT: note: diagnostic msg: {{.*}}.sh
+// CRASH_FLAG-NEXT: note: diagnostic msg: Crash backtrace is located in
+// CRASH_FLAG-NEXT: note: diagnostic msg: {{.*}}Library/Logs/DiagnosticReports{{.*}}
Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -62,7 +62,7 @@
       CCCPrintBindings(false), CCPrintHeaders(false), CCLogDiagnostics(false),
       CCGenDiagnostics(false), DefaultTargetTriple(DefaultTargetTriple),
       CCCGenericGCCName(""), CheckInputsExist(true), CCCUsePCH(true),
-      SuppressMissingInputWarning(false) {
+      GenReproducer(false), SuppressMissingInputWarning(false) {
 
   // Provide a sane fallback if no VFS is specified.
   if (!this->VFS)
@@ -596,6 +596,9 @@
     CCCGenericGCCName = A->getValue();
   CCCUsePCH =
       Args.hasFlag(options::OPT_ccc_pch_is_pch, options::OPT_ccc_pch_is_pth);
+  GenReproducer = Args.hasFlag(options::OPT_gen_reproducer,
+                               options::OPT_fno_crash_diagnostics,
+                               !!::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH"));
   // FIXME: DefaultTargetTriple is used by the target-prefixed calls to as/ld
   // and getToolChain is const.
   if (IsCLMode()) {
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -184,6 +184,8 @@
 def arcmt_migrate_emit_arc_errors : Flag<["-"], "arcmt-migrate-emit-errors">,
   HelpText<"Emit ARC errors even if the migrator can fix them">,
   Flags<[CC1Option]>;
+def gen_reproducer: Flag<["-"], "gen-reproducer">, InternalDebugOpt,
+  HelpText<"Auto-generates preprocessed source files and a reproduction script">;
 
 def _migrate : Flag<["--"], "migrate">, Flags<[DriverOption]>,
   HelpText<"Run the migrator">;
@@ -580,7 +582,8 @@
 def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>;
 def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">,
                                     Group<f_Group>;
-def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>;
+def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>,
+  HelpText<"Disable auto-generation of preprocessed source files and a script for reproduction during a clang crash">;
 def fcreate_profile : Flag<["-"], "fcreate-profile">, Group<f_Group>;
 def fcxx_exceptions: Flag<["-"], "fcxx-exceptions">, Group<f_Group>,
   HelpText<"Enable C++ exceptions">, Flags<[CC1Option]>;
Index: include/clang/Driver/Driver.h
===================================================================
--- include/clang/Driver/Driver.h
+++ include/clang/Driver/Driver.h
@@ -215,6 +215,11 @@
   /// Use lazy precompiled headers for PCH support.
   unsigned CCCUsePCH : 1;
 
+  /// Force clang to emit reproducer for driver invocation. This is enabled
+  /// indirectly by setting FORCE_CLANG_DIAGNOSTICS_CRASH environment variable
+  /// or when using the -gen-reproducer driver flag.
+  unsigned GenReproducer : 1;
+
 private:
   /// Certain options suppress the 'no input files' warning.
   unsigned SuppressMissingInputWarning : 1;
Index: include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- include/clang/Basic/DiagnosticDriverKinds.td
+++ include/clang/Basic/DiagnosticDriverKinds.td
@@ -92,7 +92,7 @@
 def err_drv_command_signalled : Error<
   "%0 command failed due to signal (use -v to see invocation)">;
 def err_drv_force_crash : Error<
-  "failing because environment variable '%0' is set">;
+  "failing because %0 is set">;
 def err_drv_invalid_mfloat_abi : Error<
   "invalid float ABI '%0'">;
 def err_drv_invalid_libcxx_deployment : Error<
Index: docs/UsersManual.rst
===================================================================
--- docs/UsersManual.rst
+++ docs/UsersManual.rst
@@ -561,6 +561,16 @@
 The -fno-crash-diagnostics flag can be helpful for speeding the process
 of generating a delta reduced test case.
 
+Clang is also capable of generating preprocessed source file(s) and associated
+run script(s) even without a crash. This is specially useful when trying to
+generate a reproducer for warnings or errors while using modules.
+
+.. option:: -gen-reproducer
+
+  Generates preprocessed source files, a reproducer script and if relevant, a
+  cache containing: built module pcm's and all headers needed to rebuilt the
+  same modules.
+
 .. _rpass:
 
 Options to Emit Optimization Reports
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to