aganea updated this revision to Diff 266989.
aganea added a comment.
Herald added subscribers: cfe-commits, steven_wu, aheejin, arichardson, sbc100, 
emaste.
Herald added a reviewer: espindola.
Herald added a project: clang.

I'm taking over this patch, as discussed offline with Zachary.

I've re-implemented the patch to use the target/final file name of the .OBJ, as 
suggested.

The bulk of the changes is mostly to pass around the file name, down to the 
back end.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D43002

Files:
  clang/include/clang/CodeGen/BackendUtil.h
  clang/include/clang/Frontend/CompilerInstance.h
  clang/include/clang/Frontend/FrontendActions.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/CodeGen/CodeGenAction.cpp
  clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
  clang/lib/Frontend/CompilerInstance.cpp
  clang/lib/Frontend/FrontendActions.cpp
  clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
  clang/lib/Frontend/PrecompiledPreamble.cpp
  clang/lib/Frontend/Rewrite/FrontendActions.cpp
  clang/tools/driver/cc1_main.cpp
  lld/COFF/LTO.cpp
  lld/COFF/LTO.h
  lld/ELF/LTO.cpp
  lld/wasm/LTO.cpp
  llvm/include/llvm/LTO/LTO.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/include/llvm/Support/ToolOutputFile.h
  llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
  llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
  llvm/lib/LTO/Caching.cpp
  llvm/lib/LTO/LTOBackend.cpp
  llvm/test/DebugInfo/COFF/globals.ll
  llvm/test/DebugInfo/COFF/multifunction.ll
  llvm/test/DebugInfo/COFF/pr28747.ll
  llvm/test/DebugInfo/COFF/simple.ll
  llvm/test/DebugInfo/COFF/vframe-fpo.ll
  llvm/test/MC/AArch64/coff-debug.ll
  llvm/test/MC/ARM/coff-debugging-secrel.ll
  llvm/test/MC/COFF/cv-compiler-info.ll
  llvm/tools/llc/llc.cpp
  llvm/tools/llvm-lto2/llvm-lto2.cpp

Index: llvm/tools/llvm-lto2/llvm-lto2.cpp
===================================================================
--- llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -352,7 +352,7 @@
     std::error_code EC;
     auto S = std::make_unique<raw_fd_ostream>(Path, EC, sys::fs::OF_None);
     check(EC, Path);
-    return std::make_unique<lto::NativeObjectStream>(std::move(S));
+    return std::make_unique<lto::NativeObjectStream>(std::move(S), Path);
   };
 
   auto AddBuffer = [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) {
Index: llvm/tools/llc/llc.cpp
===================================================================
--- llvm/tools/llc/llc.cpp
+++ llvm/tools/llc/llc.cpp
@@ -530,6 +530,9 @@
       GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]);
   if (!Out) return 1;
 
+  // Ensure the filename is passed down to CodeViewDebug.
+  Target->Options.MCOptions.OutputPathName = Out->outputFilename();
+
   std::unique_ptr<ToolOutputFile> DwoOut;
   if (!SplitDwarfOutputFile.empty()) {
     std::error_code EC;
Index: llvm/test/MC/COFF/cv-compiler-info.ll
===================================================================
--- llvm/test/MC/COFF/cv-compiler-info.ll
+++ llvm/test/MC/COFF/cv-compiler-info.ll
@@ -1,4 +1,5 @@
-; RUN: llc -mtriple i686-pc-windows-msvc < %s | FileCheck %s
+; RUN: llc -mtriple i686-pc-windows-msvc < %s | FileCheck %s --check-prefixes=CHECK,STDOUT
+; RUN: llc -mtriple i686-pc-windows-msvc < %s -o %t | FileCheck %s --input-file=%t --check-prefixes=CHECK,FILE
 ; ModuleID = 'D:\src\scopes\foo.cpp'
 source_filename = "D:\5Csrc\5Cscopes\5Cfoo.cpp"
 target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
@@ -20,19 +21,23 @@
 ; One .debug$S section should contain an S_COMPILE3 record that identifies the
 ; source language and the version of the compiler based on the DICompileUnit.
 ; CHECK: 	.section	.debug$S,"dr"
+; CHECK:        .short  4353                    # Record kind: S_OBJNAME
+; CHECK-NEXT:   .long   0                       # Signature
+; STDOUT-NEXT:  .byte   0                       # Object name
+; FILE-NEXT:    .asciz	"{{.*}}{{\\\\|/}}cv-compiler-info.ll.tmp" # Object name
 ; CHECK: 		.short	4412                  # Record kind: S_COMPILE3
-; CHECK: 		.long	1                       # Flags and language
-; CHECK: 		.short	7                     # CPUType
-; CHECK: 		.short	4                     # Frontend version
-; CHECK: 		.short	0
-; CHECK: 		.short	0
-; CHECK: 		.short	0
-; CHECK: 		.short	[[BACKEND_VERSION:[0-9]+]]  # Backend version
-; CHECK: 		.short	0
-; CHECK: 		.short	0
-; CHECK: 		.short	0
-; CHECK: 		.asciz	"clang version 4.0.0 "  # Null-terminated compiler version string
-; CHECK-NOT: .short	4412                  # Record kind: S_COMPILE3
+; CHECK-NEXT:   .long	1                       # Flags and language
+; CHECK-NEXT: 	.short	7                     # CPUType
+; CHECK-NEXT: 	.short	4                     # Frontend version
+; CHECK-NEXT: 	.short	0
+; CHECK-NEXT: 	.short	0
+; CHECK-NEXT: 	.short	0
+; CHECK-NEXT: 	.short	[[BACKEND_VERSION:[0-9]+]]  # Backend version
+; CHECK-NEXT: 	.short	0
+; CHECK-NEXT: 	.short	0
+; CHECK-NEXT: 	.short	0
+; CHECK-NEXT: 	.asciz	"clang version 4.0.0 "  # Null-terminated compiler version string
+; CHECK-NOT:    .short	4412                  # Record kind: S_COMPILE3
 !1 = !DIFile(filename: "D:\5Csrc\5Cscopes\5Cfoo.cpp", directory: "D:\5Csrc\5Cscopes\5Cclang")
 !2 = !{}
 !7 = !{i32 2, !"CodeView", i32 1}
Index: llvm/test/MC/ARM/coff-debugging-secrel.ll
===================================================================
--- llvm/test/MC/ARM/coff-debugging-secrel.ll
+++ llvm/test/MC/ARM/coff-debugging-secrel.ll
@@ -42,10 +42,10 @@
 
 ; CHECK-MSVC: Relocations [
 ; CHECK-MSVC:   Section {{.*}} .debug$S {
-; CHECK-MSVC:     0x64 IMAGE_REL_ARM_SECREL function
-; CHECK-MSVC:     0x68 IMAGE_REL_ARM_SECTION function
-; CHECK-MSVC:     0xA0 IMAGE_REL_ARM_SECREL function
-; CHECK-MSVC:     0xA4 IMAGE_REL_ARM_SECTION function
+; CHECK-MSVC:     0x70 IMAGE_REL_ARM_SECREL function
+; CHECK-MSVC:     0x74 IMAGE_REL_ARM_SECTION function
+; CHECK-MSVC:     0xAC IMAGE_REL_ARM_SECREL function
+; CHECK-MSVC:     0xB0 IMAGE_REL_ARM_SECTION function
 ; CHECK-MSVC:   }
 ; CHECK-MSVC: ]
 
Index: llvm/test/MC/AArch64/coff-debug.ll
===================================================================
--- llvm/test/MC/AArch64/coff-debug.ll
+++ llvm/test/MC/AArch64/coff-debug.ll
@@ -1,5 +1,7 @@
 ; RUN: llc -mtriple=aarch64-windows -filetype=obj -o - %s | \
-; RUN: llvm-readobj --codeview - | FileCheck %s
+; RUN: llvm-readobj --codeview - | FileCheck %s --check-prefixes=CHECK,STDOUT
+; RUN: llc -mtriple=aarch64-windows -filetype=obj -o %t %s
+; RUN: llvm-readobj --codeview %t | FileCheck %s --check-prefixes=CHECK,FILE
 
 ; ModuleID = 'a.c'
 source_filename = "a.c"
@@ -66,6 +68,12 @@
 ; CHECK:   Magic: 0x4
 ; CHECK:   Subsection [
 ; CHECK:     SubSectionType: Symbols (0xF1)
+; CHECK:     ObjNameSym {
+; CHECK:       Kind: S_OBJNAME (0x1101)
+; CHECK:       Signature: 0x0
+; CHECK:       ObjectName:
+; FILE-SAME: {{.*}}
+; CHECK:     }
 ; CHECK:     Compile3Sym {
 ; CHECK:       Kind: S_COMPILE3 (0x113C)
 ; CHECK:       Language: C (0x0)
Index: llvm/test/DebugInfo/COFF/vframe-fpo.ll
===================================================================
--- llvm/test/DebugInfo/COFF/vframe-fpo.ll
+++ llvm/test/DebugInfo/COFF/vframe-fpo.ll
@@ -65,7 +65,9 @@
 ; CODEVIEW-NEXT:   Subsection [
 ; CODEVIEW-NEXT:     SubSectionType: Symbols (0xF1)
 ; CODEVIEW-NEXT:     SubSectionSize:
-; CODEVIEW-NEXT:     Compile3Sym {
+; CODEVIEW-NEXT:     ObjNameSym {
+; CODEVIEW-NEXT:       Kind: S_OBJNAME (0x1101)
+; CODEVIEW:          Compile3Sym {
 ; CODEVIEW-NEXT:       Kind: S_COMPILE3 (0x113C)
 ; CODEVIEW:          }
 ; CODEVIEW:        ]
Index: llvm/test/DebugInfo/COFF/simple.ll
===================================================================
--- llvm/test/DebugInfo/COFF/simple.ll
+++ llvm/test/DebugInfo/COFF/simple.ll
@@ -36,8 +36,10 @@
 ; X86-NEXT: .long [[COMPILE_END:.*]]-[[COMPILE_START:.*]] #
 ; Compiler information record
 ; X86-NEXT: [[COMPILE_START]]:
-; X86-NEXT: .short [[C1_END:.*]]-[[C1_START:.*]] #
-; X86:      [[C1_END]]:
+; X86-NEXT: .short [[OBJNAME_END:.*]]-[[OBJNAME_START:.*]] #
+; X86:      [[OBJNAME_END]]:
+; X86-NEXT: .short [[COMPILE3_END:.*]]-[[COMPILE3_START:.*]] #
+; X86:      [[COMPILE3_END]]:
 ; X86-NEXT: [[COMPILE_END]]:
 ; X86-NEXT: .p2align	2
 ; X86-NEXT:	.cv_fpo_data _f
@@ -88,11 +90,11 @@
 ; OBJ32:      Characteristics [ (0x42300040)
 ; OBJ32:      ]
 ; OBJ32:      Relocations [
-; OBJ32-NEXT:   0x44 IMAGE_REL_I386_DIR32NB _f
-; OBJ32-NEXT:   0x90 IMAGE_REL_I386_SECREL _f
-; OBJ32-NEXT:   0x94 IMAGE_REL_I386_SECTION _f
-; OBJ32-NEXT:   0xC8 IMAGE_REL_I386_SECREL _f
-; OBJ32-NEXT:   0xCC IMAGE_REL_I386_SECTION _f
+; OBJ32-NEXT:   0x50 IMAGE_REL_I386_DIR32NB _f
+; OBJ32-NEXT:   0x9C IMAGE_REL_I386_SECREL _f
+; OBJ32-NEXT:   0xA0 IMAGE_REL_I386_SECTION _f
+; OBJ32-NEXT:   0xD4 IMAGE_REL_I386_SECREL _f
+; OBJ32-NEXT:   0xD8 IMAGE_REL_I386_SECTION _f
 ; OBJ32-NEXT: ]
 ; OBJ32:      Subsection [
 ; OBJ32-NEXT:   SubSectionType: Symbols (0xF1)
@@ -165,8 +167,10 @@
 ; X64-NEXT: .long [[COMPILE_END:.*]]-[[COMPILE_START:.*]] #
 ; Compiler information record
 ; X64-NEXT: [[COMPILE_START]]:
-; X64-NEXT: .short [[C1_END:.*]]-[[C1_START:.*]] #
-; X64:      [[C1_END]]:
+; X64-NEXT: .short [[OBJNAME_END:.*]]-[[OBJNAME_START:.*]] #
+; X64:      [[OBJNAME_END]]:
+; X64-NEXT: .short [[COMPILE3_END:.*]]-[[COMPILE3_START:.*]] #
+; X64:      [[COMPILE3_END]]:
 ; X64-NEXT: [[COMPILE_END]]:
 ; X64-NEXT: .p2align	2
 ; X64-NEXT:	.long	241  # Symbol subsection for f
@@ -216,10 +220,10 @@
 ; OBJ64:      Characteristics [ (0x42300040)
 ; OBJ64:      ]
 ; OBJ64:      Relocations [
-; OBJ64-NEXT:   0x64 IMAGE_REL_AMD64_SECREL f
-; OBJ64-NEXT:   0x68 IMAGE_REL_AMD64_SECTION f
-; OBJ64-NEXT:   0x9C IMAGE_REL_AMD64_SECREL f
-; OBJ64-NEXT:   0xA0 IMAGE_REL_AMD64_SECTION f
+; OBJ64-NEXT:   0x70 IMAGE_REL_AMD64_SECREL f
+; OBJ64-NEXT:   0x74 IMAGE_REL_AMD64_SECTION f
+; OBJ64-NEXT:   0xA8 IMAGE_REL_AMD64_SECREL f
+; OBJ64-NEXT:   0xAC IMAGE_REL_AMD64_SECTION f
 ; OBJ64-NEXT: ]
 ; OBJ64:      Subsection [
 ; OBJ64-NEXT:   SubSectionType: Symbols (0xF1)
Index: llvm/test/DebugInfo/COFF/pr28747.ll
===================================================================
--- llvm/test/DebugInfo/COFF/pr28747.ll
+++ llvm/test/DebugInfo/COFF/pr28747.ll
@@ -5,8 +5,10 @@
 ; CHECK-NEXT:        .long	241
 ; CHECK-NEXT:        .long	[[SUBSEC_END:.*]]-[[SUBSEC_START:.*]] # Subsection size
 ; CHECK-NEXT:        [[SUBSEC_START]]:
-; CHECK-NEXT:        .short	[[C1_END:.*]]-[[C1_START:.*]] # Record length
-; CHECK:             [[C1_END]]:
+; CHECK-NEXT:        .short	[[OBJNAME_END:.*]]-[[OBJNAME_START:.*]] # Record length
+; CHECK:             [[OBJNAME_END]]:
+; CHECK-NEXT:        .short	[[COMPILE3_END:.*]]-[[COMPILE3_START:.*]] # Record length
+; CHECK:             [[COMPILE3_END]]:
 ; CHECK-NEXT:        [[SUBSEC_END]]:
 ; CHECK-NEXT:        .p2align 2
 ; CHECK-NEXT:        .cv_filechecksums
Index: llvm/test/DebugInfo/COFF/multifunction.ll
===================================================================
--- llvm/test/DebugInfo/COFF/multifunction.ll
+++ llvm/test/DebugInfo/COFF/multifunction.ll
@@ -498,18 +498,18 @@
 ; OBJ64:      Characteristics [ (0x42300040)
 ; OBJ64:      ]
 ; OBJ64:      Relocations [
-; OBJ64-NEXT:   0x64 IMAGE_REL_AMD64_SECREL x
-; OBJ64-NEXT:   0x68 IMAGE_REL_AMD64_SECTION x
-; OBJ64-NEXT:   0x9C IMAGE_REL_AMD64_SECREL x
-; OBJ64-NEXT:   0xA0 IMAGE_REL_AMD64_SECTION x
-; OBJ64-NEXT:   0x100 IMAGE_REL_AMD64_SECREL y
-; OBJ64-NEXT:   0x104 IMAGE_REL_AMD64_SECTION y
-; OBJ64-NEXT:   0x138 IMAGE_REL_AMD64_SECREL y
-; OBJ64-NEXT:   0x13C IMAGE_REL_AMD64_SECTION y
-; OBJ64-NEXT:   0x19C IMAGE_REL_AMD64_SECREL f
-; OBJ64-NEXT:   0x1A0 IMAGE_REL_AMD64_SECTION f
-; OBJ64-NEXT:   0x1D4 IMAGE_REL_AMD64_SECREL f
-; OBJ64-NEXT:   0x1D8 IMAGE_REL_AMD64_SECTION f
+; OBJ64-NEXT:   0x70 IMAGE_REL_AMD64_SECREL x
+; OBJ64-NEXT:   0x74 IMAGE_REL_AMD64_SECTION x
+; OBJ64-NEXT:   0xA8 IMAGE_REL_AMD64_SECREL x
+; OBJ64-NEXT:   0xAC IMAGE_REL_AMD64_SECTION x
+; OBJ64-NEXT:   0x10C IMAGE_REL_AMD64_SECREL y
+; OBJ64-NEXT:   0x110 IMAGE_REL_AMD64_SECTION y
+; OBJ64-NEXT:   0x144 IMAGE_REL_AMD64_SECREL y
+; OBJ64-NEXT:   0x148 IMAGE_REL_AMD64_SECTION y
+; OBJ64-NEXT:   0x1A8 IMAGE_REL_AMD64_SECREL f
+; OBJ64-NEXT:   0x1AC IMAGE_REL_AMD64_SECTION f
+; OBJ64-NEXT:   0x1E0 IMAGE_REL_AMD64_SECREL f
+; OBJ64-NEXT:   0x1E4 IMAGE_REL_AMD64_SECTION f
 ; OBJ64-NEXT: ]
 ; OBJ64:      Subsection [
 ; OBJ64-NEXT:   SubSectionType: Symbols (0xF1)
Index: llvm/test/DebugInfo/COFF/globals.ll
===================================================================
--- llvm/test/DebugInfo/COFF/globals.ll
+++ llvm/test/DebugInfo/COFF/globals.ll
@@ -1,7 +1,9 @@
 ; RUN: llc < %s | FileCheck %s --check-prefix=ASM
 ; RUN: llc < %s -filetype=obj | llvm-readobj - --codeview | FileCheck %s --check-prefix=OBJ
 ; RUN: llc < %s | llvm-mc -filetype=obj --triple=x86_64-windows | llvm-readobj - --codeview | FileCheck %s --check-prefix=OBJ
-; RUN: llc < %s -filetype=obj | obj2yaml | FileCheck %s --check-prefix=YAML
+; RUN: llc < %s -filetype=obj | obj2yaml | FileCheck %s --check-prefixes=YAML,YAML-STDOUT
+; RUN: llc < %s -filetype=obj -o %t
+; RUN: obj2yaml < %t | FileCheck %s --check-prefixes=YAML,YAML-FILE
 
 ; C++ source to regenerate:
 ; $ cat a.cpp
@@ -246,6 +248,11 @@
 ; YAML:    Subsections:
 ; YAML:      - !Symbols
 ; YAML:        Records:
+; YAML:          - Kind:            S_OBJNAME
+; YAML:            ObjNameSym:
+; YAML:               Signature:       0
+; YAML-STDOUT         ObjectName:      ''
+; YAML-FILE           ObjectName:      '{{.*}}'
 ; YAML:          - Kind:            S_COMPILE3
 ; YAML:            Compile3Sym:
 
Index: llvm/lib/LTO/LTOBackend.cpp
===================================================================
--- llvm/lib/LTO/LTOBackend.cpp
+++ llvm/lib/LTO/LTOBackend.cpp
@@ -391,6 +391,8 @@
   }
 
   auto Stream = AddStream(Task);
+  TM->Options.MCOptions.OutputPathName = Stream->ObjectPathName;
+
   legacy::PassManager CodeGenPasses;
   if (TM->addPassesToEmitFile(CodeGenPasses, *Stream->OS,
                               DwoOut ? &DwoOut->os() : nullptr,
Index: llvm/lib/LTO/Caching.cpp
===================================================================
--- llvm/lib/LTO/Caching.cpp
+++ llvm/lib/LTO/Caching.cpp
@@ -72,14 +72,13 @@
     struct CacheStream : NativeObjectStream {
       AddBufferFn AddBuffer;
       sys::fs::TempFile TempFile;
-      std::string EntryPath;
       unsigned Task;
 
       CacheStream(std::unique_ptr<raw_pwrite_stream> OS, AddBufferFn AddBuffer,
                   sys::fs::TempFile TempFile, std::string EntryPath,
                   unsigned Task)
-          : NativeObjectStream(std::move(OS)), AddBuffer(std::move(AddBuffer)),
-            TempFile(std::move(TempFile)), EntryPath(std::move(EntryPath)),
+          : NativeObjectStream(std::move(OS), std::move(EntryPath)),
+            AddBuffer(std::move(AddBuffer)), TempFile(std::move(TempFile)),
             Task(Task) {}
 
       ~CacheStream() {
@@ -105,14 +104,14 @@
         // AddBuffer a copy of the bytes we wrote in that case. We do this
         // instead of just using the existing file, because the pruner might
         // delete the file before we get a chance to use it.
-        Error E = TempFile.keep(EntryPath);
+        Error E = TempFile.keep(ObjectPathName);
         E = handleErrors(std::move(E), [&](const ECError &E) -> Error {
           std::error_code EC = E.convertToErrorCode();
           if (EC != errc::permission_denied)
             return errorCodeToError(EC);
 
           auto MBCopy = MemoryBuffer::getMemBufferCopy((*MBOrErr)->getBuffer(),
-                                                       EntryPath);
+                                                       ObjectPathName);
           MBOrErr = std::move(MBCopy);
 
           // FIXME: should we consume the discard error?
@@ -123,7 +122,7 @@
 
         if (E)
           report_fatal_error(Twine("Failed to rename temporary file ") +
-                             TempFile.TmpName + " to " + EntryPath + ": " +
+                             TempFile.TmpName + " to " + ObjectPathName + ": " +
                              toString(std::move(E)) + "\n");
 
         AddBuffer(Task, std::move(*MBOrErr));
Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -296,6 +296,8 @@
 
   void emitTypeGlobalHashes();
 
+  void emitObjName();
+
   void emitCompilerInformation();
 
   void emitBuildInfo();
Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -590,6 +590,7 @@
   switchToDebugSectionForSymbol(nullptr);
 
   MCSymbol *CompilerInfo = beginCVSubsection(DebugSubsectionKind::Symbols);
+  emitObjName();
   emitCompilerInformation();
   endCVSubsection(CompilerInfo);
 
@@ -757,6 +758,44 @@
   }
 }
 
+static void unescapeSlashes(SmallVectorImpl<char> &Str) {
+  auto Read = Str.begin();
+  auto Write = Read;
+  while (Read != Str.end()) {
+    bool WasSlash = (*Read == '\\');
+    *Write++ = *Read++;
+    if (WasSlash && Read != Str.end() && *Read == '\\')
+      ++Read;
+  }
+  Str.resize(Write - Str.begin());
+}
+
+void CodeViewDebug::emitObjName() {
+  MCSymbol *CompilerEnd = beginSymbolRecord(SymbolKind::S_OBJNAME);
+
+  StringRef PathRef(Asm->TM.Options.MCOptions.OutputPathName);
+  assert(PathRef == "-" || !PathRef.empty());
+  llvm::SmallString<256> Path(PathRef);
+
+  if (Path == "-") {
+    // Don't emit the filename if we're writing to stdout.
+    Path.clear();
+  } else {
+    llvm::sys::fs::make_absolute(Path);
+    llvm::sys::path::remove_dots(Path, /*remove_dot_dot=*/true);
+    unescapeSlashes(Path);
+    assert(llvm::sys::path::is_absolute(Path));
+  }
+
+  OS.AddComment("Signature");
+  OS.emitInt32(0);
+
+  OS.AddComment("Object name");
+  emitNullTerminatedSymbolName(OS, Path);
+
+  endSymbolRecord(CompilerEnd);
+}
+
 namespace {
 struct Version {
   int Part[4];
Index: llvm/include/llvm/Support/ToolOutputFile.h
===================================================================
--- llvm/include/llvm/Support/ToolOutputFile.h
+++ llvm/include/llvm/Support/ToolOutputFile.h
@@ -28,9 +28,10 @@
   /// raw_fd_ostream is destructed. It installs cleanups in its constructor and
   /// uninstalls them in its destructor.
   class CleanupInstaller {
+  public:
     /// The name of the file.
     std::string Filename;
-  public:
+
     /// The flag which indicates whether we should not delete the file.
     bool Keep;
 
@@ -55,6 +56,8 @@
   /// Indicate that the tool's job wrt this output file has been successful and
   /// the file should not be deleted.
   void keep() { Installer.Keep = true; }
+
+  const std::string &outputFilename() { return Installer.Filename; }
 };
 
 } // end llvm namespace
Index: llvm/include/llvm/MC/MCTargetOptions.h
===================================================================
--- llvm/include/llvm/MC/MCTargetOptions.h
+++ llvm/include/llvm/MC/MCTargetOptions.h
@@ -58,6 +58,7 @@
   std::string ABIName;
   std::string AssemblyLanguage;
   std::string SplitDwarfFile;
+  std::string OutputPathName;
 
   /// Additional paths to search for `.include` directives when using the
   /// integrated assembler.
Index: llvm/include/llvm/LTO/LTO.h
===================================================================
--- llvm/include/llvm/LTO/LTO.h
+++ llvm/include/llvm/LTO/LTO.h
@@ -187,8 +187,10 @@
 /// destructor.
 class NativeObjectStream {
 public:
-  NativeObjectStream(std::unique_ptr<raw_pwrite_stream> OS) : OS(std::move(OS)) {}
+  NativeObjectStream(std::unique_ptr<raw_pwrite_stream> OS, std::string OSPath)
+      : OS(std::move(OS)), ObjectPathName(OSPath) {}
   std::unique_ptr<raw_pwrite_stream> OS;
+  std::string ObjectPathName;
   virtual ~NativeObjectStream() = default;
 };
 
Index: lld/wasm/LTO.cpp
===================================================================
--- lld/wasm/LTO.cpp
+++ lld/wasm/LTO.cpp
@@ -136,7 +136,7 @@
   checkError(ltoObj->run(
       [&](size_t task) {
         return std::make_unique<lto::NativeObjectStream>(
-            std::make_unique<raw_svector_ostream>(buf[task]));
+            std::make_unique<raw_svector_ostream>(buf[task]), /*OSPath=*/"");
       },
       cache));
 
Index: lld/ELF/LTO.cpp
===================================================================
--- lld/ELF/LTO.cpp
+++ lld/ELF/LTO.cpp
@@ -291,7 +291,8 @@
     checkError(ltoObj->run(
         [&](size_t task) {
           return std::make_unique<lto::NativeObjectStream>(
-              std::make_unique<raw_svector_ostream>(buf[task]));
+              std::make_unique<raw_svector_ostream>(buf[task]),
+              /*OSPath=*/"");
         },
         cache));
 
Index: lld/COFF/LTO.h
===================================================================
--- lld/COFF/LTO.h
+++ lld/COFF/LTO.h
@@ -50,6 +50,7 @@
 private:
   std::unique_ptr<llvm::lto::LTO> ltoObj;
   std::vector<SmallString<0>> buf;
+  std::vector<std::string> objFilePath;
   std::vector<std::unique_ptr<MemoryBuffer>> files;
   std::unique_ptr<llvm::raw_fd_ostream> indexFile;
   llvm::DenseSet<StringRef> thinIndices;
Index: lld/COFF/LTO.cpp
===================================================================
--- lld/COFF/LTO.cpp
+++ lld/COFF/LTO.cpp
@@ -148,6 +148,7 @@
 std::vector<InputFile *> BitcodeCompiler::compile() {
   unsigned maxTasks = ltoObj->getMaxTasks();
   buf.resize(maxTasks);
+  objFilePath.resize(maxTasks);
   files.resize(maxTasks);
 
   // The /lldltocache option specifies the path to a directory in which to cache
@@ -160,10 +161,31 @@
           files[task] = std::move(mb);
         }));
 
+  // Compute the target file names in advance, because we might need to write
+  // them into the S_OBJNAME CodeView record.
+  if (config->thinLTOIndexOnly) {
+    if (!config->ltoObjPath.empty())
+      objFilePath[0] = config->ltoObjPath.str();
+  } else {
+    for (unsigned i = 0; i != maxTasks; ++i) {
+      // Assign unique names to LTO objects. This ensures they have unique names
+      // in the PDB if one is produced. The names should look like:
+      // - foo.exe.lto.obj
+      // - foo.exe.lto.1.obj
+      // - ...
+      objFilePath[i] =
+          saver
+              .save(Twine(config->outputFile) + ".lto" +
+                    (i == 0 ? Twine("") : Twine('.') + Twine(i)) + ".obj")
+              .str();
+    }
+  }
+
   checkError(ltoObj->run(
       [&](size_t task) {
         return std::make_unique<lto::NativeObjectStream>(
-            std::make_unique<raw_svector_ostream>(buf[task]));
+            std::make_unique<raw_svector_ostream>(buf[task]),
+            objFilePath[task]);
       },
       cache));
 
@@ -180,7 +202,7 @@
   // distributed environment.
   if (config->thinLTOIndexOnly) {
     if (!config->ltoObjPath.empty())
-      saveBuffer(buf[0], config->ltoObjPath);
+      saveBuffer(buf[0], objFilePath[0]);
     if (indexFile)
       indexFile->close();
     return {};
@@ -191,15 +213,6 @@
 
   std::vector<InputFile *> ret;
   for (unsigned i = 0; i != maxTasks; ++i) {
-    // Assign unique names to LTO objects. This ensures they have unique names
-    // in the PDB if one is produced. The names should look like:
-    // - foo.exe.lto.obj
-    // - foo.exe.lto.1.obj
-    // - ...
-    StringRef ltoObjName =
-        saver.save(Twine(config->outputFile) + ".lto" +
-                   (i == 0 ? Twine("") : Twine('.') + Twine(i)) + ".obj");
-
     // Get the native object contents either from the cache or from memory.  Do
     // not use the cached MemoryBuffer directly, or the PDB will not be
     // deterministic.
@@ -212,8 +225,8 @@
       continue;
 
     if (config->saveTemps)
-      saveBuffer(buf[i], ltoObjName);
-    ret.push_back(make<ObjFile>(MemoryBufferRef(objBuf, ltoObjName)));
+      saveBuffer(buf[i], objFilePath[i]);
+    ret.push_back(make<ObjFile>(MemoryBufferRef(objBuf, objFilePath[i])));
   }
 
   return ret;
Index: clang/tools/driver/cc1_main.cpp
===================================================================
--- clang/tools/driver/cc1_main.cpp
+++ clang/tools/driver/cc1_main.cpp
@@ -248,16 +248,18 @@
   if (llvm::timeTraceProfilerEnabled()) {
     SmallString<128> Path(Clang->getFrontendOpts().OutputFile);
     llvm::sys::path::replace_extension(Path, "json");
-    if (auto profilerOutput =
-            Clang->createOutputFile(Path.str(),
-                                    /*Binary=*/false,
-                                    /*RemoveFileOnSignal=*/false, "",
-                                    /*Extension=*/"json",
-                                    /*useTemporary=*/false)) {
-
-      llvm::timeTraceProfilerWrite(*profilerOutput);
+    std::unique_ptr<raw_pwrite_stream> ProfilerOS;
+    std::string ProfilerOutputFilePath;
+    std::tie(ProfilerOS, ProfilerOutputFilePath) =
+        Clang->createOutputFile(Path.str(),
+                                /*Binary=*/false,
+                                /*RemoveFileOnSignal=*/false, "",
+                                /*Extension=*/"json",
+                                /*useTemporary=*/false);
+    if (ProfilerOS) {
+      llvm::timeTraceProfilerWrite(*ProfilerOS);
       // FIXME(ibiryukov): make profilerOutput flush in destructor instead.
-      profilerOutput->flush();
+      ProfilerOS->flush();
       llvm::timeTraceProfilerCleanup();
       Clang->clearOutputFiles(false);
     }
Index: clang/lib/Frontend/Rewrite/FrontendActions.cpp
===================================================================
--- clang/lib/Frontend/Rewrite/FrontendActions.cpp
+++ clang/lib/Frontend/Rewrite/FrontendActions.cpp
@@ -39,8 +39,10 @@
 
 std::unique_ptr<ASTConsumer>
 HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
-  if (std::unique_ptr<raw_ostream> OS =
-          CI.createDefaultOutputFile(false, InFile))
+  std::string OutputPathName;
+  std::unique_ptr<raw_ostream> OS;
+  std::tie(OS, OutputPathName) = CI.createDefaultOutputFile(false, InFile);
+  if (OS)
     return CreateHTMLPrinter(std::move(OS), CI.getPreprocessor());
   return nullptr;
 }
@@ -162,8 +164,11 @@
 
 std::unique_ptr<ASTConsumer>
 RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
-  if (std::unique_ptr<raw_ostream> OS =
-          CI.createDefaultOutputFile(false, InFile, "cpp")) {
+  std::string OutputPathName;
+  std::unique_ptr<raw_ostream> OS;
+  std::tie(OS, OutputPathName) =
+      CI.createDefaultOutputFile(false, InFile, "cpp");
+  if (OS) {
     if (CI.getLangOpts().ObjCRuntime.isNonFragile())
       return CreateModernObjCRewriter(
           std::string(InFile), std::move(OS), CI.getDiagnostics(),
@@ -184,16 +189,21 @@
 
 void RewriteMacrosAction::ExecuteAction() {
   CompilerInstance &CI = getCompilerInstance();
-  std::unique_ptr<raw_ostream> OS =
+  std::string OutputPathName;
+  std::unique_ptr<raw_ostream> OS;
+  std::tie(OS, OutputPathName) =
       CI.createDefaultOutputFile(true, getCurrentFileOrBufferName());
-  if (!OS) return;
+  if (!OS)
+    return;
 
   RewriteMacrosInInput(CI.getPreprocessor(), OS.get());
 }
 
 void RewriteTestAction::ExecuteAction() {
   CompilerInstance &CI = getCompilerInstance();
-  std::unique_ptr<raw_ostream> OS =
+  std::string OutputPathName;
+  std::unique_ptr<raw_ostream> OS;
+  std::tie(OS, OutputPathName) =
       CI.createDefaultOutputFile(false, getCurrentFileOrBufferName());
   if (!OS) return;
 
@@ -269,7 +279,8 @@
 
 bool RewriteIncludesAction::BeginSourceFileAction(CompilerInstance &CI) {
   if (!OutputStream) {
-    OutputStream =
+    std::string OutputPathName;
+    std::tie(OutputStream, OutputPathName) =
         CI.createDefaultOutputFile(true, getCurrentFileOrBufferName());
     if (!OutputStream)
       return false;
Index: clang/lib/Frontend/PrecompiledPreamble.cpp
===================================================================
--- clang/lib/Frontend/PrecompiledPreamble.cpp
+++ clang/lib/Frontend/PrecompiledPreamble.cpp
@@ -206,7 +206,7 @@
     OS = std::make_unique<llvm::raw_string_ostream>(*InMemStorage);
   } else {
     std::string OutputFile;
-    OS = GeneratePCHAction::CreateOutputFile(CI, InFile, OutputFile);
+    std::tie(OS, OutputFile) = GeneratePCHAction::CreateOutputFile(CI, InFile);
   }
   if (!OS)
     return nullptr;
Index: clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
===================================================================
--- clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
+++ clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
@@ -266,7 +266,10 @@
     v.TraverseDecl(context.getTranslationUnitDecl());
 
     MangledSymbols Symbols;
-    auto OS = Instance.createDefaultOutputFile(/*Binary=*/false, InFile, "ifs");
+    std::unique_ptr<raw_pwrite_stream> OS;
+    std::string OutputPathName;
+    std::tie(OS, OutputPathName) =
+        Instance.createDefaultOutputFile(/*Binary=*/false, InFile, "ifs");
     if (!OS)
       return;
 
Index: clang/lib/Frontend/FrontendActions.cpp
===================================================================
--- clang/lib/Frontend/FrontendActions.cpp
+++ clang/lib/Frontend/FrontendActions.cpp
@@ -68,8 +68,10 @@
 
 std::unique_ptr<ASTConsumer>
 ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
-  if (std::unique_ptr<raw_ostream> OS =
-          CI.createDefaultOutputFile(false, InFile))
+  std::string OutputPathName;
+  std::unique_ptr<raw_ostream> OS;
+  std::tie(OS, OutputPathName) = CI.createDefaultOutputFile(false, InFile);
+  if (OS)
     return CreateASTPrinter(std::move(OS), CI.getFrontendOpts().ASTDumpFilter);
   return nullptr;
 }
@@ -99,8 +101,8 @@
     return nullptr;
 
   std::string OutputFile;
-  std::unique_ptr<raw_pwrite_stream> OS =
-      CreateOutputFile(CI, InFile, /*ref*/ OutputFile);
+  std::unique_ptr<raw_pwrite_stream> OS;
+  std::tie(OS, OutputFile) = CreateOutputFile(CI, InFile);
   if (!OS)
     return nullptr;
 
@@ -132,21 +134,15 @@
   return true;
 }
 
-std::unique_ptr<llvm::raw_pwrite_stream>
-GeneratePCHAction::CreateOutputFile(CompilerInstance &CI, StringRef InFile,
-                                    std::string &OutputFile) {
+std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
+GeneratePCHAction::CreateOutputFile(CompilerInstance &CI, StringRef InFile) {
   // We use createOutputFile here because this is exposed via libclang, and we
   // must disable the RemoveFileOnSignal behavior.
   // We use a temporary to avoid race conditions.
-  std::unique_ptr<raw_pwrite_stream> OS =
-      CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
-                          /*RemoveFileOnSignal=*/false, InFile,
-                          /*Extension=*/"", CI.getFrontendOpts().UseTemporary);
-  if (!OS)
-    return nullptr;
-
-  OutputFile = CI.getFrontendOpts().OutputFile;
-  return OS;
+  return CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
+                             /*RemoveFileOnSignal=*/false, InFile,
+                             /*Extension=*/"",
+                             CI.getFrontendOpts().UseTemporary);
 }
 
 bool GeneratePCHAction::shouldEraseOutputFiles() {
@@ -163,11 +159,12 @@
 std::unique_ptr<ASTConsumer>
 GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
                                         StringRef InFile) {
-  std::unique_ptr<raw_pwrite_stream> OS = CreateOutputFile(CI, InFile);
+  std::unique_ptr<raw_pwrite_stream> OS;
+  std::string OutputFile;
+  std::tie(OS, OutputFile) = CreateOutputFile(CI, InFile);
   if (!OS)
     return nullptr;
 
-  std::string OutputFile = CI.getFrontendOpts().OutputFile;
   std::string Sysroot;
 
   auto Buffer = std::make_shared<PCHBuffer>();
@@ -196,7 +193,7 @@
   return GenerateModuleAction::BeginSourceFileAction(CI);
 }
 
-std::unique_ptr<raw_pwrite_stream>
+std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
 GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI,
                                                     StringRef InFile) {
   // If no output file was provided, figure out where this module would go
@@ -233,7 +230,7 @@
   return GenerateModuleAction::BeginSourceFileAction(CI);
 }
 
-std::unique_ptr<raw_pwrite_stream>
+std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
 GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI,
                                                 StringRef InFile) {
   return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
@@ -303,7 +300,7 @@
   return GenerateModuleAction::BeginSourceFileAction(CI);
 }
 
-std::unique_ptr<raw_pwrite_stream>
+std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
 GenerateHeaderModuleAction::CreateOutputFile(CompilerInstance &CI,
                                              StringRef InFile) {
   return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
@@ -827,7 +824,9 @@
     }
   }
 
-  std::unique_ptr<raw_ostream> OS =
+  std::unique_ptr<raw_ostream> OS;
+  std::string OutputPathName;
+  std::tie(OS, OutputPathName) =
       CI.createDefaultOutputFile(BinaryMode, getCurrentFileOrBufferName());
   if (!OS) return;
 
@@ -882,7 +881,9 @@
 
 void DumpCompilerOptionsAction::ExecuteAction() {
   CompilerInstance &CI = getCompilerInstance();
-  std::unique_ptr<raw_ostream> OSP =
+  std::unique_ptr<raw_ostream> OSP;
+  std::string OutputPathName;
+  std::tie(OSP, OutputPathName) =
       CI.createDefaultOutputFile(false, getCurrentFile());
   if (!OSP)
     return;
Index: clang/lib/Frontend/CompilerInstance.cpp
===================================================================
--- clang/lib/Frontend/CompilerInstance.cpp
+++ clang/lib/Frontend/CompilerInstance.cpp
@@ -646,15 +646,10 @@
       if (EraseFiles) {
         llvm::sys::fs::remove(OF.TempFilename);
       } else {
-        SmallString<128> NewOutFile(OF.Filename);
-
-        // If '-working-directory' was passed, the output filename should be
-        // relative to that.
-        FileMgr->FixupRelativePath(NewOutFile);
         if (std::error_code ec =
-                llvm::sys::fs::rename(OF.TempFilename, NewOutFile)) {
+                llvm::sys::fs::rename(OF.TempFilename, OF.Filename)) {
           getDiagnostics().Report(diag::err_unable_to_rename_temp)
-            << OF.TempFilename << OF.Filename << ec.message();
+              << OF.TempFilename << OF.Filename << ec.message();
 
           llvm::sys::fs::remove(OF.TempFilename);
         }
@@ -671,7 +666,7 @@
   NonSeekStream.reset();
 }
 
-std::unique_ptr<raw_pwrite_stream>
+std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
 CompilerInstance::createDefaultOutputFile(bool Binary, StringRef InFile,
                                           StringRef Extension) {
   return createOutputFile(getFrontendOpts().OutputFile, Binary,
@@ -683,7 +678,7 @@
   return std::make_unique<llvm::raw_null_ostream>();
 }
 
-std::unique_ptr<raw_pwrite_stream>
+std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
 CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary,
                                    bool RemoveFileOnSignal, StringRef InFile,
                                    StringRef Extension, bool UseTemporary,
@@ -696,7 +691,15 @@
   if (!OS) {
     getDiagnostics().Report(diag::err_fe_unable_to_open_output) << OutputPath
                                                                 << EC.message();
-    return nullptr;
+    return {nullptr, ""};
+  }
+
+  // If '-working-directory' was passed, the output filename should be
+  // relative to that.
+  if (OutputPathName != "-") {
+    SmallString<128> NewOutFile(OutputPathName);
+    FileMgr->makeAbsolutePath(NewOutFile);
+    OutputPathName = NewOutFile.str().str();
   }
 
   // Add the output file -- but don't try to remove "-", since this means we are
@@ -704,7 +707,8 @@
   addOutputFile(
       OutputFile((OutputPathName != "-") ? OutputPathName : "", TempPathName));
 
-  return OS;
+  return std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>(
+      std::move(OS), OutputPathName);
 }
 
 std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile(
Index: clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
===================================================================
--- clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
+++ clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
@@ -297,7 +297,7 @@
           Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, LangOpts,
           Ctx.getTargetInfo().getDataLayout(), M.get(),
           BackendAction::Backend_EmitLL,
-          std::make_unique<llvm::raw_svector_ostream>(Buffer));
+          std::make_unique<llvm::raw_svector_ostream>(Buffer), OutputFileName);
       llvm::dbgs() << Buffer;
     });
 
@@ -305,7 +305,7 @@
     clang::EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
                              LangOpts, Ctx.getTargetInfo().getDataLayout(),
                              M.get(), BackendAction::Backend_EmitObj,
-                             std::move(OS));
+                             std::move(OS), OutputFileName);
 
     // Free the memory for the temporary buffer.
     llvm::SmallVector<char, 0> Empty;
Index: clang/lib/CodeGen/CodeGenAction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenAction.cpp
+++ clang/lib/CodeGen/CodeGenAction.cpp
@@ -111,6 +111,7 @@
     const TargetOptions &TargetOpts;
     const LangOptions &LangOpts;
     std::unique_ptr<raw_pwrite_stream> AsmOutStream;
+    std::string AsmOutputPathName;
     ASTContext *Context;
 
     Timer LLVMIRGeneration;
@@ -138,11 +139,13 @@
                     const LangOptions &LangOpts, bool TimePasses,
                     const std::string &InFile,
                     SmallVector<LinkModule, 4> LinkModules,
-                    std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C,
+                    std::unique_ptr<raw_pwrite_stream> OS,
+                    const std::string &OutputPathName, LLVMContext &C,
                     CoverageSourceInfo *CoverageInfo = nullptr)
         : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts),
           CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
-          AsmOutStream(std::move(OS)), Context(nullptr),
+          AsmOutStream(std::move(OS)), AsmOutputPathName(OutputPathName),
+          Context(nullptr),
           LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
           LLVMIRGenerationRefCount(0),
           Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
@@ -334,7 +337,8 @@
 
       EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
                         LangOpts, C.getTargetInfo().getDataLayout(),
-                        getModule(), Action, std::move(AsmOutStream));
+                        getModule(), Action, std::move(AsmOutStream),
+                        AsmOutputPathName);
 
       Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
 
@@ -932,7 +936,7 @@
   return VMContext;
 }
 
-static std::unique_ptr<raw_pwrite_stream>
+static std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
 GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {
   switch (Action) {
   case Backend_EmitAssembly:
@@ -942,9 +946,9 @@
   case Backend_EmitBC:
     return CI.createDefaultOutputFile(true, InFile, "bc");
   case Backend_EmitNothing:
-    return nullptr;
+    return {nullptr, ""};
   case Backend_EmitMCNull:
-    return CI.createNullOutputFile();
+    return {CI.createNullOutputFile(), ""};
   case Backend_EmitObj:
     return CI.createDefaultOutputFile(true, InFile, "o");
   }
@@ -955,9 +959,10 @@
 std::unique_ptr<ASTConsumer>
 CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   BackendAction BA = static_cast<BackendAction>(Act);
+  std::string OutputPathName;
   std::unique_ptr<raw_pwrite_stream> OS = CI.takeOutputStream();
   if (!OS)
-    OS = GetOutputStream(CI, InFile, BA);
+    std::tie(OS, OutputPathName) = GetOutputStream(CI, InFile, BA);
 
   if (BA != Backend_EmitNothing && !OS)
     return nullptr;
@@ -1000,7 +1005,8 @@
       BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(),
       CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(),
       CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, std::string(InFile),
-      std::move(LinkModules), std::move(OS), *VMContext, CoverageInfo));
+      std::move(LinkModules), std::move(OS), OutputPathName, *VMContext,
+      CoverageInfo));
   BEConsumer = Result.get();
 
   // Enable generating macro debug info only when debug info is not disabled and
@@ -1113,8 +1119,9 @@
     CompilerInstance &CI = getCompilerInstance();
     auto &CodeGenOpts = CI.getCodeGenOpts();
     auto &Diagnostics = CI.getDiagnostics();
-    std::unique_ptr<raw_pwrite_stream> OS =
-        GetOutputStream(CI, getCurrentFile(), BA);
+    std::string OutputPathName;
+    std::unique_ptr<raw_pwrite_stream> OS;
+    std::tie(OS, OutputPathName) = GetOutputStream(CI, getCurrentFile(), BA);
     if (BA != Backend_EmitNothing && !OS)
       return;
 
@@ -1173,7 +1180,7 @@
     EmitBackendOutput(Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts,
                       TargetOpts, CI.getLangOpts(),
                       CI.getTarget().getDataLayout(), TheModule.get(), BA,
-                      std::move(OS));
+                      std::move(OS), OutputPathName);
 
     if (OptRecordFile)
       OptRecordFile->keep();
Index: clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -121,7 +121,7 @@
   /// In this case, we allow this method to fail and not report an error.
   /// When MustCreateTM is used, we print an error if we are unable to load
   /// the requested target.
-  void CreateTargetMachine(bool MustCreateTM);
+  void CreateTargetMachine(bool MustCreateTM, const std::string &OutputFile);
 
   /// Add passes necessary to emit assembly or LLVM IR.
   ///
@@ -157,11 +157,12 @@
 
   std::unique_ptr<TargetMachine> TM;
 
-  void EmitAssembly(BackendAction Action,
-                    std::unique_ptr<raw_pwrite_stream> OS);
+  void EmitAssembly(BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS,
+                    const std::string &OSFile);
 
   void EmitAssemblyWithNewPassManager(BackendAction Action,
-                                      std::unique_ptr<raw_pwrite_stream> OS);
+                                      std::unique_ptr<raw_pwrite_stream> OS,
+                                      const std::string &OutputFile);
 };
 
 // We need this wrapper to access LangOpts and CGOpts from extension functions
@@ -433,7 +434,8 @@
                               const CodeGenOptions &CodeGenOpts,
                               const clang::TargetOptions &TargetOpts,
                               const LangOptions &LangOpts,
-                              const HeaderSearchOptions &HSOpts) {
+                              const HeaderSearchOptions &HSOpts,
+                              const std::string &OutputPathName) {
   Options.ThreadModel =
       llvm::StringSwitch<llvm::ThreadModel::Model>(CodeGenOpts.ThreadModel)
           .Case("posix", llvm::ThreadModel::POSIX)
@@ -499,6 +501,7 @@
   Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection;
   Options.EmitCallSiteInfo = CodeGenOpts.EmitCallSiteInfo;
 
+  Options.MCOptions.OutputPathName = OutputPathName;
   Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
   Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
   Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
@@ -783,7 +786,8 @@
                                     BackendArgs.data());
 }
 
-void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
+void EmitAssemblyHelper::CreateTargetMachine(
+    bool MustCreateTM, const std::string &OutputPathName) {
   // Create the TargetMachine for generating code.
   std::string Error;
   std::string Triple = TheModule->getTargetTriple();
@@ -801,7 +805,8 @@
   CodeGenOpt::Level OptLevel = getCGOptLevel(CodeGenOpts);
 
   llvm::TargetOptions Options;
-  initTargetOptions(Options, CodeGenOpts, TargetOpts, LangOpts, HSOpts);
+  initTargetOptions(Options, CodeGenOpts, TargetOpts, LangOpts, HSOpts,
+                    OutputPathName);
   TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr,
                                           Options, RM, CM, OptLevel));
 }
@@ -836,7 +841,8 @@
 }
 
 void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
-                                      std::unique_ptr<raw_pwrite_stream> OS) {
+                                      std::unique_ptr<raw_pwrite_stream> OS,
+                                      const std::string &OutputFile) {
   TimeRegion Region(FrontendTimesIsEnabled ? &CodeGenerationTime : nullptr);
 
   setCommandLineOpts(CodeGenOpts);
@@ -844,7 +850,7 @@
   bool UsesCodeGen = (Action != Backend_EmitNothing &&
                       Action != Backend_EmitBC &&
                       Action != Backend_EmitLL);
-  CreateTargetMachine(UsesCodeGen);
+  CreateTargetMachine(UsesCodeGen, OutputFile);
 
   if (UsesCodeGen && !TM)
     return;
@@ -1048,14 +1054,15 @@
 /// This API is planned to have its functionality finished and then to replace
 /// `EmitAssembly` at some point in the future when the default switches.
 void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
-    BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) {
+    BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS,
+    const std::string &OutputFile) {
   TimeRegion Region(FrontendTimesIsEnabled ? &CodeGenerationTime : nullptr);
   setCommandLineOpts(CodeGenOpts);
 
   bool RequiresCodeGen = (Action != Backend_EmitNothing &&
                           Action != Backend_EmitBC &&
                           Action != Backend_EmitLL);
-  CreateTargetMachine(RequiresCodeGen);
+  CreateTargetMachine(RequiresCodeGen, OutputFile);
 
   if (RequiresCodeGen && !TM)
     return;
@@ -1462,15 +1469,14 @@
   return nullptr;
 }
 
-static void runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M,
-                              const HeaderSearchOptions &HeaderOpts,
-                              const CodeGenOptions &CGOpts,
-                              const clang::TargetOptions &TOpts,
-                              const LangOptions &LOpts,
-                              std::unique_ptr<raw_pwrite_stream> OS,
-                              std::string SampleProfile,
-                              std::string ProfileRemapping,
-                              BackendAction Action) {
+static void
+runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M,
+                  const HeaderSearchOptions &HeaderOpts,
+                  const CodeGenOptions &CGOpts,
+                  const clang::TargetOptions &TOpts, const LangOptions &LOpts,
+                  std::unique_ptr<raw_pwrite_stream> OS,
+                  const std::string &OutputFile, std::string SampleProfile,
+                  std::string ProfileRemapping, BackendAction Action) {
   StringMap<DenseMap<GlobalValue::GUID, GlobalValueSummary *>>
       ModuleToDefinedGVSummaries;
   CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
@@ -1522,7 +1528,7 @@
     OwnedImports.push_back(std::move(*MBOrErr));
   }
   auto AddStream = [&](size_t Task) {
-    return std::make_unique<lto::NativeObjectStream>(std::move(OS));
+    return std::make_unique<lto::NativeObjectStream>(std::move(OS), OutputFile);
   };
   lto::Config Conf;
   if (CGOpts.SaveTempsFilePrefix != "") {
@@ -1540,7 +1546,7 @@
   Conf.RelocModel = CGOpts.RelocationModel;
   Conf.CGOptLevel = getCGOptLevel(CGOpts);
   Conf.OptLevel = CGOpts.OptimizationLevel;
-  initTargetOptions(Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts);
+  initTargetOptions(Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts, OutputFile);
   Conf.SampleProfile = std::move(SampleProfile);
   Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;
   // For historical reasons, loop interleaving is set to mirror setting for loop
@@ -1599,14 +1605,12 @@
   }
 }
 
-void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
-                              const HeaderSearchOptions &HeaderOpts,
-                              const CodeGenOptions &CGOpts,
-                              const clang::TargetOptions &TOpts,
-                              const LangOptions &LOpts,
-                              const llvm::DataLayout &TDesc, Module *M,
-                              BackendAction Action,
-                              std::unique_ptr<raw_pwrite_stream> OS) {
+void clang::EmitBackendOutput(
+    DiagnosticsEngine &Diags, const HeaderSearchOptions &HeaderOpts,
+    const CodeGenOptions &CGOpts, const clang::TargetOptions &TOpts,
+    const LangOptions &LOpts, const llvm::DataLayout &TDesc, Module *M,
+    BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS,
+    const std::string &OutputFile) {
 
   llvm::TimeTraceScope TimeScope("Backend");
 
@@ -1631,8 +1635,9 @@
     if (CombinedIndex) {
       if (!CombinedIndex->skipModuleByDistributedBackend()) {
         runThinLTOBackend(CombinedIndex.get(), M, HeaderOpts, CGOpts, TOpts,
-                          LOpts, std::move(OS), CGOpts.SampleProfileFile,
-                          CGOpts.ProfileRemappingFile, Action);
+                          LOpts, std::move(OS), OutputFile,
+                          CGOpts.SampleProfileFile, CGOpts.ProfileRemappingFile,
+                          Action);
         return;
       }
       // Distributed indexing detected that nothing from the module is needed
@@ -1650,9 +1655,9 @@
   EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M);
 
   if (CGOpts.ExperimentalNewPassManager)
-    AsmHelper.EmitAssemblyWithNewPassManager(Action, std::move(OS));
+    AsmHelper.EmitAssemblyWithNewPassManager(Action, std::move(OS), OutputFile);
   else
-    AsmHelper.EmitAssembly(Action, std::move(OS));
+    AsmHelper.EmitAssembly(Action, std::move(OS), OutputFile);
 
   // Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's
   // DataLayout.
Index: clang/include/clang/Frontend/FrontendActions.h
===================================================================
--- clang/include/clang/Frontend/FrontendActions.h
+++ clang/include/clang/Frontend/FrontendActions.h
@@ -97,15 +97,14 @@
 
   /// Creates file to write the PCH into and returns a stream to write it
   /// into. On error, returns null.
-  static std::unique_ptr<llvm::raw_pwrite_stream>
-  CreateOutputFile(CompilerInstance &CI, StringRef InFile,
-                   std::string &OutputFile);
+  static std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
+  CreateOutputFile(CompilerInstance &CI, StringRef InFile);
 
   bool BeginSourceFileAction(CompilerInstance &CI) override;
 };
 
 class GenerateModuleAction : public ASTFrontendAction {
-  virtual std::unique_ptr<raw_pwrite_stream>
+  virtual std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
   CreateOutputFile(CompilerInstance &CI, StringRef InFile) = 0;
 
 protected:
@@ -132,7 +131,7 @@
 private:
   bool BeginSourceFileAction(CompilerInstance &CI) override;
 
-  std::unique_ptr<raw_pwrite_stream>
+  std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
   CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
 };
 
@@ -140,7 +139,7 @@
 private:
   bool BeginSourceFileAction(CompilerInstance &CI) override;
 
-  std::unique_ptr<raw_pwrite_stream>
+  std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
   CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
 };
 
@@ -153,7 +152,7 @@
   bool PrepareToExecuteAction(CompilerInstance &CI) override;
   bool BeginSourceFileAction(CompilerInstance &CI) override;
 
-  std::unique_ptr<raw_pwrite_stream>
+  std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
   CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
 };
 
Index: clang/include/clang/Frontend/CompilerInstance.h
===================================================================
--- clang/include/clang/Frontend/CompilerInstance.h
+++ clang/include/clang/Frontend/CompilerInstance.h
@@ -700,7 +700,7 @@
   /// atomically replace the target output on success).
   ///
   /// \return - Null on error.
-  std::unique_ptr<raw_pwrite_stream>
+  std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
   createDefaultOutputFile(bool Binary = true, StringRef BaseInput = "",
                           StringRef Extension = "");
 
@@ -708,7 +708,7 @@
   /// optionally deriving the output path name.
   ///
   /// \return - Null on error.
-  std::unique_ptr<raw_pwrite_stream>
+  std::tuple<std::unique_ptr<raw_pwrite_stream>, std::string>
   createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal,
                    StringRef BaseInput, StringRef Extension, bool UseTemporary,
                    bool CreateMissingDirectories = false);
Index: clang/include/clang/CodeGen/BackendUtil.h
===================================================================
--- clang/include/clang/CodeGen/BackendUtil.h
+++ clang/include/clang/CodeGen/BackendUtil.h
@@ -41,7 +41,8 @@
                          const TargetOptions &TOpts, const LangOptions &LOpts,
                          const llvm::DataLayout &TDesc, llvm::Module *M,
                          BackendAction Action,
-                         std::unique_ptr<raw_pwrite_stream> OS);
+                         std::unique_ptr<raw_pwrite_stream> OS,
+                         const std::string &OutputFile);
 
   void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
                     llvm::MemoryBufferRef Buf);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to