r329465 - Recommit r329442: Generate Libclang invocation reproducers using a new

via cfe-commits cfe-commits at lists.llvm.org
Sat Apr 7 12:44:01 PDT 2018


Hi Alex,

The two tests you added in this commit seem to be failing because of a crash on one of the Windows bots. Can you take a look?

http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/8912

FAIL: Clang :: Index/create-libclang-parsing-reproducer.c (7891 of 37034)
******************** TEST 'Clang :: Index/create-libclang-parsing-reproducer.c' FAILED ********************
Script:
--
rm -rf C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\tools\clang\test\Index\Output\create-libclang-parsing-reproducer.c.tmp
mkdir C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\tools\clang\test\Index\Output\create-libclang-parsing-reproducer.c.tmp
env CINDEXTEST_INVOCATION_EMISSION_PATH=C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\tools\clang\test\Index\Output\create-libclang-parsing-reproducer.c.tmp not C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\bin\c-index-test.EXE -test-load-source all C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\test\Index\create-libclang-parsing-reproducer.c
c:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\bin\clang.EXE -cc1gen-reproducer C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\tools\clang\test\Index\Output\create-libclang-parsing-reproducer.c.tmp/libclang-* -v | C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\bin\FileCheck.EXE C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\test\Index\create-libclang-parsing-reproducer.c
ls C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\tools\clang\test\Index\Output\create-libclang-parsing-reproducer.c.tmp | C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\bin\count.EXE 0
rm -rf C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\tools\clang\test\Index\Output\create-libclang-parsing-reproducer.c.tmp
mkdir C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\tools\clang\test\Index\Output\create-libclang-parsing-reproducer.c.tmp
env CINDEXTEST_INVOCATION_EMISSION_PATH=C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\tools\clang\test\Index\Output\create-libclang-parsing-reproducer.c.tmp not C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\bin\c-index-test.EXE -test-load-source all "-remap-file=C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\test\Index\create-libclang-parsing-reproducer.c,C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\test\Index/Inputs/record-parsing-invocation-remap.c" C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\test\Index\create-libclang-parsing-reproducer.c
c:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\bin\clang.EXE -cc1gen-reproducer C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\tools\clang\test\Index\Output\create-libclang-parsing-reproducer.c.tmp/libclang-* -v | C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\bin\FileCheck.EXE C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\test\Index\create-libclang-parsing-reproducer.c
--
Exit Code: 2

Command Output (stdout):
--
$ "rm" "-rf" "C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\tools\clang\test\Index\Output\create-libclang-parsing-reproducer.c.tmp"
$ "mkdir" "C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\tools\clang\test\Index\Output\create-libclang-parsing-reproducer.c.tmp"
$ "not" "C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\bin\c-index-test.EXE" "-test-load-source" "all" "C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\test\Index\create-libclang-parsing-reproducer.c"
# command stderr:
libclang: crash detected during parsing: {

  'source_filename' : '(null)'

  'command_line_args' : ['clang', 'C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\test\Index\create-libclang-parsing-reproducer.c'],

  'unsaved_files' : [],

  'options' : 1,

}

Unable to load translation unit!

Failure: libclang crashed


$ "c:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\bin\clang.EXE" "-cc1gen-reproducer" "C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\tools\clang\test\Index\Output\create-libclang-parsing-reproducer.c.tmp/libclang-*" "-v"
# command stderr:
YAML:1:366: error: Unrecognized escape code!

{"toolchain":"C:\\ps4-buildslave2\\llvm-clang-x86_64-expensive-checks-win\\build","libclang.operation":"parse","libclang.opts":1,"args":["clang","-fno-spell-checking","C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\test\Index\create-libclang-parsing-reproducer.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"]}

                                                                                                                                                                                                                                                                                                                                                                             ^

LLVMSymbolizer: error reading file: PDB Error: Unable to load PDB.  Make sure the file exists and is readable.  Calling loadDataForExe



LLVMSymbolizer: error reading file: PDB Error: Unable to load PDB.  Make sure the file exists and is readable.  Calling loadDataForExe



LLVMSymbolizer: error reading file: PDB Error: Unable to load PDB.  Make sure the file exists and is readable.  Calling loadDataForExe



#0 0x00007ff9225a0806 (C:\WINDOWS\SYSTEM32\MSVCP140D.dll+0x30806)

#1 0x00007ff7b10e5062 std::vector<char const *,class std::allocator<char const *> >::operator[](unsigned __int64) c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector:1235:0

#2 0x00007ff7b10df32e cc1gen_reproducer_main(class llvm::ArrayRef<char const *>,char const *,void *) c:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\tools\driver\cc1gen_reproducer_main.cpp:182:0

#3 0x00007ff7b109cc6e ExecuteCC1Tool c:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\tools\driver\driver.cpp:316:0

#4 0x00007ff7b109d4a1 main c:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\tools\driver\driver.cpp:394:0

#5 0x00007ff7b9d35064 invoke_main f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:65:0

#6 0x00007ff7b9d34f27 __scrt_common_main_seh f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:253:0

#7 0x00007ff7b9d34dee __scrt_common_main f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:296:0

#8 0x00007ff7b9d35089 mainCRTStartup f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp:17:0

#9 0x00007ff92c481fe4 (C:\WINDOWS\System32\KERNEL32.DLL+0x11fe4)

#10 0x00007ff92eeff061 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x6f061)


error: command failed with exit status: 0x80000003
$ "C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\bin\FileCheck.EXE" "C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\test\Index\create-libclang-parsing-reproducer.c"
# command stderr:
FileCheck error: '-' is empty.

FileCheck command line:  C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\build\bin\FileCheck.EXE C:\ps4-buildslave2\llvm-clang-x86_64-expensive-checks-win\llvm\tools\clang\test\Index\create-libclang-parsing-reproducer.c


error: command failed with exit status: 2

--

********************

Douglas Yung

> -----Original Message-----
> From: cfe-commits [mailto:cfe-commits-bounces at lists.llvm.org] On Behalf Of
> Alex Lorenz via cfe-commits
> Sent: Friday, April 06, 2018 17:03
> To: cfe-commits at lists.llvm.org
> Subject: r329465 - Recommit r329442: Generate Libclang invocation reproducers
> using a new
> 
> Author: arphaman
> Date: Fri Apr  6 17:03:27 2018
> New Revision: 329465
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=329465&view=rev
> Log:
> Recommit r329442: Generate Libclang invocation reproducers using a new -
> cc1gen-reproducer driver option
> 
> The recommit fixes:
> - An MSAN failure (CCPrintOptions wasn't initialized in the Driver)
> - Ensures that the strings in the libclang invocation files are escaped
> 
> Original message:
> 
> This commit is a follow up to the previous work that recorded Libclang
> invocations into temporary files: r319702.
> 
> It adds a new -cc1 mode to clang: -cc1gen-reproducer. The goal of this mode is
> to generate Clang reproducer files for Libclang tool invocation. The JSON
> format in the invocation files is not really intended to be stable, so
> Libclang and Clang should be of the same version when generating reproducers.
> The new mode emits the information about the temporary files and Libclang-
> specific information to stdout using JSON.
> 
> rdar://35322614
> 
> Differential Revision: https://reviews.llvm.org/D40983
> 
> Added:
>     cfe/trunk/test/Index/create-libclang-completion-reproducer.c
>     cfe/trunk/test/Index/create-libclang-parsing-reproducer.c
>     cfe/trunk/tools/driver/cc1gen_reproducer_main.cpp
> Modified:
>     cfe/trunk/include/clang/Driver/Driver.h
>     cfe/trunk/lib/Driver/Driver.cpp
>     cfe/trunk/tools/driver/CMakeLists.txt
>     cfe/trunk/tools/driver/driver.cpp
>     cfe/trunk/tools/libclang/CIndexer.cpp
> 
> Modified: cfe/trunk/include/clang/Driver/Driver.h
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/include/clang/Driver/Driver.h?rev=329465&r1=329464&r2=329465
> &view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Driver/Driver.h (original)
> +++ cfe/trunk/include/clang/Driver/Driver.h Fri Apr  6 17:03:27 2018
> @@ -405,11 +405,19 @@ public:
>    int ExecuteCompilation(Compilation &C,
>       SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands);
> 
> -  /// generateCompilationDiagnostics - Generate diagnostics information
> +  /// Contains the files in the compilation diagnostic report generated
> + by  /// generateCompilationDiagnostics.
> +  struct CompilationDiagnosticReport {
> +    llvm::SmallVector<std::string, 4> TemporaryFiles;  };
> +
> +  /// generateCompilationDiagnostics - Generate diagnostics information
>    /// including preprocessed source file(s).
> -  ///
> -  void generateCompilationDiagnostics(Compilation &C,
> -                                      const Command &FailingCommand);
> +  ///
> +  void generateCompilationDiagnostics(
> +      Compilation &C, const Command &FailingCommand,
> +      StringRef AdditionalInformation = "",
> +      CompilationDiagnosticReport *GeneratedReport = nullptr);
> 
>    /// @}
>    /// @name Helper Methods
> 
> Modified: cfe/trunk/lib/Driver/Driver.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/lib/Driver/Driver.cpp?rev=329465&r1=329464&r2=329465&view=di
> ff
> ==============================================================================
> --- cfe/trunk/lib/Driver/Driver.cpp (original)
> +++ cfe/trunk/lib/Driver/Driver.cpp Fri Apr  6 17:03:27 2018
> @@ -89,14 +89,14 @@ Driver::Driver(StringRef ClangExecutable
>      : Opts(createDriverOptTable()), Diags(Diags), VFS(std::move(VFS)),
>        Mode(GCCMode), SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
>        LTOMode(LTOK_None), ClangExecutable(ClangExecutable),
> -      SysRoot(DEFAULT_SYSROOT),
> -      DriverTitle("clang LLVM compiler"), CCPrintOptionsFilename(nullptr),
> -      CCPrintHeadersFilename(nullptr), CCLogDiagnosticsFilename(nullptr),
> -      CCCPrintBindings(false), CCPrintHeaders(false),
> CCLogDiagnostics(false),
> +      SysRoot(DEFAULT_SYSROOT), DriverTitle("clang LLVM compiler"),
> +      CCPrintOptionsFilename(nullptr), CCPrintHeadersFilename(nullptr),
> +      CCLogDiagnosticsFilename(nullptr), CCCPrintBindings(false),
> +      CCPrintOptions(false), CCPrintHeaders(false),
> + CCLogDiagnostics(false),
>        CCGenDiagnostics(false), DefaultTargetTriple(DefaultTargetTriple),
> -      CCCGenericGCCName(""), Saver(Alloc),
> -      CheckInputsExist(true), CCCUsePCH(true),
> -      GenReproducer(false), SuppressMissingInputWarning(false) {
> +      CCCGenericGCCName(""), Saver(Alloc), CheckInputsExist(true),
> +      CCCUsePCH(true), GenReproducer(false),
> +      SuppressMissingInputWarning(false) {
> 
>    // Provide a sane fallback if no VFS is specified.
>    if (!this->VFS)
> @@ -1111,8 +1111,9 @@ bool Driver::getCrashDiagnosticFile(Stri
>  // When clang crashes, produce diagnostic information including the fully  //
> preprocessed source file(s).  Request that the developer attach the  //
> diagnostic information to a bug report.
> -void Driver::generateCompilationDiagnostics(Compilation &C,
> -                                            const Command &FailingCommand) {
> +void Driver::generateCompilationDiagnostics(
> +    Compilation &C, const Command &FailingCommand,
> +    StringRef AdditionalInformation, CompilationDiagnosticReport
> +*Report) {
>    if (C.getArgs().hasArg(options::OPT_fno_crash_diagnostics))
>      return;
> 
> @@ -1238,6 +1239,8 @@ void Driver::generateCompilationDiagnost
>    SmallString<128> ReproCrashFilename;
>    for (const char *TempFile : TempFiles) {
>      Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile;
> +    if (Report)
> +      Report->TemporaryFiles.push_back(TempFile);
>      if (ReproCrashFilename.empty()) {
>        ReproCrashFilename = TempFile;
>        llvm::sys::path::replace_extension(ReproCrashFilename, ".crash"); @@ -
> 1266,6 +1269,11 @@ void Driver::generateCompilationDiagnost
>      ScriptOS << "# Original command: ";
>      Cmd.Print(ScriptOS, "\n", /*Quote=*/true);
>      Cmd.Print(ScriptOS, "\n", /*Quote=*/true, &CrashInfo);
> +    if (!AdditionalInformation.empty())
> +      ScriptOS << "\n# Additional information: " << AdditionalInformation
> +               << "\n";
> +    if (Report)
> +      Report->TemporaryFiles.push_back(Script);
>      Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
>    }
> 
> 
> Added: cfe/trunk/test/Index/create-libclang-completion-reproducer.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/create-libclang-
> completion-reproducer.c?rev=329465&view=auto
> ==============================================================================
> --- cfe/trunk/test/Index/create-libclang-completion-reproducer.c (added)
> +++ cfe/trunk/test/Index/create-libclang-completion-reproducer.c Fri Apr
> +++ 6 17:03:27 2018
> @@ -0,0 +1,14 @@
> +// RUN: rm -rf %t
> +// RUN: mkdir %t
> +// RUN: env CINDEXTEST_INVOCATION_EMISSION_PATH=%t not c-index-test
> +-code-completion-at=%s:10:1
> +"-remap-file=%s,%S/Inputs/record-parsing-invocation-remap.c" %s // RUN:
> +%clang -cc1gen-reproducer %t/libclang-* -v | FileCheck %s
> +
> +// Invocation file must be removed by clang:
> +// RUN: ls %t | count 0
> +
> +// CHECK: REPRODUCER METAINFO: {"libclang.operation": "complete",
> +"libclang.opts": "1", "invocation-args":
> +["-code-completion-at={{.*}}create-libclang-completion-reproducer.c:10:
> +1"]}
> +
> +// CHECK: REPRODUCER:
> +// CHECK-NEXT: {
> +// CHECK-NEXT: "files":["{{.*}}.c","{{.*}}.sh"] // CHECK-NEXT: }
> 
> Added: cfe/trunk/test/Index/create-libclang-parsing-reproducer.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/create-libclang-
> parsing-reproducer.c?rev=329465&view=auto
> ==============================================================================
> --- cfe/trunk/test/Index/create-libclang-parsing-reproducer.c (added)
> +++ cfe/trunk/test/Index/create-libclang-parsing-reproducer.c Fri Apr  6
> +++ 17:03:27 2018
> @@ -0,0 +1,21 @@
> +// RUN: rm -rf %t
> +// RUN: mkdir %t
> +// RUN: env CINDEXTEST_INVOCATION_EMISSION_PATH=%t not c-index-test
> +-test-load-source all %s // RUN: %clang -cc1gen-reproducer
> +%t/libclang-* -v | FileCheck %s
> +
> +// Invocation file must be removed by clang:
> +// RUN: ls %t | count 0
> +
> +// RUN: rm -rf %t
> +// RUN: mkdir %t
> +// RUN: env CINDEXTEST_INVOCATION_EMISSION_PATH=%t not c-index-test
> +-test-load-source all
> +"-remap-file=%s,%S/Inputs/record-parsing-invocation-remap.c" %s // RUN:
> +%clang -cc1gen-reproducer %t/libclang-* -v | FileCheck %s
> +
> +#pragma clang __debug parser_crash
> +
> +// CHECK: REPRODUCER METAINFO: {"libclang.operation": "parse",
> +"libclang.opts": "1"}
> +
> +// CHECK: REPRODUCER:
> +// CHECK-NEXT: {
> +// CHECK-NEXT: "files":["{{.*}}.c","{{.*}}.sh"] // CHECK-NEXT: }
> 
> Modified: cfe/trunk/tools/driver/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/tools/driver/CMakeLists.txt?rev=329465&r1=329464&r2=329465&v
> iew=diff
> ==============================================================================
> --- cfe/trunk/tools/driver/CMakeLists.txt (original)
> +++ cfe/trunk/tools/driver/CMakeLists.txt Fri Apr  6 17:03:27 2018
> @@ -32,6 +32,7 @@ add_clang_tool(clang
>    driver.cpp
>    cc1_main.cpp
>    cc1as_main.cpp
> +  cc1gen_reproducer_main.cpp
> 
>    DEPENDS
>    ${tablegen_deps}
> 
> Added: cfe/trunk/tools/driver/cc1gen_reproducer_main.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/tools/driver/cc1gen_reproducer_main.cpp?rev=329465&view=auto
> ==============================================================================
> --- cfe/trunk/tools/driver/cc1gen_reproducer_main.cpp (added)
> +++ cfe/trunk/tools/driver/cc1gen_reproducer_main.cpp Fri Apr  6
> +++ 17:03:27 2018
> @@ -0,0 +1,196 @@
> +//===-- cc1gen_reproducer_main.cpp - Clang reproducer generator
> +----------===// //
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open
> +Source // License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------------------
> +----===//
> +//
> +// This is the entry point to the clang -cc1gen-reproducer
> +functionality, which // generates reproducers for invocations for clang-based
> tools.
> +//
> +//===------------------------------------------------------------------
> +----===//
> +
> +#include "clang/Basic/Diagnostic.h"
> +#include "clang/Basic/LLVM.h"
> +#include "clang/Basic/VirtualFileSystem.h"
> +#include "clang/Driver/Compilation.h"
> +#include "clang/Driver/Driver.h"
> +#include "llvm/ADT/ArrayRef.h"
> +#include "llvm/ADT/STLExtras.h"
> +#include "llvm/Support/FileSystem.h"
> +#include "llvm/Support/TargetSelect.h"
> +#include "llvm/Support/YAMLTraits.h"
> +#include "llvm/Support/raw_ostream.h"
> +
> +using namespace clang;
> +
> +namespace {
> +
> +struct UnsavedFileHash {
> +  std::string Name;
> +  std::string MD5;
> +};
> +
> +struct ClangInvocationInfo {
> +  std::string Toolchain;
> +  std::string LibclangOperation;
> +  std::string LibclangOptions;
> +  std::vector<std::string> Arguments;
> +  std::vector<std::string> InvocationArguments;
> +  std::vector<UnsavedFileHash> UnsavedFileHashes;
> +  bool Dump = false;
> +};
> +
> +} // end anonymous namespace
> +
> +LLVM_YAML_IS_SEQUENCE_VECTOR(UnsavedFileHash)
> +
> +namespace llvm {
> +namespace yaml {
> +
> +template <> struct MappingTraits<UnsavedFileHash> {
> +  static void mapping(IO &IO, UnsavedFileHash &Info) {
> +    IO.mapRequired("name", Info.Name);
> +    IO.mapRequired("md5", Info.MD5);
> +  }
> +};
> +
> +template <> struct MappingTraits<ClangInvocationInfo> {
> +  static void mapping(IO &IO, ClangInvocationInfo &Info) {
> +    IO.mapRequired("toolchain", Info.Toolchain);
> +    IO.mapOptional("libclang.operation", Info.LibclangOperation);
> +    IO.mapOptional("libclang.opts", Info.LibclangOptions);
> +    IO.mapRequired("args", Info.Arguments);
> +    IO.mapOptional("invocation-args", Info.InvocationArguments);
> +    IO.mapOptional("unsaved_file_hashes", Info.UnsavedFileHashes);
> +  }
> +};
> +
> +} // end namespace yaml
> +} // end namespace llvm
> +
> +static std::string generateReproducerMetaInfo(const ClangInvocationInfo
> +&Info) {
> +  std::string Result;
> +  llvm::raw_string_ostream OS(Result);
> +  OS << '{';
> +  bool NeedComma = false;
> +  auto EmitKey = [&](StringRef Key) {
> +    if (NeedComma)
> +      OS << ", ";
> +    NeedComma = true;
> +    OS << '"' << Key << "\": ";
> +  };
> +  auto EmitStringKey = [&](StringRef Key, StringRef Value) {
> +    if (Value.empty())
> +      return;
> +    EmitKey(Key);
> +    OS << '"' << Value << '"';
> +  };
> +  EmitStringKey("libclang.operation", Info.LibclangOperation);
> +  EmitStringKey("libclang.opts", Info.LibclangOptions);
> +  if (!Info.InvocationArguments.empty()) {
> +    EmitKey("invocation-args");
> +    OS << '[';
> +    for (const auto &Arg : llvm::enumerate(Info.InvocationArguments)) {
> +      if (Arg.index())
> +        OS << ',';
> +      OS << '"' << Arg.value() << '"';
> +    }
> +    OS << ']';
> +  }
> +  OS << '}';
> +  // FIXME: Compare unsaved file hashes and report mismatch in the
> reproducer.
> +  if (Info.Dump)
> +    llvm::outs() << "REPRODUCER METAINFO: " << OS.str() << "\n";
> +  return std::move(OS.str());
> +}
> +
> +/// Generates a reproducer for a set of arguments from a specific invocation.
> +static llvm::Optional<driver::Driver::CompilationDiagnosticReport>
> +generateReproducerForInvocationArguments(ArrayRef<const char *> Argv,
> +                                         const ClangInvocationInfo
> +&Info) {
> +  using namespace driver;
> +  auto TargetAndMode =
> +ToolChain::getTargetAndModeFromProgramName(Argv[0]);
> +
> +  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new
> + DiagnosticOptions;
> +
> +  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
> + DiagnosticsEngine Diags(DiagID, &*DiagOpts, new
> + IgnoringDiagConsumer());  ProcessWarningOptions(Diags, *DiagOpts,
> + /*ReportDiags=*/false);  Driver TheDriver(Argv[0],
> + llvm::sys::getDefaultTargetTriple(), Diags);
> + TheDriver.setTargetAndMode(TargetAndMode);
> +
> +  std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(Argv));
> +  if (C && !C->containsError()) {
> +    for (const auto &J : C->getJobs()) {
> +      if (const Command *Cmd = dyn_cast<Command>(&J)) {
> +        Driver::CompilationDiagnosticReport Report;
> +        TheDriver.generateCompilationDiagnostics(
> +            *C, *Cmd, generateReproducerMetaInfo(Info), &Report);
> +        return Report;
> +      }
> +    }
> +  }
> +
> +  return None;
> +}
> +
> +std::string GetExecutablePath(const char *Argv0, bool
> +CanonicalPrefixes);
> +
> +static void printReproducerInformation(
> +    llvm::raw_ostream &OS, const ClangInvocationInfo &Info,
> +    const driver::Driver::CompilationDiagnosticReport &Report) {
> +  OS << "REPRODUCER:\n";
> +  OS << "{\n";
> +  OS << R"("files":[)";
> +  for (const auto &File : llvm::enumerate(Report.TemporaryFiles)) {
> +    if (File.index())
> +      OS << ',';
> +    OS << '"' << File.value() << '"';
> +  }
> +  OS << "]\n}\n";
> +}
> +
> +int cc1gen_reproducer_main(ArrayRef<const char *> Argv, const char *Argv0,
> +                           void *MainAddr) {
> +  if (Argv.size() < 1) {
> +    llvm::errs() << "error: missing invocation file\n";
> +    return 1;
> +  }
> +  // Parse the invocation descriptor.
> +  StringRef Input = Argv[0];
> +  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
> +      llvm::MemoryBuffer::getFile(Input);
> +  if (!Buffer) {
> +    llvm::errs() << "error: failed to read " << Input << ": "
> +                 << Buffer.getError().message() << "\n";
> +    return 1;
> +  }
> +  llvm::yaml::Input YAML(Buffer.get()->getBuffer());
> +  ClangInvocationInfo InvocationInfo;
> +  YAML >> InvocationInfo;
> +  if (Argv.size() > 1 && Argv[1] == StringRef("-v"))
> +    InvocationInfo.Dump = true;
> +
> +  // Create an invocation that will produce the reproducer.
> +  std::vector<const char *> DriverArgs;  for (const auto &Arg :
> + InvocationInfo.Arguments)
> +    DriverArgs.push_back(Arg.c_str());
> +  std::string Path = GetExecutablePath(Argv0,
> + /*CanonicalPrefixes=*/true);  DriverArgs[0] = Path.c_str();
> + llvm::Optional<driver::Driver::CompilationDiagnosticReport> Report =
> +      generateReproducerForInvocationArguments(DriverArgs,
> + InvocationInfo);
> +
> +  // Emit the information about the reproduce files to stdout.
> +  int Result = 1;
> +  if (Report) {
> +    printReproducerInformation(llvm::outs(), InvocationInfo, *Report);
> +    Result = 0;
> +  }
> +
> +  // Remove the input file.
> +  llvm::sys::fs::remove(Input);
> +  return Result;
> +}
> 
> Modified: cfe/trunk/tools/driver/driver.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/tools/driver/driver.cpp?rev=329465&r1=329464&r2=329465&view=
> diff
> ==============================================================================
> --- cfe/trunk/tools/driver/driver.cpp (original)
> +++ cfe/trunk/tools/driver/driver.cpp Fri Apr  6 17:03:27 2018
> @@ -205,6 +205,8 @@ extern int cc1_main(ArrayRef<const char
>                      void *MainAddr);
>  extern int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0,
>                        void *MainAddr);
> +extern int cc1gen_reproducer_main(ArrayRef<const char *> Argv,
> +                                  const char *Argv0, void *MainAddr);
> 
>  static void insertTargetAndModeArgs(const ParsedClangName &NameParts,
>                                      SmallVectorImpl<const char *> &ArgVector,
> @@ -310,6 +312,8 @@ static int ExecuteCC1Tool(ArrayRef<const
>      return cc1_main(argv.slice(2), argv[0], GetExecutablePathVP);
>    if (Tool == "as")
>      return cc1as_main(argv.slice(2), argv[0], GetExecutablePathVP);
> +  if (Tool == "gen-reproducer")
> +    return cc1gen_reproducer_main(argv.slice(2), argv[0],
> + GetExecutablePathVP);
> 
>    // Reject unknown tools.
>    llvm::errs() << "error: unknown integrated tool '" << Tool << "'. "
> 
> Modified: cfe/trunk/tools/libclang/CIndexer.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/tools/libclang/CIndexer.cpp?rev=329465&r1=329464&r2=329465&v
> iew=diff
> ==============================================================================
> --- cfe/trunk/tools/libclang/CIndexer.cpp (original)
> +++ cfe/trunk/tools/libclang/CIndexer.cpp Fri Apr  6 17:03:27 2018
> @@ -22,6 +22,7 @@
>  #include "llvm/Support/MutexGuard.h"
>  #include "llvm/Support/Path.h"
>  #include "llvm/Support/Program.h"
> +#include "llvm/Support/YAMLParser.h"
>  #include <cstdio>
> 
>  #ifdef __CYGWIN__
> @@ -112,7 +113,7 @@ LibclangInvocationReporter::LibclangInvo
>    // Write out the information about the invocation to it.
>    auto WriteStringKey = [&OS](StringRef Key, StringRef Value) {
>      OS << R"(")" << Key << R"(":")";
> -    OS << Value << '"';
> +    OS << llvm::yaml::escape(Value) << '"';
>    };
>    OS << '{';
>    WriteStringKey("toolchain", Idx.getClangToolchainPath());
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


More information about the cfe-commits mailing list