1 //===- DriverUtils.cpp ----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "Driver.h" 10 #include "InputFiles.h" 11 12 #include "lld/Common/ErrorHandler.h" 13 #include "lld/Common/Memory.h" 14 #include "llvm/Option/Arg.h" 15 #include "llvm/Option/ArgList.h" 16 #include "llvm/Option/Option.h" 17 #include "llvm/Support/Path.h" 18 #include "llvm/TextAPI/MachO/TextAPIReader.h" 19 20 using namespace llvm; 21 using namespace llvm::MachO; 22 using namespace llvm::opt; 23 using namespace llvm::sys; 24 using namespace lld; 25 using namespace lld::macho; 26 27 // Create prefix string literals used in Options.td 28 #define PREFIX(NAME, VALUE) const char *NAME[] = VALUE; 29 #include "Options.inc" 30 #undef PREFIX 31 32 // Create table mapping all options defined in Options.td 33 static const opt::OptTable::Info optInfo[] = { 34 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ 35 {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \ 36 X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12}, 37 #include "Options.inc" 38 #undef OPTION 39 }; 40 41 MachOOptTable::MachOOptTable() : OptTable(optInfo) {} 42 43 // Set color diagnostics according to --color-diagnostics={auto,always,never} 44 // or --no-color-diagnostics flags. 45 static void handleColorDiagnostics(opt::InputArgList &args) { 46 auto *arg = args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq, 47 OPT_no_color_diagnostics); 48 if (!arg) 49 return; 50 if (arg->getOption().getID() == OPT_color_diagnostics) { 51 lld::errs().enable_colors(true); 52 } else if (arg->getOption().getID() == OPT_no_color_diagnostics) { 53 lld::errs().enable_colors(false); 54 } else { 55 StringRef s = arg->getValue(); 56 if (s == "always") 57 lld::errs().enable_colors(true); 58 else if (s == "never") 59 lld::errs().enable_colors(false); 60 else if (s != "auto") 61 error("unknown option: --color-diagnostics=" + s); 62 } 63 } 64 65 opt::InputArgList MachOOptTable::parse(ArrayRef<const char *> argv) { 66 // Make InputArgList from string vectors. 67 unsigned missingIndex; 68 unsigned missingCount; 69 SmallVector<const char *, 256> vec(argv.data(), argv.data() + argv.size()); 70 71 opt::InputArgList args = ParseArgs(vec, missingIndex, missingCount); 72 73 if (missingCount) 74 error(Twine(args.getArgString(missingIndex)) + ": missing argument"); 75 76 handleColorDiagnostics(args); 77 78 for (opt::Arg *arg : args.filtered(OPT_UNKNOWN)) 79 error("unknown argument: " + arg->getSpelling()); 80 return args; 81 } 82 83 void MachOOptTable::printHelp(const char *argv0, bool showHidden) const { 84 PrintHelp(lld::outs(), (std::string(argv0) + " [options] file...").c_str(), 85 "LLVM Linker", showHidden); 86 lld::outs() << "\n"; 87 } 88 89 Optional<std::string> macho::resolveDylibPath(StringRef path) { 90 // TODO: if a tbd and dylib are both present, we should check to make sure 91 // they are consistent. 92 if (fs::exists(path)) 93 return std::string(path); 94 95 SmallString<261> location = path; 96 path::replace_extension(location, ".tbd"); 97 if (fs::exists(location)) 98 return std::string(location); 99 100 return {}; 101 } 102 103 Optional<DylibFile *> macho::makeDylibFromTAPI(MemoryBufferRef mbref, 104 DylibFile *umbrella) { 105 Expected<std::unique_ptr<InterfaceFile>> result = TextAPIReader::get(mbref); 106 if (!result) { 107 error("could not load TAPI file at " + mbref.getBufferIdentifier() + ": " + 108 toString(result.takeError())); 109 return {}; 110 } 111 return make<DylibFile>(**result, umbrella); 112 } 113