//===- DriverUtils.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "Driver.h" #include "InputFiles.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Memory.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" #include "llvm/Support/Path.h" #include "llvm/TextAPI/MachO/TextAPIReader.h" using namespace llvm; using namespace llvm::MachO; using namespace llvm::opt; using namespace llvm::sys; using namespace lld; using namespace lld::macho; // Create prefix string literals used in Options.td #define PREFIX(NAME, VALUE) const char *NAME[] = VALUE; #include "Options.inc" #undef PREFIX // Create table mapping all options defined in Options.td static const opt::OptTable::Info optInfo[] = { #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \ X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12}, #include "Options.inc" #undef OPTION }; MachOOptTable::MachOOptTable() : OptTable(optInfo) {} // Set color diagnostics according to --color-diagnostics={auto,always,never} // or --no-color-diagnostics flags. static void handleColorDiagnostics(opt::InputArgList &args) { auto *arg = args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq, OPT_no_color_diagnostics); if (!arg) return; if (arg->getOption().getID() == OPT_color_diagnostics) { lld::errs().enable_colors(true); } else if (arg->getOption().getID() == OPT_no_color_diagnostics) { lld::errs().enable_colors(false); } else { StringRef s = arg->getValue(); if (s == "always") lld::errs().enable_colors(true); else if (s == "never") lld::errs().enable_colors(false); else if (s != "auto") error("unknown option: --color-diagnostics=" + s); } } opt::InputArgList MachOOptTable::parse(ArrayRef argv) { // Make InputArgList from string vectors. unsigned missingIndex; unsigned missingCount; SmallVector vec(argv.data(), argv.data() + argv.size()); opt::InputArgList args = ParseArgs(vec, missingIndex, missingCount); if (missingCount) error(Twine(args.getArgString(missingIndex)) + ": missing argument"); handleColorDiagnostics(args); for (opt::Arg *arg : args.filtered(OPT_UNKNOWN)) error("unknown argument: " + arg->getSpelling()); return args; } void MachOOptTable::printHelp(const char *argv0, bool showHidden) const { PrintHelp(lld::outs(), (std::string(argv0) + " [options] file...").c_str(), "LLVM Linker", showHidden); lld::outs() << "\n"; } Optional macho::resolveDylibPath(StringRef path) { // TODO: if a tbd and dylib are both present, we should check to make sure // they are consistent. if (fs::exists(path)) return std::string(path); SmallString<261> location = path; path::replace_extension(location, ".tbd"); if (fs::exists(location)) return std::string(location); return {}; } Optional macho::makeDylibFromTAPI(MemoryBufferRef mbref, DylibFile *umbrella) { Expected> result = TextAPIReader::get(mbref); if (!result) { error("could not load TAPI file at " + mbref.getBufferIdentifier() + ": " + toString(result.takeError())); return {}; } return make(**result, umbrella); }