diff options
Diffstat (limited to 'Common')
-rw-r--r-- | Common/Args.cpp | 87 | ||||
-rw-r--r-- | Common/CMakeLists.txt | 27 | ||||
-rw-r--r-- | Common/ErrorHandler.cpp | 160 | ||||
-rw-r--r-- | Common/Filesystem.cpp | 99 | ||||
-rw-r--r-- | Common/Memory.cpp | 19 | ||||
-rw-r--r-- | Common/Reproduce.cpp | 67 | ||||
-rw-r--r-- | Common/Strings.cpp | 99 | ||||
-rw-r--r-- | Common/TargetOptionsCommandFlags.cpp | 18 | ||||
-rw-r--r-- | Common/Threads.cpp | 9 | ||||
-rw-r--r-- | Common/Timer.cpp | 61 | ||||
-rw-r--r-- | Common/Version.cpp | 42 |
11 files changed, 416 insertions, 272 deletions
diff --git a/Common/Args.cpp b/Common/Args.cpp index 3f0671d72a666..4ea3a435c7ae0 100644 --- a/Common/Args.cpp +++ b/Common/Args.cpp @@ -1,9 +1,8 @@ //===- Args.cpp -----------------------------------------------------------===// // -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -18,56 +17,66 @@ using namespace llvm; using namespace lld; -int lld::args::getInteger(opt::InputArgList &Args, unsigned Key, int Default) { - auto *A = Args.getLastArg(Key); - if (!A) +// TODO(sbc): Remove this once CGOptLevel can be set completely based on bitcode +// function metadata. +CodeGenOpt::Level lld::args::getCGOptLevel(int optLevelLTO) { + if (optLevelLTO == 3) + return CodeGenOpt::Aggressive; + assert(optLevelLTO < 3); + return CodeGenOpt::Default; +} + +int64_t lld::args::getInteger(opt::InputArgList &args, unsigned key, + int64_t Default) { + auto *a = args.getLastArg(key); + if (!a) return Default; - int V; - if (to_integer(A->getValue(), V, 10)) - return V; + int64_t v; + if (to_integer(a->getValue(), v, 10)) + return v; - StringRef Spelling = Args.getArgString(A->getIndex()); - error(Spelling + ": number expected, but got '" + A->getValue() + "'"); + StringRef spelling = args.getArgString(a->getIndex()); + error(spelling + ": number expected, but got '" + a->getValue() + "'"); return 0; } -std::vector<StringRef> lld::args::getStrings(opt::InputArgList &Args, int Id) { - std::vector<StringRef> V; - for (auto *Arg : Args.filtered(Id)) - V.push_back(Arg->getValue()); - return V; +std::vector<StringRef> lld::args::getStrings(opt::InputArgList &args, int id) { + std::vector<StringRef> v; + for (auto *arg : args.filtered(id)) + v.push_back(arg->getValue()); + return v; } -uint64_t lld::args::getZOptionValue(opt::InputArgList &Args, int Id, - StringRef Key, uint64_t Default) { - for (auto *Arg : Args.filtered_reverse(Id)) { - std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('='); - if (KV.first == Key) { - uint64_t Result = Default; - if (!to_integer(KV.second, Result)) - error("invalid " + Key + ": " + KV.second); - return Result; +uint64_t lld::args::getZOptionValue(opt::InputArgList &args, int id, + StringRef key, uint64_t Default) { + for (auto *arg : args.filtered_reverse(id)) { + std::pair<StringRef, StringRef> kv = StringRef(arg->getValue()).split('='); + if (kv.first == key) { + uint64_t result = Default; + if (!to_integer(kv.second, result)) + error("invalid " + key + ": " + kv.second); + return result; } } return Default; } -std::vector<StringRef> lld::args::getLines(MemoryBufferRef MB) { - SmallVector<StringRef, 0> Arr; - MB.getBuffer().split(Arr, '\n'); +std::vector<StringRef> lld::args::getLines(MemoryBufferRef mb) { + SmallVector<StringRef, 0> arr; + mb.getBuffer().split(arr, '\n'); - std::vector<StringRef> Ret; - for (StringRef S : Arr) { - S = S.trim(); - if (!S.empty() && S[0] != '#') - Ret.push_back(S); + std::vector<StringRef> ret; + for (StringRef s : arr) { + s = s.trim(); + if (!s.empty() && s[0] != '#') + ret.push_back(s); } - return Ret; + return ret; } -StringRef lld::args::getFilenameWithoutExe(StringRef Path) { - if (Path.endswith_lower(".exe")) - return sys::path::stem(Path); - return sys::path::filename(Path); +StringRef lld::args::getFilenameWithoutExe(StringRef path) { + if (path.endswith_lower(".exe")) + return sys::path::stem(path); + return sys::path::filename(path); } diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt index a45fe209f06f3..70849cc7b94b2 100644 --- a/Common/CMakeLists.txt +++ b/Common/CMakeLists.txt @@ -2,15 +2,42 @@ if(NOT LLD_BUILT_STANDALONE) set(tablegen_deps intrinsics_gen) endif() +find_first_existing_vc_file("${LLVM_MAIN_SRC_DIR}" llvm_vc) +find_first_existing_vc_file("${LLD_SOURCE_DIR}" lld_vc) + +set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/VCSVersion.inc") +set(generate_vcs_version_script "${LLVM_CMAKE_PATH}/GenerateVersionFromVCS.cmake") + +if(lld_vc) + set(lld_source_dir ${LLD_SOURCE_DIR}) +endif() + +add_custom_command(OUTPUT "${version_inc}" + DEPENDS "${lld_vc}" "${generate_vcs_version_script}" + COMMAND ${CMAKE_COMMAND} "-DNAMES=LLD" + "-DLLD_SOURCE_DIR=${LLD_SOURCE_DIR}" + "-DHEADER_FILE=${version_inc}" + -P "${generate_vcs_version_script}") + +# Mark the generated header as being generated. +set_source_files_properties("${version_inc}" + PROPERTIES GENERATED TRUE + HEADER_FILE_ONLY TRUE) + +set_property(SOURCE Version.cpp APPEND PROPERTY + COMPILE_DEFINITIONS "HAVE_VCS_VERSION_INC") + add_lld_library(lldCommon Args.cpp ErrorHandler.cpp + Filesystem.cpp Memory.cpp Reproduce.cpp Strings.cpp TargetOptionsCommandFlags.cpp Threads.cpp Timer.cpp + VCSVersion.inc Version.cpp ADDITIONAL_HEADER_DIRS diff --git a/Common/ErrorHandler.cpp b/Common/ErrorHandler.cpp index c059516daf94d..c87c0609b2601 100644 --- a/Common/ErrorHandler.cpp +++ b/Common/ErrorHandler.cpp @@ -1,9 +1,8 @@ //===- ErrorHandler.cpp ---------------------------------------------------===// // -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -17,6 +16,7 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" #include <mutex> +#include <regex> #if !defined(_MSC_VER) && !defined(__MINGW32__) #include <unistd.h> @@ -27,29 +27,29 @@ using namespace lld; // The functions defined in this file can be called from multiple threads, // but outs() or errs() are not thread-safe. We protect them using a mutex. -static std::mutex Mu; +static std::mutex mu; // Prints "\n" or does nothing, depending on Msg contents of // the previous call of this function. -static void newline(raw_ostream *ErrorOS, const Twine &Msg) { +static void newline(raw_ostream *errorOS, const Twine &msg) { // True if the previous error message contained "\n". // We want to separate multi-line error messages with a newline. - static bool Flag; + static bool flag; - if (Flag) - *ErrorOS << "\n"; - Flag = StringRef(Msg.str()).contains('\n'); + if (flag) + *errorOS << "\n"; + flag = StringRef(msg.str()).contains('\n'); } ErrorHandler &lld::errorHandler() { - static ErrorHandler Handler; - return Handler; + static ErrorHandler handler; + return handler; } -void lld::exitLld(int Val) { +void lld::exitLld(int val) { // Delete any temporary file, while keeping the memory mapping open. - if (errorHandler().OutputBuffer) - errorHandler().OutputBuffer->discard(); + if (errorHandler().outputBuffer) + errorHandler().outputBuffer->discard(); // Dealloc/destroy ManagedStatic variables before calling // _exit(). In a non-LTO build, this is a nop. In an LTO @@ -58,87 +58,121 @@ void lld::exitLld(int Val) { outs().flush(); errs().flush(); - _exit(Val); + _exit(val); } -void lld::diagnosticHandler(const DiagnosticInfo &DI) { - SmallString<128> S; - raw_svector_ostream OS(S); - DiagnosticPrinterRawOStream DP(OS); - DI.print(DP); - switch (DI.getSeverity()) { +void lld::diagnosticHandler(const DiagnosticInfo &di) { + SmallString<128> s; + raw_svector_ostream os(s); + DiagnosticPrinterRawOStream dp(os); + di.print(dp); + switch (di.getSeverity()) { case DS_Error: - error(S); + error(s); break; case DS_Warning: - warn(S); + warn(s); break; case DS_Remark: case DS_Note: - message(S); + message(s); break; } } -void lld::checkError(Error E) { - handleAllErrors(std::move(E), - [&](ErrorInfoBase &EIB) { error(EIB.message()); }); +void lld::checkError(Error e) { + handleAllErrors(std::move(e), + [&](ErrorInfoBase &eib) { error(eib.message()); }); +} + +static std::string getLocation(std::string msg, std::string defaultMsg) { + static std::vector<std::regex> Regexes{ + std::regex(R"(^undefined symbol:.*\n>>> referenced by (\S+):(\d+)\n.*)"), + std::regex(R"(^undefined symbol:.*\n>>> referenced by (.*):)"), + std::regex( + R"(^duplicate symbol: .*\n>>> defined in (\S+)\n>>> defined in.*)"), + std::regex( + R"(^duplicate symbol: .*\n>>> defined at (\S+):(\d+).*)"), + std::regex( + R"(.*\n>>> defined in .*\n>>> referenced by (\S+):(\d+))"), + std::regex( + R"(^undefined (internal|hidden|protected) symbol: .*\n>>> referenced by (\S+):(\d+)\n.*)"), + std::regex(R"((\S+):(\d+): unclosed quote)"), + }; + + std::smatch Match; + for (std::regex &Re : Regexes) { + if (std::regex_search(msg, Match, Re)) { + return Match.size() > 2 ? Match.str(1) + "(" + Match.str(2) + ")" + : Match.str(1); + } + } + return defaultMsg; } -void ErrorHandler::print(StringRef S, raw_ostream::Colors C) { - *ErrorOS << LogName << ": "; - if (ColorDiagnostics) { - ErrorOS->changeColor(C, true); - *ErrorOS << S; - ErrorOS->resetColor(); +void ErrorHandler::printHeader(StringRef s, raw_ostream::Colors c, + const Twine &msg) { + + if (vsDiagnostics) { + // A Visual Studio-style error message starts with an error location. + // If a location cannot be extracted then we default to LogName. + *errorOS << getLocation(msg.str(), logName) << ": "; + } else { + *errorOS << logName << ": "; + } + + if (colorDiagnostics) { + errorOS->changeColor(c, true); + *errorOS << s; + errorOS->resetColor(); } else { - *ErrorOS << S; + *errorOS << s; } } -void ErrorHandler::log(const Twine &Msg) { - if (Verbose) { - std::lock_guard<std::mutex> Lock(Mu); - *ErrorOS << LogName << ": " << Msg << "\n"; +void ErrorHandler::log(const Twine &msg) { + if (verbose) { + std::lock_guard<std::mutex> lock(mu); + *errorOS << logName << ": " << msg << "\n"; } } -void ErrorHandler::message(const Twine &Msg) { - std::lock_guard<std::mutex> Lock(Mu); - outs() << Msg << "\n"; +void ErrorHandler::message(const Twine &msg) { + std::lock_guard<std::mutex> lock(mu); + outs() << msg << "\n"; outs().flush(); } -void ErrorHandler::warn(const Twine &Msg) { - if (FatalWarnings) { - error(Msg); +void ErrorHandler::warn(const Twine &msg) { + if (fatalWarnings) { + error(msg); return; } - std::lock_guard<std::mutex> Lock(Mu); - newline(ErrorOS, Msg); - print("warning: ", raw_ostream::MAGENTA); - *ErrorOS << Msg << "\n"; + std::lock_guard<std::mutex> lock(mu); + newline(errorOS, msg); + printHeader("warning: ", raw_ostream::MAGENTA, msg); + *errorOS << msg << "\n"; } -void ErrorHandler::error(const Twine &Msg) { - std::lock_guard<std::mutex> Lock(Mu); - newline(ErrorOS, Msg); - - if (ErrorLimit == 0 || ErrorCount < ErrorLimit) { - print("error: ", raw_ostream::RED); - *ErrorOS << Msg << "\n"; - } else if (ErrorCount == ErrorLimit) { - print("error: ", raw_ostream::RED); - *ErrorOS << ErrorLimitExceededMsg << "\n"; - if (ExitEarly) +void ErrorHandler::error(const Twine &msg) { + std::lock_guard<std::mutex> lock(mu); + newline(errorOS, msg); + + if (errorLimit == 0 || errorCount < errorLimit) { + printHeader("error: ", raw_ostream::RED, msg); + *errorOS << msg << "\n"; + } else if (errorCount == errorLimit) { + printHeader("error: ", raw_ostream::RED, msg); + *errorOS << errorLimitExceededMsg << "\n"; + if (exitEarly) exitLld(1); } - ++ErrorCount; + ++errorCount; } -void ErrorHandler::fatal(const Twine &Msg) { - error(Msg); +void ErrorHandler::fatal(const Twine &msg) { + error(msg); exitLld(1); } diff --git a/Common/Filesystem.cpp b/Common/Filesystem.cpp new file mode 100644 index 0000000000000..c3d3f998f03b7 --- /dev/null +++ b/Common/Filesystem.cpp @@ -0,0 +1,99 @@ +//===- Filesystem.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 +// +//===----------------------------------------------------------------------===// +// +// This file contains a few utility functions to handle files. +// +//===----------------------------------------------------------------------===// + +#include "lld/Common/Filesystem.h" +#include "lld/Common/Threads.h" +#include "llvm/Config/llvm-config.h" +#include "llvm/Support/FileOutputBuffer.h" +#include "llvm/Support/FileSystem.h" +#if LLVM_ON_UNIX +#include <unistd.h> +#endif +#include <thread> + +using namespace llvm; +using namespace lld; + +// Removes a given file asynchronously. This is a performance hack, +// so remove this when operating systems are improved. +// +// On Linux (and probably on other Unix-like systems), unlink(2) is a +// noticeably slow system call. As of 2016, unlink takes 250 +// milliseconds to remove a 1 GB file on ext4 filesystem on my machine. +// +// To create a new result file, we first remove existing file. So, if +// you repeatedly link a 1 GB program in a regular compile-link-debug +// cycle, every cycle wastes 250 milliseconds only to remove a file. +// Since LLD can link a 1 GB binary in about 5 seconds, that waste +// actually counts. +// +// This function spawns a background thread to remove the file. +// The calling thread returns almost immediately. +void lld::unlinkAsync(StringRef path) { +// Removing a file is async on windows. +#if defined(_WIN32) + sys::fs::remove(path); +#else + if (!threadsEnabled || !sys::fs::exists(path) || + !sys::fs::is_regular_file(path)) + return; + + // We cannot just remove path from a different thread because we are now going + // to create path as a new file. + // Instead we open the file and unlink it on this thread. The unlink is fast + // since the open fd guarantees that it is not removing the last reference. + int fd; + std::error_code ec = sys::fs::openFileForRead(path, fd); + sys::fs::remove(path); + + if (ec) + return; + + // close and therefore remove TempPath in background. + std::mutex m; + std::condition_variable cv; + bool started = false; + std::thread([&, fd] { + { + std::lock_guard<std::mutex> l(m); + started = true; + cv.notify_all(); + } + ::close(fd); + }).detach(); + + // GLIBC 2.26 and earlier have race condition that crashes an entire process + // if the main thread calls exit(2) while other thread is starting up. + std::unique_lock<std::mutex> l(m); + cv.wait(l, [&] { return started; }); +#endif +} + +// Simulate file creation to see if Path is writable. +// +// Determining whether a file is writable or not is amazingly hard, +// and after all the only reliable way of doing that is to actually +// create a file. But we don't want to do that in this function +// because LLD shouldn't update any file if it will end in a failure. +// We also don't want to reimplement heuristics to determine if a +// file is writable. So we'll let FileOutputBuffer do the work. +// +// FileOutputBuffer doesn't touch a desitnation file until commit() +// is called. We use that class without calling commit() to predict +// if the given file is writable. +std::error_code lld::tryCreateFile(StringRef path) { + if (path.empty()) + return std::error_code(); + if (path == "-") + return std::error_code(); + return errorToErrorCode(FileOutputBuffer::create(path, 1).takeError()); +} diff --git a/Common/Memory.cpp b/Common/Memory.cpp index efc5bcc2218b4..c53e1d3e6cfc7 100644 --- a/Common/Memory.cpp +++ b/Common/Memory.cpp @@ -1,9 +1,8 @@ //===- Memory.cpp ---------------------------------------------------------===// // -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -12,12 +11,12 @@ using namespace llvm; using namespace lld; -BumpPtrAllocator lld::BAlloc; -StringSaver lld::Saver{BAlloc}; -std::vector<SpecificAllocBase *> lld::SpecificAllocBase::Instances; +BumpPtrAllocator lld::bAlloc; +StringSaver lld::saver{bAlloc}; +std::vector<SpecificAllocBase *> lld::SpecificAllocBase::instances; void lld::freeArena() { - for (SpecificAllocBase *Alloc : SpecificAllocBase::Instances) - Alloc->reset(); - BAlloc.Reset(); + for (SpecificAllocBase *alloc : SpecificAllocBase::instances) + alloc->reset(); + bAlloc.Reset(); } diff --git a/Common/Reproduce.cpp b/Common/Reproduce.cpp index 7be4ea6bb98b5..24210c420418c 100644 --- a/Common/Reproduce.cpp +++ b/Common/Reproduce.cpp @@ -1,9 +1,8 @@ //===- Reproduce.cpp - Utilities for creating reproducers -----------------===// // -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -22,45 +21,41 @@ using namespace llvm::sys; // assuming that the current directory is "/home/john/bar". // Returned string is a forward slash separated path even on Windows to avoid // a mess with backslash-as-escape and backslash-as-path-separator. -std::string lld::relativeToRoot(StringRef Path) { - SmallString<128> Abs = Path; - if (fs::make_absolute(Abs)) - return Path; - path::remove_dots(Abs, /*remove_dot_dot=*/true); +std::string lld::relativeToRoot(StringRef path) { + SmallString<128> abs = path; + if (fs::make_absolute(abs)) + return path; + path::remove_dots(abs, /*remove_dot_dot=*/true); // This is Windows specific. root_name() returns a drive letter // (e.g. "c:") or a UNC name (//net). We want to keep it as part // of the result. - SmallString<128> Res; - StringRef Root = path::root_name(Abs); - if (Root.endswith(":")) - Res = Root.drop_back(); - else if (Root.startswith("//")) - Res = Root.substr(2); - - path::append(Res, path::relative_path(Abs)); - return path::convert_to_slash(Res); + SmallString<128> res; + StringRef root = path::root_name(abs); + if (root.endswith(":")) + res = root.drop_back(); + else if (root.startswith("//")) + res = root.substr(2); + + path::append(res, path::relative_path(abs)); + return path::convert_to_slash(res); } // Quote a given string if it contains a space character. -std::string lld::quote(StringRef S) { - if (S.contains(' ')) - return ("\"" + S + "\"").str(); - return S; -} - -std::string lld::rewritePath(StringRef S) { - if (fs::exists(S)) - return relativeToRoot(S); - return S; +std::string lld::quote(StringRef s) { + if (s.contains(' ')) + return ("\"" + s + "\"").str(); + return s; } -std::string lld::toString(const opt::Arg &Arg) { - std::string K = Arg.getSpelling(); - if (Arg.getNumValues() == 0) - return K; - std::string V = quote(Arg.getValue()); - if (Arg.getOption().getRenderStyle() == opt::Option::RenderJoinedStyle) - return K + V; - return K + " " + V; +// Converts an Arg to a string representation suitable for a response file. +// To show an Arg in a diagnostic, use Arg::getAsString() instead. +std::string lld::toString(const opt::Arg &arg) { + std::string k = arg.getSpelling(); + if (arg.getNumValues() == 0) + return k; + std::string v = quote(arg.getValue()); + if (arg.getOption().getRenderStyle() == opt::Option::RenderJoinedStyle) + return k + v; + return k + " " + v; } diff --git a/Common/Strings.cpp b/Common/Strings.cpp index 6f74865b7f42d..0bf06626cc7a9 100644 --- a/Common/Strings.cpp +++ b/Common/Strings.cpp @@ -1,9 +1,8 @@ //===- Strings.cpp -------------------------------------------------------===// // -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -20,85 +19,85 @@ using namespace llvm; using namespace lld; // Returns the demangled C++ symbol name for Name. -Optional<std::string> lld::demangleItanium(StringRef Name) { +Optional<std::string> lld::demangleItanium(StringRef name) { // itaniumDemangle can be used to demangle strings other than symbol // names which do not necessarily start with "_Z". Name can be // either a C or C++ symbol. Don't call itaniumDemangle if the name // does not look like a C++ symbol name to avoid getting unexpected // result for a C symbol that happens to match a mangled type name. - if (!Name.startswith("_Z")) + if (!name.startswith("_Z")) return None; - char *Buf = itaniumDemangle(Name.str().c_str(), nullptr, nullptr, nullptr); - if (!Buf) + char *buf = itaniumDemangle(name.str().c_str(), nullptr, nullptr, nullptr); + if (!buf) return None; - std::string S(Buf); - free(Buf); - return S; + std::string s(buf); + free(buf); + return s; } -Optional<std::string> lld::demangleMSVC(StringRef Name) { - std::string Prefix; - if (Name.consume_front("__imp_")) - Prefix = "__declspec(dllimport) "; +Optional<std::string> lld::demangleMSVC(StringRef name) { + std::string prefix; + if (name.consume_front("__imp_")) + prefix = "__declspec(dllimport) "; // Demangle only C++ names. - if (!Name.startswith("?")) + if (!name.startswith("?")) return None; - char *Buf = microsoftDemangle(Name.str().c_str(), nullptr, nullptr, nullptr); - if (!Buf) + char *buf = microsoftDemangle(name.str().c_str(), nullptr, nullptr, nullptr); + if (!buf) return None; - std::string S(Buf); - free(Buf); - return Prefix + S; + std::string s(buf); + free(buf); + return prefix + s; } -StringMatcher::StringMatcher(ArrayRef<StringRef> Pat) { - for (StringRef S : Pat) { - Expected<GlobPattern> Pat = GlobPattern::create(S); - if (!Pat) - error(toString(Pat.takeError())); +StringMatcher::StringMatcher(ArrayRef<StringRef> pat) { + for (StringRef s : pat) { + Expected<GlobPattern> pat = GlobPattern::create(s); + if (!pat) + error(toString(pat.takeError())); else - Patterns.push_back(*Pat); + patterns.push_back(*pat); } } -bool StringMatcher::match(StringRef S) const { - for (const GlobPattern &Pat : Patterns) - if (Pat.match(S)) +bool StringMatcher::match(StringRef s) const { + for (const GlobPattern &pat : patterns) + if (pat.match(s)) return true; return false; } // Converts a hex string (e.g. "deadbeef") to a vector. -std::vector<uint8_t> lld::parseHex(StringRef S) { - std::vector<uint8_t> Hex; - while (!S.empty()) { - StringRef B = S.substr(0, 2); - S = S.substr(2); - uint8_t H; - if (!to_integer(B, H, 16)) { - error("not a hexadecimal value: " + B); +std::vector<uint8_t> lld::parseHex(StringRef s) { + std::vector<uint8_t> hex; + while (!s.empty()) { + StringRef b = s.substr(0, 2); + s = s.substr(2); + uint8_t h; + if (!to_integer(b, h, 16)) { + error("not a hexadecimal value: " + b); return {}; } - Hex.push_back(H); + hex.push_back(h); } - return Hex; + return hex; } // Returns true if S is valid as a C language identifier. -bool lld::isValidCIdentifier(StringRef S) { - return !S.empty() && (isAlpha(S[0]) || S[0] == '_') && - std::all_of(S.begin() + 1, S.end(), - [](char C) { return C == '_' || isAlnum(C); }); +bool lld::isValidCIdentifier(StringRef s) { + return !s.empty() && (isAlpha(s[0]) || s[0] == '_') && + std::all_of(s.begin() + 1, s.end(), + [](char c) { return c == '_' || isAlnum(c); }); } // Write the contents of the a buffer to a file -void lld::saveBuffer(StringRef Buffer, const Twine &Path) { - std::error_code EC; - raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None); - if (EC) - error("cannot create " + Path + ": " + EC.message()); - OS << Buffer; +void lld::saveBuffer(StringRef buffer, const Twine &path) { + std::error_code ec; + raw_fd_ostream os(path.str(), ec, sys::fs::OpenFlags::F_None); + if (ec) + error("cannot create " + path + ": " + ec.message()); + os << buffer; } diff --git a/Common/TargetOptionsCommandFlags.cpp b/Common/TargetOptionsCommandFlags.cpp index 7a3fc510704f5..d4c29d7f88b80 100644 --- a/Common/TargetOptionsCommandFlags.cpp +++ b/Common/TargetOptionsCommandFlags.cpp @@ -1,9 +1,8 @@ //===-- TargetOptionsCommandFlags.cpp ---------------------------*- C++ -*-===// // -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -20,16 +19,17 @@ #include "llvm/Target/TargetOptions.h" // Define an externally visible version of -// InitTargetOptionsFromCodeGenFlags, so that its functionality can be +// initTargetOptionsFromCodeGenFlags, so that its functionality can be // used without having to include llvm/CodeGen/CommandFlags.inc, which // would lead to multiple definitions of the command line flags. -llvm::TargetOptions lld::InitTargetOptionsFromCodeGenFlags() { +llvm::TargetOptions lld::initTargetOptionsFromCodeGenFlags() { return ::InitTargetOptionsFromCodeGenFlags(); } -llvm::Optional<llvm::CodeModel::Model> lld::GetCodeModelFromCMModel() { +llvm::Optional<llvm::CodeModel::Model> lld::getCodeModelFromCMModel() { return getCodeModel(); } -std::string lld::GetCPUStr() { return ::getCPUStr(); } -std::vector<std::string> lld::GetMAttrs() { return ::MAttrs; } +std::string lld::getCPUStr() { return ::getCPUStr(); } + +std::vector<std::string> lld::getMAttrs() { return ::MAttrs; } diff --git a/Common/Threads.cpp b/Common/Threads.cpp index c64b8c38b9091..af04972a37602 100644 --- a/Common/Threads.cpp +++ b/Common/Threads.cpp @@ -1,12 +1,11 @@ //===- Threads.cpp --------------------------------------------------------===// // -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "lld/Common/Threads.h" -bool lld::ThreadsEnabled = true; +bool lld::threadsEnabled = true; diff --git a/Common/Timer.cpp b/Common/Timer.cpp index 89f9829b47cf2..4b7d11003b2cb 100644 --- a/Common/Timer.cpp +++ b/Common/Timer.cpp @@ -1,9 +1,8 @@ //===- Timer.cpp ----------------------------------------------------------===// // -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -14,43 +13,43 @@ using namespace lld; using namespace llvm; -ScopedTimer::ScopedTimer(Timer &T) : T(&T) { T.start(); } +ScopedTimer::ScopedTimer(Timer &t) : t(&t) { t.start(); } void ScopedTimer::stop() { - if (!T) + if (!t) return; - T->stop(); - T = nullptr; + t->stop(); + t = nullptr; } ScopedTimer::~ScopedTimer() { stop(); } -Timer::Timer(llvm::StringRef Name) : Name(Name), Parent(nullptr) {} -Timer::Timer(llvm::StringRef Name, Timer &Parent) - : Name(Name), Parent(&Parent) {} +Timer::Timer(llvm::StringRef name) : name(name), parent(nullptr) {} +Timer::Timer(llvm::StringRef name, Timer &parent) + : name(name), parent(&parent) {} void Timer::start() { - if (Parent && Total.count() == 0) - Parent->Children.push_back(this); - StartTime = std::chrono::high_resolution_clock::now(); + if (parent && total.count() == 0) + parent->children.push_back(this); + startTime = std::chrono::high_resolution_clock::now(); } void Timer::stop() { - Total += (std::chrono::high_resolution_clock::now() - StartTime); + total += (std::chrono::high_resolution_clock::now() - startTime); } Timer &Timer::root() { - static Timer RootTimer("Total Link Time"); - return RootTimer; + static Timer rootTimer("Total Link Time"); + return rootTimer; } void Timer::print() { - double TotalDuration = static_cast<double>(root().millis()); + double totalDuration = static_cast<double>(root().millis()); // We want to print the grand total under all the intermediate phases, so we // print all children first, then print the total under that. - for (const auto &Child : Children) - Child->print(1, TotalDuration); + for (const auto &child : children) + child->print(1, totalDuration); message(std::string(49, '-')); @@ -59,22 +58,22 @@ void Timer::print() { double Timer::millis() const { return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>( - Total) + total) .count(); } -void Timer::print(int Depth, double TotalDuration, bool Recurse) const { - double P = 100.0 * millis() / TotalDuration; +void Timer::print(int depth, double totalDuration, bool recurse) const { + double p = 100.0 * millis() / totalDuration; - SmallString<32> Str; - llvm::raw_svector_ostream Stream(Str); - std::string S = std::string(Depth * 2, ' ') + Name + std::string(":"); - Stream << format("%-30s%5d ms (%5.1f%%)", S.c_str(), (int)millis(), P); + SmallString<32> str; + llvm::raw_svector_ostream stream(str); + std::string s = std::string(depth * 2, ' ') + name + std::string(":"); + stream << format("%-30s%5d ms (%5.1f%%)", s.c_str(), (int)millis(), p); - message(Str); + message(str); - if (Recurse) { - for (const auto &Child : Children) - Child->print(Depth + 1, TotalDuration); + if (recurse) { + for (const auto &child : children) + child->print(depth + 1, totalDuration); } } diff --git a/Common/Version.cpp b/Common/Version.cpp index 6226c9a2fac69..ae10f2f28b229 100644 --- a/Common/Version.cpp +++ b/Common/Version.cpp @@ -1,9 +1,8 @@ //===- lib/Common/Version.cpp - LLD Version Number ---------------*- C++-=====// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -13,31 +12,16 @@ #include "lld/Common/Version.h" -using namespace llvm; - -// Returns an SVN repository path, which is usually "trunk". -static std::string getRepositoryPath() { - StringRef S = LLD_REPOSITORY_STRING; - size_t Pos = S.find("lld/"); - if (Pos != StringRef::npos) - return S.substr(Pos + 4); - return S; -} - -// Returns an SVN repository name, e.g., " (trunk 284614)" -// or an empty string if no repository info is available. -static std::string getRepository() { - std::string Repo = getRepositoryPath(); - std::string Rev = LLD_REVISION_STRING; - - if (Repo.empty() && Rev.empty()) - return ""; - if (!Repo.empty() && !Rev.empty()) - return " (" + Repo + " " + Rev + ")"; - return " (" + Repo + Rev + ")"; -} +#ifdef HAVE_VCS_VERSION_INC +#include "VCSVersion.inc" +#endif -// Returns a version string, e.g., "LLD 4.0 (lld/trunk 284614)". +// Returns a version string, e.g.: +// lld 9.0.0 (https://github.com/llvm/llvm-project.git 9efdd7ac5e914d3c9fa1ef) std::string lld::getLLDVersion() { - return "LLD " + std::string(LLD_VERSION_STRING) + getRepository(); +#if defined(LLD_REPOSITORY) && defined(LLD_REVISION) + return "LLD " LLD_VERSION_STRING " (" LLD_REPOSITORY " " LLD_REVISION ")"; +#else + return "LLD " LLD_VERSION_STRING; +#endif } |