aganea updated this revision to Diff 267880.
aganea marked an inline comment as done.
aganea added a comment.

As requested.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D80833

Files:
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Frontend/CompilerInvocation.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
  clang/test/CodeGen/debug-info-codeview-buildinfo.c
  clang/tools/driver/cc1_main.cpp
  clang/tools/driver/driver.cpp
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp

Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -831,6 +831,31 @@
   return TypeTable.writeLeafType(SIR);
 }
 
+static std::string renderCommandLine(ArrayRef<const char *> CommandLineArgs,
+                                     StringRef MainFile) {
+  std::string FlatCmdLine;
+  SmallString<128> TempArg;
+  auto maybeQuote = [&TempArg](const char *Arg) -> StringRef {
+    const bool Escape =
+        StringRef(Arg).find_first_of(" \"\\$") != StringRef::npos;
+    if (!Escape)
+      return Arg;
+    TempArg.clear();
+    (Twine("\"") + Arg + "\"").toVector(TempArg);
+    return TempArg;
+  };
+  for (auto &Arg : CommandLineArgs) {
+    if (Arg == nullptr)
+      break;
+    // The command-line shall not contain the file to compile.
+    if (Arg == MainFile)
+      continue;
+    FlatCmdLine += maybeQuote(Arg);
+    FlatCmdLine += " ";
+  }
+  return FlatCmdLine;
+}
+
 void CodeViewDebug::emitBuildInfo() {
   // First, make LF_BUILDINFO. It's a sequence of strings with various bits of
   // build info. The known prefix is:
@@ -851,8 +876,14 @@
       getStringIdTypeIdx(TypeTable, MainSourceFile->getDirectory());
   BuildInfoArgs[BuildInfoRecord::SourceFile] =
       getStringIdTypeIdx(TypeTable, MainSourceFile->getFilename());
-  // FIXME: Path to compiler and command line. PDB is intentionally blank unless
-  // we implement /Zi type servers.
+  if (!StringRef(Asm->TM.Options.MCOptions.BuildTool).empty()) {
+    BuildInfoArgs[BuildInfoRecord::BuildTool] =
+        getStringIdTypeIdx(TypeTable, Asm->TM.Options.MCOptions.BuildTool);
+    BuildInfoArgs[BuildInfoRecord::CommandLine] = getStringIdTypeIdx(
+        TypeTable, renderCommandLine(Asm->TM.Options.MCOptions.CommandLineArgs,
+                                     MainSourceFile->getFilename()));
+  }
+  // FIXME: PDB is intentionally blank unless we implement /Zi type servers.
   BuildInfoRecord BIR(BuildInfoArgs);
   TypeIndex BuildInfoIndex = TypeTable.writeLeafType(BIR);
 
Index: llvm/include/llvm/MC/MCTargetOptions.h
===================================================================
--- llvm/include/llvm/MC/MCTargetOptions.h
+++ llvm/include/llvm/MC/MCTargetOptions.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_MC_MCTARGETOPTIONS_H
 #define LLVM_MC_MCTARGETOPTIONS_H
 
+#include "llvm/ADT/ArrayRef.h"
 #include <string>
 #include <vector>
 
@@ -59,6 +60,9 @@
   std::string AssemblyLanguage;
   std::string SplitDwarfFile;
 
+  const char *BuildTool = nullptr;
+  ArrayRef<const char *> CommandLineArgs;
+
   /// Additional paths to search for `.include` directives when using the
   /// integrated assembler.
   std::vector<std::string> IASSearchPaths;
Index: clang/tools/driver/driver.cpp
===================================================================
--- clang/tools/driver/driver.cpp
+++ clang/tools/driver/driver.cpp
@@ -203,8 +203,7 @@
   }
 }
 
-extern int cc1_main(ArrayRef<const char *> Argv, const char *Argv0,
-                    void *MainAddr);
+extern int cc1_main(ArrayRef<const char *> Argv, void *MainAddr);
 extern int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0,
                       void *MainAddr);
 extern int cc1gen_reproducer_main(ArrayRef<const char *> Argv,
@@ -327,7 +326,7 @@
   StringRef Tool = ArgV[1];
   void *GetExecutablePathVP = (void *)(intptr_t)GetExecutablePath;
   if (Tool == "-cc1")
-    return cc1_main(makeArrayRef(ArgV).slice(2), ArgV[0], GetExecutablePathVP);
+    return cc1_main(makeArrayRef(ArgV), GetExecutablePathVP);
   if (Tool == "-cc1as")
     return cc1as_main(makeArrayRef(ArgV).slice(2), ArgV[0],
                       GetExecutablePathVP);
Index: clang/tools/driver/cc1_main.cpp
===================================================================
--- clang/tools/driver/cc1_main.cpp
+++ clang/tools/driver/cc1_main.cpp
@@ -181,7 +181,7 @@
   return 0;
 }
 
-int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
+int cc1_main(ArrayRef<const char *> Argv, void *MainAddr) {
   ensureSufficientStack();
 
   std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
@@ -203,12 +203,11 @@
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
   TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
-  bool Success =
-      CompilerInvocation::CreateFromArgs(Clang->getInvocation(), Argv, Diags);
-
+  bool Success = CompilerInvocation::CreateFromArgs(
+      Clang->getInvocation(), Argv.slice(1), Diags, Argv[0]);
   if (Clang->getFrontendOpts().TimeTrace) {
     llvm::timeTraceProfilerInitialize(
-        Clang->getFrontendOpts().TimeTraceGranularity, Argv0);
+        Clang->getFrontendOpts().TimeTraceGranularity, Argv[0]);
   }
   // --print-supported-cpus takes priority over the actual compilation.
   if (Clang->getFrontendOpts().PrintSupportedCPUs)
@@ -218,7 +217,7 @@
   if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
       Clang->getHeaderSearchOpts().ResourceDir.empty())
     Clang->getHeaderSearchOpts().ResourceDir =
-      CompilerInvocation::GetResourcesPath(Argv0, MainAddr);
+        CompilerInvocation::GetResourcesPath(Argv[0], MainAddr);
 
   // Create the actual diagnostics engine.
   Clang->createDiagnostics();
Index: clang/test/CodeGen/debug-info-codeview-buildinfo.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/debug-info-codeview-buildinfo.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cl /c /Z7 %s /Fo%t.obj
+// RUN: llvm-pdbutil dump --types %t.obj | FileCheck %s
+
+int main() { return 42; }
+
+// CHECK:                       Types (.debug$T)
+// CHECK: ============================================================
+// CHECK: 0x[[PWD:.+]] | LF_STRING_ID [size = {{.+}}] ID: <no type>, String: [[PWDVAL:.+]]
+// CHECK: 0x[[FILEPATH:.+]] | LF_STRING_ID [size = {{.+}}] ID: <no type>, String: [[FILEPATHVAL:.+[\\/]debug-info-codeview-buildinfo.c]]
+// CHECK: 0x[[TOOL:.+]] | LF_STRING_ID [size = {{.+}}] ID: <no type>, String: [[TOOLVAL:.+[\\/]clang.*]]
+// CHECK: 0x[[CMDLINE:.+]] | LF_STRING_ID [size = {{.+}}] ID: <no type>, String: -cc1
+// CHECK: 0x{{.+}} | LF_BUILDINFO [size = {{.+}}]
+// CHECK:          0x[[PWD]]: `[[PWDVAL]]`
+// CHECK:          0x[[TOOL]]: `[[TOOLVAL]]`
+// CHECK:          0x[[FILEPATH]]: `[[FILEPATHVAL]]`
+// CHECK:          <no type>: ``
+// CHECK:          0x[[CMDLINE]]: `-cc1
Index: clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
===================================================================
--- clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
+++ clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
@@ -93,7 +93,7 @@
   if (CC1Args)
     *CC1Args = {CCArgs.begin(), CCArgs.end()};
   auto CI = std::make_unique<CompilerInvocation>();
-  if (!CompilerInvocation::CreateFromArgs(*CI, CCArgs, *Diags) &&
+  if (!CompilerInvocation::CreateFromArgs(*CI, CCArgs, *Diags, Args[0]) &&
       !ShouldRecoverOnErorrs)
     return nullptr;
   return CI;
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -3615,7 +3615,8 @@
 
 bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
                                         ArrayRef<const char *> CommandLineArgs,
-                                        DiagnosticsEngine &Diags) {
+                                        DiagnosticsEngine &Diags,
+                                        const char *BuildTool) {
   bool Success = true;
 
   // Parse the arguments.
@@ -3735,6 +3736,11 @@
     Res.getCodeGenOpts().FineGrainedBitfieldAccesses = false;
     Diags.Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored);
   }
+
+  // Store the command-line for using in CodeView backend.
+  Res.getCodeGenOpts().BuildTool = BuildTool;
+  Res.getCodeGenOpts().CommandLineArgs = CommandLineArgs;
+
   return Success;
 }
 
Index: clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -541,6 +541,8 @@
          Entry.Group == frontend::IncludeDirGroup::System))
       Options.MCOptions.IASSearchPaths.push_back(
           Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path);
+  Options.MCOptions.BuildTool = CodeGenOpts.BuildTool;
+  Options.MCOptions.CommandLineArgs = CodeGenOpts.CommandLineArgs;
 }
 static Optional<GCOVOptions> getGCOVOptions(const CodeGenOptions &CodeGenOpts) {
   if (CodeGenOpts.DisableGCov)
Index: clang/include/clang/Frontend/CompilerInvocation.h
===================================================================
--- clang/include/clang/Frontend/CompilerInvocation.h
+++ clang/include/clang/Frontend/CompilerInvocation.h
@@ -155,7 +155,8 @@
   /// \param [out] Res - The resulting invocation.
   static bool CreateFromArgs(CompilerInvocation &Res,
                              ArrayRef<const char *> CommandLineArgs,
-                             DiagnosticsEngine &Diags);
+                             DiagnosticsEngine &Diags,
+                             const char *BuildTool = nullptr);
 
   /// Get the directory where the compiler headers
   /// reside, relative to the compiler binary (found by the passed in
Index: clang/include/clang/Basic/CodeGenOptions.h
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.h
+++ clang/include/clang/Basic/CodeGenOptions.h
@@ -332,6 +332,10 @@
   /// coverage pass should actually not be instrumented.
   std::vector<std::string> SanitizeCoverageBlacklistFiles;
 
+  /// Executable and command-line used to create a given CompilerInvocation.
+  const char *BuildTool = nullptr;
+  ArrayRef<const char *> CommandLineArgs;
+
 public:
   // Define accessors/mutators for code generation options of enumeration type.
 #define CODEGENOPT(Name, Bits, Default)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to