Update prebuilt Clang to r416183b from Android.
https://android.googlesource.com/platform/prebuilts/clang/host/
linux-x86/+/06a71ddac05c22edb2d10b590e1769b3f8619bef
clang 12.0.5 (based on r416183b) from build 7284624.
Change-Id: I277a316abcf47307562d8b748b84870f31a72866
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/linux-x64/clang/include/lld/Common/Args.h b/linux-x64/clang/include/lld/Common/Args.h
index b3c8686..48f7b40 100644
--- a/linux-x64/clang/include/lld/Common/Args.h
+++ b/linux-x64/clang/include/lld/Common/Args.h
@@ -28,6 +28,8 @@
int64_t getInteger(llvm::opt::InputArgList &args, unsigned key,
int64_t Default);
+int64_t getHex(llvm::opt::InputArgList &args, unsigned key, int64_t Default);
+
std::vector<StringRef> getStrings(llvm::opt::InputArgList &args, int id);
uint64_t getZOptionValue(llvm::opt::InputArgList &args, int id, StringRef key,
diff --git a/linux-x64/clang/include/lld/Common/DWARF.h b/linux-x64/clang/include/lld/Common/DWARF.h
new file mode 100644
index 0000000..b77985a
--- /dev/null
+++ b/linux-x64/clang/include/lld/Common/DWARF.h
@@ -0,0 +1,49 @@
+//===- DWARF.h --------------------------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_DWARF_H
+#define LLD_DWARF_H
+
+#include "lld/Common/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
+#include <memory>
+#include <string>
+
+namespace llvm {
+struct DILineInfo;
+} // namespace llvm
+
+namespace lld {
+
+class DWARFCache {
+public:
+ DWARFCache(std::unique_ptr<llvm::DWARFContext> dwarf);
+ llvm::Optional<llvm::DILineInfo> getDILineInfo(uint64_t offset,
+ uint64_t sectionIndex);
+ llvm::Optional<std::pair<std::string, unsigned>>
+ getVariableLoc(StringRef name);
+
+ llvm::DWARFContext *getContext() { return dwarf.get(); }
+
+private:
+ std::unique_ptr<llvm::DWARFContext> dwarf;
+ std::vector<const llvm::DWARFDebugLine::LineTable *> lineTables;
+ struct VarLoc {
+ const llvm::DWARFDebugLine::LineTable *lt;
+ unsigned file;
+ unsigned line;
+ };
+ llvm::DenseMap<StringRef, VarLoc> variableLoc;
+};
+
+} // namespace lld
+
+#endif
diff --git a/linux-x64/clang/include/lld/Common/Driver.h b/linux-x64/clang/include/lld/Common/Driver.h
index e559595..eb5bc7b 100644
--- a/linux-x64/clang/include/lld/Common/Driver.h
+++ b/linux-x64/clang/include/lld/Common/Driver.h
@@ -13,29 +13,48 @@
#include "llvm/Support/raw_ostream.h"
namespace lld {
+struct SafeReturn {
+ int ret;
+ bool canRunAgain;
+};
+
+// Generic entry point when using LLD as a library, safe for re-entry, supports
+// crash recovery. Returns a general completion code and a boolean telling
+// whether it can be called again. In some cases, a crash could corrupt memory
+// and re-entry would not be possible anymore. Use exitLld() in that case to
+// properly exit your application and avoid intermittent crashes on exit caused
+// by cleanup.
+SafeReturn safeLldMain(int argc, const char **argv, llvm::raw_ostream &stdoutOS,
+ llvm::raw_ostream &stderrOS);
+
namespace coff {
bool link(llvm::ArrayRef<const char *> args, bool canExitEarly,
- llvm::raw_ostream &diag = llvm::errs());
+ llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS);
}
namespace mingw {
-bool link(llvm::ArrayRef<const char *> args,
- llvm::raw_ostream &diag = llvm::errs());
+bool link(llvm::ArrayRef<const char *> args, bool canExitEarly,
+ llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS);
}
namespace elf {
bool link(llvm::ArrayRef<const char *> args, bool canExitEarly,
- llvm::raw_ostream &diag = llvm::errs());
+ llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS);
}
namespace mach_o {
bool link(llvm::ArrayRef<const char *> args, bool canExitEarly,
- llvm::raw_ostream &diag = llvm::errs());
+ llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS);
+}
+
+namespace macho {
+bool link(llvm::ArrayRef<const char *> args, bool canExitEarly,
+ llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS);
}
namespace wasm {
bool link(llvm::ArrayRef<const char *> args, bool canExitEarly,
- llvm::raw_ostream &diag = llvm::errs());
+ llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS);
}
}
diff --git a/linux-x64/clang/include/lld/Common/ErrorHandler.h b/linux-x64/clang/include/lld/Common/ErrorHandler.h
index 3467fdc..4460452 100644
--- a/linux-x64/clang/include/lld/Common/ErrorHandler.h
+++ b/linux-x64/clang/include/lld/Common/ErrorHandler.h
@@ -59,7 +59,7 @@
//
// warn() doesn't do anything but printing out a given message.
//
-// It is not recommended to use llvm::outs() or llvm::errs() directly in lld
+// It is not recommended to use llvm::outs() or lld::errs() directly in lld
// because they are not thread-safe. The functions declared in this file are
// thread-safe.
//
@@ -76,38 +76,63 @@
namespace llvm {
class DiagnosticInfo;
+class raw_ostream;
}
namespace lld {
+// We wrap stdout and stderr so that you can pass alternative stdout/stderr as
+// arguments to lld::*::link() functions.
+extern llvm::raw_ostream *stdoutOS;
+extern llvm::raw_ostream *stderrOS;
+
+llvm::raw_ostream &outs();
+llvm::raw_ostream &errs();
+
+enum class ErrorTag { LibNotFound, SymbolNotFound };
+
class ErrorHandler {
public:
uint64_t errorCount = 0;
uint64_t errorLimit = 20;
StringRef errorLimitExceededMsg = "too many errors emitted, stopping now";
+ StringRef errorHandlingScript;
StringRef logName = "lld";
- llvm::raw_ostream *errorOS = &llvm::errs();
- bool colorDiagnostics = llvm::errs().has_colors();
bool exitEarly = true;
bool fatalWarnings = false;
bool verbose = false;
+ bool vsDiagnostics = false;
+ bool disableOutput = false;
+ std::function<void()> cleanupCallback;
void error(const Twine &msg);
+ void error(const Twine &msg, ErrorTag tag, ArrayRef<StringRef> args);
LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &msg);
void log(const Twine &msg);
void message(const Twine &msg);
void warn(const Twine &msg);
+ void reset() {
+ if (cleanupCallback)
+ cleanupCallback();
+ *this = ErrorHandler();
+ }
+
std::unique_ptr<llvm::FileOutputBuffer> outputBuffer;
private:
- void print(StringRef s, raw_ostream::Colors c);
+ using Colors = raw_ostream::Colors;
+
+ std::string getLocation(const Twine &msg);
};
/// Returns the default error handler.
ErrorHandler &errorHandler();
inline void error(const Twine &msg) { errorHandler().error(msg); }
+inline void error(const Twine &msg, ErrorTag tag, ArrayRef<StringRef> args) {
+ errorHandler().error(msg, tag, args);
+}
inline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &msg) {
errorHandler().fatal(msg);
}
@@ -135,6 +160,13 @@
return std::move(*e);
}
+// Don't move from Expected wrappers around references.
+template <class T> T &check(Expected<T &> e) {
+ if (!e)
+ fatal(llvm::toString(e.takeError()));
+ return *e;
+}
+
template <class T>
T check2(ErrorOr<T> e, llvm::function_ref<std::string()> prefix) {
if (auto ec = e.getError())
diff --git a/linux-x64/clang/include/lld/Common/LLVM.h b/linux-x64/clang/include/lld/Common/LLVM.h
index f7ed1d7..f6eca27 100644
--- a/linux-x64/clang/include/lld/Common/LLVM.h
+++ b/linux-x64/clang/include/lld/Common/LLVM.h
@@ -17,6 +17,7 @@
// This should be the only #include, force #includes of all the others on
// clients.
#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include <utility>
@@ -48,12 +49,18 @@
struct WasmFunction;
struct WasmGlobal;
struct WasmGlobalType;
+struct WasmLimits;
struct WasmRelocation;
struct WasmSignature;
+struct WasmTable;
+struct WasmTableType;
} // namespace wasm
} // namespace llvm
namespace lld {
+llvm::raw_ostream &outs();
+llvm::raw_ostream &errs();
+
// Casting operators.
using llvm::cast;
using llvm::cast_or_null;
@@ -84,8 +91,11 @@
using llvm::wasm::WasmFunction;
using llvm::wasm::WasmGlobal;
using llvm::wasm::WasmGlobalType;
+using llvm::wasm::WasmLimits;
using llvm::wasm::WasmRelocation;
using llvm::wasm::WasmSignature;
+using llvm::wasm::WasmTable;
+using llvm::wasm::WasmTableType;
} // end namespace lld.
namespace std {
diff --git a/linux-x64/clang/include/lld/Common/Memory.h b/linux-x64/clang/include/lld/Common/Memory.h
index 41d8f15..f516a32 100644
--- a/linux-x64/clang/include/lld/Common/Memory.h
+++ b/linux-x64/clang/include/lld/Common/Memory.h
@@ -47,11 +47,20 @@
llvm::SpecificBumpPtrAllocator<T> alloc;
};
+// Use a static local for these singletons so they are only registered if an
+// object of this instance is ever constructed. Otherwise we will create and
+// register ELF allocators for COFF and the reverse.
+template <typename T>
+inline llvm::SpecificBumpPtrAllocator<T> &getSpecificAllocSingleton() {
+ static SpecificAlloc<T> instance;
+ return instance.alloc;
+}
+
// Use this arena if your object has a destructor.
// Your destructor will be invoked from freeArena().
template <typename T, typename... U> T *make(U &&... args) {
- static SpecificAlloc<T> alloc;
- return new (alloc.alloc.Allocate()) T(std::forward<U>(args)...);
+ return new (getSpecificAllocSingleton<T>().Allocate())
+ T(std::forward<U>(args)...);
}
} // namespace lld
diff --git a/linux-x64/clang/include/lld/Common/Strings.h b/linux-x64/clang/include/lld/Common/Strings.h
index ded22dd..38d93e0 100644
--- a/linux-x64/clang/include/lld/Common/Strings.h
+++ b/linux-x64/clang/include/lld/Common/Strings.h
@@ -18,9 +18,8 @@
namespace lld {
// Returns a demangled C++ symbol name. If Name is not a mangled
-// name, it returns Optional::None.
-llvm::Optional<std::string> demangleItanium(llvm::StringRef name);
-llvm::Optional<std::string> demangleMSVC(llvm::StringRef s);
+// name, it returns name.
+std::string demangleItanium(llvm::StringRef name);
std::vector<uint8_t> parseHex(llvm::StringRef s);
bool isValidCIdentifier(llvm::StringRef s);
@@ -28,16 +27,57 @@
// Write the contents of the a buffer to a file
void saveBuffer(llvm::StringRef buffer, const llvm::Twine &path);
-// This class represents multiple glob patterns.
-class StringMatcher {
+// A single pattern to match against. A pattern can either be double-quoted
+// text that should be matched exactly after removing the quoting marks or a
+// glob pattern in the sense of GlobPattern.
+class SingleStringMatcher {
public:
- StringMatcher() = default;
- explicit StringMatcher(llvm::ArrayRef<llvm::StringRef> pat);
+ // Create a StringPattern from Pattern to be matched exactly irregardless
+ // of globbing characters if ExactMatch is true.
+ SingleStringMatcher(llvm::StringRef Pattern);
+ // Match s against this pattern, exactly if ExactMatch is true.
bool match(llvm::StringRef s) const;
+ // Returns true for pattern "*" which will match all inputs.
+ bool isTrivialMatchAll() const {
+ return !ExactMatch && GlobPatternMatcher.isTrivialMatchAll();
+ }
+
private:
- std::vector<llvm::GlobPattern> patterns;
+ // Whether to do an exact match irregardless of the presence of wildcard
+ // character.
+ bool ExactMatch;
+
+ // GlobPattern object if not doing an exact match.
+ llvm::GlobPattern GlobPatternMatcher;
+
+ // StringRef to match exactly if doing an exact match.
+ llvm::StringRef ExactPattern;
+};
+
+// This class represents multiple patterns to match against. A pattern can
+// either be a double-quoted text that should be matched exactly after removing
+// the quoted marks or a glob pattern.
+class StringMatcher {
+private:
+ // Patterns to match against.
+ std::vector<SingleStringMatcher> patterns;
+
+public:
+ StringMatcher() = default;
+
+ // Matcher for a single pattern.
+ StringMatcher(llvm::StringRef Pattern)
+ : patterns({SingleStringMatcher(Pattern)}) {}
+
+ // Add a new pattern to the existing ones to match against.
+ void addPattern(SingleStringMatcher Matcher) { patterns.push_back(Matcher); }
+
+ bool empty() const { return patterns.empty(); }
+
+ // Match s against the patterns.
+ bool match(llvm::StringRef s) const;
};
} // namespace lld
diff --git a/linux-x64/clang/include/lld/Common/TargetOptionsCommandFlags.h b/linux-x64/clang/include/lld/Common/TargetOptionsCommandFlags.h
index 9345e61..422bb63 100644
--- a/linux-x64/clang/include/lld/Common/TargetOptionsCommandFlags.h
+++ b/linux-x64/clang/include/lld/Common/TargetOptionsCommandFlags.h
@@ -16,6 +16,7 @@
namespace lld {
llvm::TargetOptions initTargetOptionsFromCodeGenFlags();
+llvm::Optional<llvm::Reloc::Model> getRelocModelFromCMModel();
llvm::Optional<llvm::CodeModel::Model> getCodeModelFromCMModel();
std::string getCPUStr();
std::vector<std::string> getMAttrs();
diff --git a/linux-x64/clang/include/lld/Common/Threads.h b/linux-x64/clang/include/lld/Common/Threads.h
deleted file mode 100644
index 7834130..0000000
--- a/linux-x64/clang/include/lld/Common/Threads.h
+++ /dev/null
@@ -1,92 +0,0 @@
-//===- Threads.h ------------------------------------------------*- C++ -*-===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-//
-// LLD supports threads to distribute workloads to multiple cores. Using
-// multicore is most effective when more than one core are idle. At the
-// last step of a build, it is often the case that a linker is the only
-// active process on a computer. So, we are naturally interested in using
-// threads wisely to reduce latency to deliver results to users.
-//
-// That said, we don't want to do "too clever" things using threads.
-// Complex multi-threaded algorithms are sometimes extremely hard to
-// reason about and can easily mess up the entire design.
-//
-// Fortunately, when a linker links large programs (when the link time is
-// most critical), it spends most of the time to work on massive number of
-// small pieces of data of the same kind, and there are opportunities for
-// large parallelism there. Here are examples:
-//
-// - We have hundreds of thousands of input sections that need to be
-// copied to a result file at the last step of link. Once we fix a file
-// layout, each section can be copied to its destination and its
-// relocations can be applied independently.
-//
-// - We have tens of millions of small strings when constructing a
-// mergeable string section.
-//
-// For the cases such as the former, we can just use parallelForEach
-// instead of std::for_each (or a plain for loop). Because tasks are
-// completely independent from each other, we can run them in parallel
-// without any coordination between them. That's very easy to understand
-// and reason about.
-//
-// For the cases such as the latter, we can use parallel algorithms to
-// deal with massive data. We have to write code for a tailored algorithm
-// for each problem, but the complexity of multi-threading is isolated in
-// a single pass and doesn't affect the linker's overall design.
-//
-// The above approach seems to be working fairly well. As an example, when
-// linking Chromium (output size 1.6 GB), using 4 cores reduces latency to
-// 75% compared to single core (from 12.66 seconds to 9.55 seconds) on my
-// Ivy Bridge Xeon 2.8 GHz machine. Using 40 cores reduces it to 63% (from
-// 12.66 seconds to 7.95 seconds). Because of the Amdahl's law, the
-// speedup is not linear, but as you add more cores, it gets faster.
-//
-// On a final note, if you are trying to optimize, keep the axiom "don't
-// guess, measure!" in mind. Some important passes of the linker are not
-// that slow. For example, resolving all symbols is not a very heavy pass,
-// although it would be very hard to parallelize it. You want to first
-// identify a slow pass and then optimize it.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_COMMON_THREADS_H
-#define LLD_COMMON_THREADS_H
-
-#include "llvm/Support/Parallel.h"
-#include <functional>
-
-namespace lld {
-
-extern bool threadsEnabled;
-
-template <typename R, class FuncTy> void parallelForEach(R &&range, FuncTy fn) {
- if (threadsEnabled)
- for_each(llvm::parallel::par, std::begin(range), std::end(range), fn);
- else
- for_each(llvm::parallel::seq, std::begin(range), std::end(range), fn);
-}
-
-inline void parallelForEachN(size_t begin, size_t end,
- llvm::function_ref<void(size_t)> fn) {
- if (threadsEnabled)
- for_each_n(llvm::parallel::par, begin, end, fn);
- else
- for_each_n(llvm::parallel::seq, begin, end, fn);
-}
-
-template <typename R, class FuncTy> void parallelSort(R &&range, FuncTy fn) {
- if (threadsEnabled)
- sort(llvm::parallel::par, std::begin(range), std::end(range), fn);
- else
- sort(llvm::parallel::seq, std::begin(range), std::end(range), fn);
-}
-
-} // namespace lld
-
-#endif
diff --git a/linux-x64/clang/include/lld/Common/Timer.h b/linux-x64/clang/include/lld/Common/Timer.h
index 4a298b0..95e811a 100644
--- a/linux-x64/clang/include/lld/Common/Timer.h
+++ b/linux-x64/clang/include/lld/Common/Timer.h
@@ -12,6 +12,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include <assert.h>
+#include <atomic>
#include <chrono>
#include <map>
#include <memory>
@@ -27,6 +28,8 @@
void stop();
+ std::chrono::time_point<std::chrono::high_resolution_clock> startTime;
+
Timer *t = nullptr;
};
@@ -36,8 +39,7 @@
static Timer &root();
- void start();
- void stop();
+ void addToTotal(std::chrono::nanoseconds time) { total += time.count(); }
void print();
double millis() const;
@@ -46,11 +48,9 @@
explicit Timer(llvm::StringRef name);
void print(int depth, double totalDuration, bool recurse = true) const;
- std::chrono::time_point<std::chrono::high_resolution_clock> startTime;
- std::chrono::nanoseconds total;
+ std::atomic<std::chrono::nanoseconds::rep> total;
std::vector<Timer *> children;
std::string name;
- Timer *parent;
};
} // namespace lld