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 std::string nearest; 80 if (findNearest(arg->getAsString(args), nearest) > 1) 81 error("unknown argument '" + arg->getAsString(args) + "'"); 82 else 83 error("unknown argument '" + arg->getAsString(args) + 84 "', did you mean '" + nearest + "'"); 85 } 86 return args; 87 } 88 89 void MachOOptTable::printHelp(const char *argv0, bool showHidden) const { 90 PrintHelp(lld::outs(), (std::string(argv0) + " [options] file...").c_str(), 91 "LLVM Linker", showHidden); 92 lld::outs() << "\n"; 93 } 94 95 Optional<std::string> macho::resolveDylibPath(StringRef path) { 96 // TODO: if a tbd and dylib are both present, we should check to make sure 97 // they are consistent. 98 if (fs::exists(path)) 99 return std::string(path); 100 101 SmallString<261> location = path; 102 path::replace_extension(location, ".tbd"); 103 if (fs::exists(location)) 104 return std::string(location); 105 106 return {}; 107 } 108 109 Optional<DylibFile *> macho::makeDylibFromTAPI(MemoryBufferRef mbref, 110 DylibFile *umbrella) { 111 Expected<std::unique_ptr<InterfaceFile>> result = TextAPIReader::get(mbref); 112 if (!result) { 113 error("could not load TAPI file at " + mbref.getBufferIdentifier() + ": " + 114 toString(result.takeError())); 115 return {}; 116 } 117 return make<DylibFile>(**result, umbrella); 118 } 119