summaryrefslogtreecommitdiff
path: root/Common
diff options
context:
space:
mode:
Diffstat (limited to 'Common')
-rw-r--r--Common/Args.cpp87
-rw-r--r--Common/CMakeLists.txt27
-rw-r--r--Common/ErrorHandler.cpp160
-rw-r--r--Common/Filesystem.cpp99
-rw-r--r--Common/Memory.cpp19
-rw-r--r--Common/Reproduce.cpp67
-rw-r--r--Common/Strings.cpp99
-rw-r--r--Common/TargetOptionsCommandFlags.cpp18
-rw-r--r--Common/Threads.cpp9
-rw-r--r--Common/Timer.cpp61
-rw-r--r--Common/Version.cpp42
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
}