summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h13
-rw-r--r--llvm/test/tools/dsymutil/Inputs/swift-interface.ll34
-rw-r--r--llvm/test/tools/dsymutil/X86/swift-interface.test23
-rw-r--r--llvm/tools/dsymutil/CompileUnit.cpp8
-rw-r--r--llvm/tools/dsymutil/CompileUnit.h5
-rw-r--r--llvm/tools/dsymutil/DwarfLinker.cpp143
-rw-r--r--llvm/tools/dsymutil/DwarfLinker.h10
-rw-r--r--llvm/tools/dsymutil/LinkUtils.h3
-rw-r--r--llvm/tools/dsymutil/dsymutil.cpp55
9 files changed, 245 insertions, 49 deletions
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
index 8107624f8a8..279a2e7e352 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
@@ -159,6 +159,19 @@ inline Optional<const char *> toString(const Optional<DWARFFormValue> &V) {
return None;
}
+/// Take an optional DWARFFormValue and try to extract a string value from it.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \returns an optional value that contains a value if the form value
+/// was valid and was a string.
+inline StringRef toStringRef(const Optional<DWARFFormValue> &V,
+ StringRef Default = {}) {
+ if (V)
+ if (auto S = V->getAsCString())
+ return *S;
+ return Default;
+}
+
/// Take an optional DWARFFormValue and extract a string value from it.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
diff --git a/llvm/test/tools/dsymutil/Inputs/swift-interface.ll b/llvm/test/tools/dsymutil/Inputs/swift-interface.ll
new file mode 100644
index 00000000000..715800e6d61
--- /dev/null
+++ b/llvm/test/tools/dsymutil/Inputs/swift-interface.ll
@@ -0,0 +1,34 @@
+; This is a manually stripped empty Swift program with one import.
+source_filename = "/swift-interface.ll"
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.9.0"
+
+@__swift_reflection_version = linkonce_odr hidden constant i16 3
+@llvm.used = appending global [1 x i8*] [i8* bitcast (i16* @__swift_reflection_version to i8*)], section "llvm.metadata", align 8
+
+define i32 @main(i32, i8**) !dbg !29 {
+entry:
+ %2 = bitcast i8** %1 to i8*
+ ret i32 0, !dbg !35
+}
+
+!llvm.dbg.cu = !{!0}
+!swift.module.flags = !{!14}
+!llvm.module.flags = !{!20, !21, !24}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_Swift, file: !1, isOptimized: false, runtimeVersion: 5, emissionKind: FullDebug, enums: !2, imports: !3)
+!1 = !DIFile(filename: "ParseableInterfaceImports.swift", directory: "/")
+!2 = !{}
+!3 = !{!4}
+!4 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !1, entity: !5, file: !1)
+!5 = !DIModule(scope: null, name: "Foo", includePath: "/Foo/x86_64.swiftinterface")
+!14 = !{!"standard-library", i1 false}
+!20 = !{i32 2, !"Dwarf Version", i32 4}
+!21 = !{i32 2, !"Debug Info Version", i32 3}
+!24 = !{i32 1, !"Swift Version", i32 7}
+!29 = distinct !DISubprogram(name: "main", linkageName: "main", scope: !5, file: !1, line: 1, type: !30, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
+!30 = !DISubroutineType(types: !31)
+!31 = !{}
+!35 = !DILocation(line: 0, scope: !36)
+!36 = !DILexicalBlockFile(scope: !29, file: !37, discriminator: 0)
+!37 = !DIFile(filename: "<compiler-generated>", directory: "")
diff --git a/llvm/test/tools/dsymutil/X86/swift-interface.test b/llvm/test/tools/dsymutil/X86/swift-interface.test
new file mode 100644
index 00000000000..4bfd2b89e7c
--- /dev/null
+++ b/llvm/test/tools/dsymutil/X86/swift-interface.test
@@ -0,0 +1,23 @@
+# RUN: rm -rf %t.dir
+# RUN: mkdir -p %t.dir/obj
+# RUN: mkdir -p %t.dir/Foo/x86_64
+# RUN: llc %p/../Inputs/swift-interface.ll -filetype=obj -o %t.dir/obj/1.o
+# RUN: dsymutil -oso-prepend-path %t.dir -y %s \
+# RUN: -o %t.dir/swift-interface.dSYM 2>&1 \
+# RUN: | FileCheck %s --check-prefix=WARNINGS
+# RUN: echo "// module Foo" >%t.dir/Foo/x86_64.swiftinterface
+# RUN: dsymutil -oso-prepend-path %t.dir -y %s \
+# RUN: -o %t.dir/swift-interface.dSYM
+# RUN: cat %t.dir/swift-interface.dSYM/Contents/Resources/Swift/Foo.swiftinterface \
+# RUN: | FileCheck %s --check-prefix=INTERFACE
+
+# WARNINGS: cannot copy parseable Swift interface
+# INTERFACE: module Foo
+
+---
+triple: 'x86_64-apple-darwin'
+objects:
+ - filename: obj/1.o
+ symbols:
+ - { sym: _main, objAddr: 0x0, binAddr: 0x10000, size: 0x10 }
+...
diff --git a/llvm/tools/dsymutil/CompileUnit.cpp b/llvm/tools/dsymutil/CompileUnit.cpp
index 670591a9436..036c61a6b92 100644
--- a/llvm/tools/dsymutil/CompileUnit.cpp
+++ b/llvm/tools/dsymutil/CompileUnit.cpp
@@ -22,6 +22,14 @@ static bool inFunctionScope(CompileUnit &U, unsigned Idx) {
return false;
}
+uint16_t CompileUnit::getLanguage() {
+ if (!Language) {
+ DWARFDie CU = getOrigUnit().getUnitDIE();
+ Language = dwarf::toUnsigned(CU.find(dwarf::DW_AT_language), 0);
+ }
+ return Language;
+}
+
void CompileUnit::markEverythingAsKept() {
unsigned Idx = 0;
diff --git a/llvm/tools/dsymutil/CompileUnit.h b/llvm/tools/dsymutil/CompileUnit.h
index 6e3c2c669e0..e0f5d3bc65b 100644
--- a/llvm/tools/dsymutil/CompileUnit.h
+++ b/llvm/tools/dsymutil/CompileUnit.h
@@ -114,6 +114,8 @@ public:
bool hasODR() const { return HasODR; }
bool isClangModule() const { return !ClangModuleName.empty(); }
+ uint16_t getLanguage();
+
const std::string &getClangModuleName() const { return ClangModuleName; }
DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; }
@@ -316,6 +318,9 @@ private:
/// Did a DIE actually contain a valid reloc?
bool HasInterestingContent;
+ /// The DW_AT_language of this unit.
+ uint16_t Language = 0;
+
/// If this is a Clang module, this holds the module's name.
std::string ClangModuleName;
};
diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp
index fa408d7cfe7..e97d5026174 100644
--- a/llvm/tools/dsymutil/DwarfLinker.cpp
+++ b/llvm/tools/dsymutil/DwarfLinker.cpp
@@ -243,18 +243,55 @@ bool DwarfLinker::createStreamer(const Triple &TheTriple,
return Streamer->init(TheTriple);
}
+/// Resolve the relative path to a build artifact referenced by DWARF by
+/// applying DW_AT_comp_dir.
+static void resolveRelativeObjectPath(SmallVectorImpl<char> &Buf, DWARFDie CU) {
+ sys::path::append(Buf, dwarf::toString(CU.find(dwarf::DW_AT_comp_dir), ""));
+}
+
+/// Collect references to parseable Swift interfaces in imported
+/// DW_TAG_module blocks.
+static void analyzeImportedModule(
+ const DWARFDie &DIE, CompileUnit &CU,
+ std::map<std::string, std::string> &ParseableSwiftInterfaces,
+ std::function<void(const Twine &, const DWARFDie &)> ReportWarning) {
+ if (CU.getLanguage() != dwarf::DW_LANG_Swift)
+ return;
+
+ StringRef Path = dwarf::toStringRef(DIE.find(dwarf::DW_AT_LLVM_include_path));
+ if (!Path.endswith(".swiftinterface"))
+ return;
+ if (Optional<DWARFFormValue> Val = DIE.find(dwarf::DW_AT_name))
+ if (Optional<const char *> Name = Val->getAsCString()) {
+ auto &Entry = ParseableSwiftInterfaces[*Name];
+ // The prepend path is applied later when copying.
+ DWARFDie CUDie = CU.getOrigUnit().getUnitDIE();
+ SmallString<128> ResolvedPath;
+ if (sys::path::is_relative(Path))
+ resolveRelativeObjectPath(ResolvedPath, CUDie);
+ sys::path::append(ResolvedPath, Path);
+ if (!Entry.empty() && Entry != ResolvedPath)
+ ReportWarning(
+ Twine("Conflicting parseable interfaces for Swift Module ") +
+ *Name + ": " + Entry + " and " + Path,
+ DIE);
+ Entry = ResolvedPath.str();
+ }
+}
+
/// Recursive helper to build the global DeclContext information and
/// gather the child->parent relationships in the original compile unit.
///
/// \return true when this DIE and all of its children are only
/// forward declarations to types defined in external clang modules
/// (i.e., forward declarations that are children of a DW_TAG_module).
-static bool analyzeContextInfo(const DWARFDie &DIE, unsigned ParentIdx,
- CompileUnit &CU, DeclContext *CurrentDeclContext,
- UniquingStringPool &StringPool,
- DeclContextTree &Contexts,
- uint64_t ModulesEndOffset,
- bool InImportedModule = false) {
+static bool analyzeContextInfo(
+ const DWARFDie &DIE, unsigned ParentIdx, CompileUnit &CU,
+ DeclContext *CurrentDeclContext, UniquingStringPool &StringPool,
+ DeclContextTree &Contexts, uint64_t ModulesEndOffset,
+ std::map<std::string, std::string> &ParseableSwiftInterfaces,
+ std::function<void(const Twine &, const DWARFDie &)> ReportWarning,
+ bool InImportedModule = false) {
unsigned MyIdx = CU.getOrigUnit().getDIEIndex(DIE);
CompileUnit::DIEInfo &Info = CU.getInfo(MyIdx);
@@ -274,6 +311,7 @@ static bool analyzeContextInfo(const DWARFDie &DIE, unsigned ParentIdx,
dwarf::toString(DIE.find(dwarf::DW_AT_name), "") !=
CU.getClangModuleName()) {
InImportedModule = true;
+ analyzeImportedModule(DIE, CU, ParseableSwiftInterfaces, ReportWarning);
}
Info.ParentIdx = ParentIdx;
@@ -294,9 +332,10 @@ static bool analyzeContextInfo(const DWARFDie &DIE, unsigned ParentIdx,
Info.Prune = InImportedModule;
if (DIE.hasChildren())
for (auto Child : DIE.children())
- Info.Prune &=
- analyzeContextInfo(Child, MyIdx, CU, CurrentDeclContext, StringPool,
- Contexts, ModulesEndOffset, InImportedModule);
+ Info.Prune &= analyzeContextInfo(Child, MyIdx, CU, CurrentDeclContext,
+ StringPool, Contexts, ModulesEndOffset,
+ ParseableSwiftInterfaces, ReportWarning,
+ InImportedModule);
// Prune this DIE if it is either a forward declaration inside a
// DW_TAG_module or a DW_TAG_module that contains nothing but
@@ -2106,7 +2145,7 @@ static uint64_t getDwoId(const DWARFDie &CUDie, const DWARFUnit &Unit) {
}
bool DwarfLinker::registerModuleReference(
- const DWARFDie &CUDie, const DWARFUnit &Unit, DebugMap &ModuleMap,
+ DWARFDie CUDie, const DWARFUnit &Unit, DebugMap &ModuleMap,
const DebugMapObject &DMO, RangesTy &Ranges, OffsetsStringPool &StringPool,
UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts,
uint64_t ModulesEndOffset, unsigned &UnitID, bool IsLittleEndian,
@@ -2117,7 +2156,6 @@ bool DwarfLinker::registerModuleReference(
return false;
// Clang module DWARF skeleton CUs abuse this for the path to the module.
- std::string PCMpath = dwarf::toString(CUDie.find(dwarf::DW_AT_comp_dir), "");
uint64_t DwoId = getDwoId(CUDie, Unit);
std::string Name = dwarf::toString(CUDie.find(dwarf::DW_AT_name), "");
@@ -2152,7 +2190,8 @@ bool DwarfLinker::registerModuleReference(
// Cyclic dependencies are disallowed by Clang, but we still
// shouldn't run into an infinite loop, so mark it as processed now.
ClangModules.insert({PCMfile, DwoId});
- if (Error E = loadClangModule(PCMfile, PCMpath, Name, DwoId, ModuleMap, DMO,
+
+ if (Error E = loadClangModule(CUDie, PCMfile, Name, DwoId, ModuleMap, DMO,
Ranges, StringPool, UniquingStringPool,
ODRContexts, ModulesEndOffset, UnitID,
IsLittleEndian, Indent + 2, Quiet)) {
@@ -2185,17 +2224,16 @@ DwarfLinker::loadObject(const DebugMapObject &Obj, const DebugMap &Map) {
}
Error DwarfLinker::loadClangModule(
- StringRef Filename, StringRef ModulePath, StringRef ModuleName,
- uint64_t DwoId, DebugMap &ModuleMap, const DebugMapObject &DMO,
- RangesTy &Ranges, OffsetsStringPool &StringPool,
- UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts,
- uint64_t ModulesEndOffset, unsigned &UnitID, bool IsLittleEndian,
- unsigned Indent, bool Quiet) {
- SmallString<80> Path(Options.PrependPath);
+ DWARFDie CUDie, StringRef Filename, StringRef ModuleName, uint64_t DwoId,
+ DebugMap &ModuleMap, const DebugMapObject &DMO, RangesTy &Ranges,
+ OffsetsStringPool &StringPool, UniquingStringPool &UniquingStringPool,
+ DeclContextTree &ODRContexts, uint64_t ModulesEndOffset, unsigned &UnitID,
+ bool IsLittleEndian, unsigned Indent, bool Quiet) {
+ /// Using a SmallString<0> because loadClangModule() is recursive.
+ SmallString<0> Path(Options.PrependPath);
if (sys::path::is_relative(Filename))
- sys::path::append(Path, ModulePath, Filename);
- else
- sys::path::append(Path, Filename);
+ resolveRelativeObjectPath(Path, CUDie);
+ sys::path::append(Path, Filename);
// Don't use the cached binary holder because we have no thread-safety
// guarantee and the lifetime is limited.
auto &Obj = ModuleMap.addDebugMapObject(
@@ -2282,7 +2320,11 @@ Error DwarfLinker::loadClangModule(
ModuleName);
Unit->setHasInterestingContent();
analyzeContextInfo(CUDie, 0, *Unit, &ODRContexts.getRoot(),
- UniquingStringPool, ODRContexts, ModulesEndOffset);
+ UniquingStringPool, ODRContexts, ModulesEndOffset,
+ ParseableSwiftInterfaces,
+ [&](const Twine &Warning, const DWARFDie &DIE) {
+ reportWarning(Warning, DMO, &DIE);
+ });
// Keep everything.
Unit->markEverythingAsKept();
}
@@ -2449,6 +2491,43 @@ bool DwarfLinker::emitPaperTrailWarnings(const DebugMapObject &DMO,
return true;
}
+static Error copySwiftInterfaces(
+ const std::map<std::string, std::string> &ParseableSwiftInterfaces,
+ StringRef Architecture, const LinkOptions &Options) {
+ std::error_code EC;
+ SmallString<128> InputPath;
+ SmallString<128> Path;
+ sys::path::append(Path, *Options.ResourceDir, "Swift");
+ if ((EC = sys::fs::create_directories(Path.str(), true,
+ sys::fs::perms::all_all)))
+ return make_error<StringError>(
+ "cannot create directory: " + toString(errorCodeToError(EC)), EC);
+ unsigned BaseLength = Path.size();
+
+ for (auto &I : ParseableSwiftInterfaces) {
+ StringRef ModuleName = I.first;
+ StringRef InterfaceFile = I.second;
+ if (!Options.PrependPath.empty()) {
+ InputPath.clear();
+ sys::path::append(InputPath, Options.PrependPath, InterfaceFile);
+ InterfaceFile = InputPath;
+ }
+ sys::path::append(Path, ModuleName);
+ Path.append(".swiftinterface");
+ if (Options.Verbose)
+ outs() << "copy parseable Swift interface " << InterfaceFile << " -> "
+ << Path.str() << '\n';
+
+ // copy_file attempts an APFS clone first, so this should be cheap.
+ if ((EC = sys::fs::copy_file(InterfaceFile, Path.str())))
+ warn(Twine("cannot copy parseable Swift interface ") +
+ InterfaceFile + ": " +
+ toString(errorCodeToError(EC)));
+ Path.resize(BaseLength);
+ }
+ return Error::success();
+}
+
bool DwarfLinker::link(const DebugMap &Map) {
if (!createStreamer(Map.getTriple(), OutFile))
return false;
@@ -2636,7 +2715,11 @@ bool DwarfLinker::link(const DebugMap &Map) {
continue;
analyzeContextInfo(CurrentUnit->getOrigUnit().getUnitDIE(), 0,
*CurrentUnit, &ODRContexts.getRoot(),
- UniquingStringPool, ODRContexts, ModulesEndOffset);
+ UniquingStringPool, ODRContexts, ModulesEndOffset,
+ ParseableSwiftInterfaces,
+ [&](const Twine &Warning, const DWARFDie &DIE) {
+ reportWarning(Warning, LinkContext.DMO, &DIE);
+ });
}
};
@@ -2749,7 +2832,17 @@ bool DwarfLinker::link(const DebugMap &Map) {
pool.wait();
}
- return Options.NoOutput ? true : Streamer->finish(Map, Options.Translator);
+ if (Options.NoOutput)
+ return true;
+
+ if (Options.ResourceDir && !ParseableSwiftInterfaces.empty()) {
+ StringRef ArchName = Triple::getArchTypeName(Map.getTriple().getArch());
+ if (auto E =
+ copySwiftInterfaces(ParseableSwiftInterfaces, ArchName, Options))
+ return error(toString(std::move(E)));
+ }
+
+ return Streamer->finish(Map, Options.Translator);
} // namespace dsymutil
bool linkDwarf(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
diff --git a/llvm/tools/dsymutil/DwarfLinker.h b/llvm/tools/dsymutil/DwarfLinker.h
index fdc86cf442a..482c607d22c 100644
--- a/llvm/tools/dsymutil/DwarfLinker.h
+++ b/llvm/tools/dsymutil/DwarfLinker.h
@@ -193,7 +193,7 @@ private:
/// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
/// pointing to the module, and a DW_AT_gnu_dwo_id with the module
/// hash.
- bool registerModuleReference(const DWARFDie &CUDie, const DWARFUnit &Unit,
+ bool registerModuleReference(DWARFDie CUDie, const DWARFUnit &Unit,
DebugMap &ModuleMap, const DebugMapObject &DMO,
RangesTy &Ranges,
OffsetsStringPool &OffsetsStringPool,
@@ -206,7 +206,7 @@ private:
/// Recursively add the debug info in this clang module .pcm
/// file (and all the modules imported by it in a bottom-up fashion)
/// to Units.
- Error loadClangModule(StringRef Filename, StringRef ModulePath,
+ Error loadClangModule(DWARFDie CUDie, StringRef FilePath,
StringRef ModuleName, uint64_t DwoId,
DebugMap &ModuleMap, const DebugMapObject &DMO,
RangesTy &Ranges, OffsetsStringPool &OffsetsStringPool,
@@ -494,6 +494,12 @@ private:
/// Mapping the PCM filename to the DwoId.
StringMap<uint64_t> ClangModules;
+ /// A list of all .swiftinterface files referenced by the debug
+ /// info, mapping Module name to path on disk. The entries need to
+ /// be uniqued and sorted and there are only few entries expected
+ /// per compile unit, which is why this is a std::map.
+ std::map<std::string, std::string> ParseableSwiftInterfaces;
+
bool ModuleCacheHintDisplayed = false;
bool ArchiveHintDisplayed = false;
};
diff --git a/llvm/tools/dsymutil/LinkUtils.h b/llvm/tools/dsymutil/LinkUtils.h
index 2b3ccb29088..0cd5600b65d 100644
--- a/llvm/tools/dsymutil/LinkUtils.h
+++ b/llvm/tools/dsymutil/LinkUtils.h
@@ -62,6 +62,9 @@ struct LinkOptions {
/// -oso-prepend-path
std::string PrependPath;
+ /// The Resources directory in the .dSYM bundle.
+ Optional<std::string> ResourceDir;
+
/// Symbol map translator.
SymbolMapTranslator Translator;
diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp
index 14f9a0e5137..1651fa86f79 100644
--- a/llvm/tools/dsymutil/dsymutil.cpp
+++ b/llvm/tools/dsymutil/dsymutil.cpp
@@ -278,23 +278,30 @@ static bool verify(llvm::StringRef OutputFile, llvm::StringRef Arch) {
return false;
}
-static Expected<std::string> getOutputFileName(llvm::StringRef InputFile) {
+namespace {
+struct OutputLocation {
+ std::string DWARFFile;
+ Optional<std::string> ResourceDir;
+};
+}
+
+static Expected<OutputLocation> getOutputFileName(llvm::StringRef InputFile) {
if (OutputFileOpt == "-")
- return OutputFileOpt;
+ return OutputLocation{OutputFileOpt, {}};
// When updating, do in place replacement.
if (OutputFileOpt.empty() && (Update || !SymbolMap.empty()))
- return InputFile;
+ return OutputLocation{InputFile, {}};
// If a flat dSYM has been requested, things are pretty simple.
if (FlatOut) {
if (OutputFileOpt.empty()) {
if (InputFile == "-")
- return "a.out.dwarf";
- return (InputFile + ".dwarf").str();
+ return OutputLocation{"a.out.dwarf", {}};
+ return OutputLocation{(InputFile + ".dwarf").str(), {}};
}
- return OutputFileOpt;
+ return OutputLocation{OutputFileOpt, {}};
}
// We need to create/update a dSYM bundle.
@@ -307,17 +314,18 @@ static Expected<std::string> getOutputFileName(llvm::StringRef InputFile) {
// <DWARF file(s)>
std::string DwarfFile =
InputFile == "-" ? llvm::StringRef("a.out") : InputFile;
- llvm::SmallString<128> BundleDir(OutputFileOpt);
- if (BundleDir.empty())
- BundleDir = DwarfFile + ".dSYM";
- if (auto E = createBundleDir(BundleDir))
+ llvm::SmallString<128> Path(OutputFileOpt);
+ if (Path.empty())
+ Path = DwarfFile + ".dSYM";
+ if (auto E = createBundleDir(Path))
return std::move(E);
- if (auto E = createPlistFile(DwarfFile, BundleDir))
+ if (auto E = createPlistFile(DwarfFile, Path))
return std::move(E);
- llvm::sys::path::append(BundleDir, "Contents", "Resources", "DWARF",
- llvm::sys::path::filename(DwarfFile));
- return BundleDir.str();
+ llvm::sys::path::append(Path, "Contents", "Resources");
+ StringRef ResourceDir = Path;
+ llvm::sys::path::append(Path, "DWARF", llvm::sys::path::filename(DwarfFile));
+ return OutputLocation{Path.str(), ResourceDir.str()};
}
/// Parses the command line options into the LinkOptions struct and performs
@@ -544,13 +552,15 @@ int main(int argc, char **argv) {
// types don't work with std::bind in the ThreadPool implementation.
std::shared_ptr<raw_fd_ostream> OS;
- Expected<std::string> OutputFileOrErr = getOutputFileName(InputFile);
- if (!OutputFileOrErr) {
- WithColor::error() << toString(OutputFileOrErr.takeError());
+ Expected<OutputLocation> OutputLocationOrErr =
+ getOutputFileName(InputFile);
+ if (!OutputLocationOrErr) {
+ WithColor::error() << toString(OutputLocationOrErr.takeError());
return 1;
}
+ OptionsOrErr->ResourceDir = OutputLocationOrErr->ResourceDir;
- std::string OutputFile = *OutputFileOrErr;
+ std::string OutputFile = OutputLocationOrErr->DWARFFile;
if (NeedsTempFiles) {
TempFiles.emplace_back(Map->getTriple().getArchName().str());
@@ -597,12 +607,13 @@ int main(int argc, char **argv) {
return 1;
if (NeedsTempFiles) {
- Expected<std::string> OutputFileOrErr = getOutputFileName(InputFile);
- if (!OutputFileOrErr) {
- WithColor::error() << toString(OutputFileOrErr.takeError());
+ Expected<OutputLocation> OutputLocationOrErr = getOutputFileName(InputFile);
+ if (!OutputLocationOrErr) {
+ WithColor::error() << toString(OutputLocationOrErr.takeError());
return 1;
}
- if (!MachOUtils::generateUniversalBinary(TempFiles, *OutputFileOrErr,
+ if (!MachOUtils::generateUniversalBinary(TempFiles,
+ OutputLocationOrErr->DWARFFile,
*OptionsOrErr, SDKPath))
return 1;
}
OpenPOWER on IntegriCloud