aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:19:15 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:19:15 +0000
commitd93e1dfac8711cfed1a9d9cd1876a788b83945cd (patch)
tree5896fa6c02a262a6148b215487e545d937de58b7 /include
parent8d43286d630f9224de07809ea253e83ebb9cdee6 (diff)
downloadsrc-d93e1dfac8711cfed1a9d9cd1876a788b83945cd.tar.gz
src-d93e1dfac8711cfed1a9d9cd1876a788b83945cd.zip
Vendor import of lld trunk r290819:vendor/lld/lld-trunk-r290819
Notes
Notes: svn path=/vendor/lld/dist/; revision=311125 svn path=/vendor/lld/lld-trunk-r290819/; revision=311126; tag=vendor/lld/lld-trunk-r290819
Diffstat (limited to 'include')
-rw-r--r--include/lld/Config/Version.h34
-rw-r--r--include/lld/Config/Version.inc.in1
-rw-r--r--include/lld/Core/Atom.h16
-rw-r--r--include/lld/Core/DefinedAtom.h4
-rw-r--r--include/lld/Core/LinkingContext.h21
-rw-r--r--include/lld/Core/Node.h11
-rw-r--r--include/lld/Core/Parallel.h69
-rw-r--r--include/lld/Core/Pass.h13
-rw-r--r--include/lld/Core/PassManager.h2
-rw-r--r--include/lld/Core/Reader.h17
-rw-r--r--include/lld/Core/Reference.h10
-rw-r--r--include/lld/Core/Reproduce.h73
-rw-r--r--include/lld/Core/Simple.h83
-rw-r--r--include/lld/Core/SymbolTable.h10
-rw-r--r--include/lld/Driver/Driver.h2
-rw-r--r--include/lld/ReaderWriter/MachOLinkingContext.h6
-rw-r--r--include/lld/Support/Memory.h63
17 files changed, 264 insertions, 171 deletions
diff --git a/include/lld/Config/Version.h b/include/lld/Config/Version.h
index 41433c1175ef..1cec3cc7678c 100644
--- a/include/lld/Config/Version.h
+++ b/include/lld/Config/Version.h
@@ -6,11 +6,9 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines version macros and version-related utility functions
-/// for lld.
-///
+//
+// Defines a version-related utility function.
+//
//===----------------------------------------------------------------------===//
#ifndef LLD_VERSION_H
@@ -18,34 +16,10 @@
#include "lld/Config/Version.inc"
#include "llvm/ADT/StringRef.h"
-#include <string>
-
-/// \brief Helper macro for LLD_VERSION_STRING.
-#define LLD_MAKE_VERSION_STRING2(X) #X
-
-/// \brief Helper macro for LLD_VERSION_STRING.
-#define LLD_MAKE_VERSION_STRING(X, Y) LLD_MAKE_VERSION_STRING2(X.Y)
-
-/// \brief A string that describes the lld version number, e.g., "1.0".
-#define LLD_VERSION_STRING \
- LLD_MAKE_VERSION_STRING(LLD_VERSION_MAJOR, LLD_VERSION_MINOR)
namespace lld {
-/// \brief Retrieves the repository path (e.g., Subversion path) that
-/// identifies the particular lld branch, tag, or trunk from which this
-/// lld was built.
-llvm::StringRef getLLDRepositoryPath();
-
-/// \brief Retrieves the repository revision number (or identifer) from which
-/// this lld was built.
-llvm::StringRef getLLDRevision();
-
-/// \brief Retrieves the full repository version that is an amalgamation of
-/// the information in getLLDRepositoryPath() and getLLDRevision().
-std::string getLLDRepositoryVersion();
-
/// \brief Retrieves a string representing the complete lld version.
-llvm::StringRef getLLDVersion();
+std::string getLLDVersion();
}
#endif // LLD_VERSION_H
diff --git a/include/lld/Config/Version.inc.in b/include/lld/Config/Version.inc.in
index c893a56686c0..2789a5c46089 100644
--- a/include/lld/Config/Version.inc.in
+++ b/include/lld/Config/Version.inc.in
@@ -1,4 +1,5 @@
#define LLD_VERSION @LLD_VERSION@
+#define LLD_VERSION_STRING "@LLD_VERSION@"
#define LLD_VERSION_MAJOR @LLD_VERSION_MAJOR@
#define LLD_VERSION_MINOR @LLD_VERSION_MINOR@
#define LLD_REVISION_STRING "@LLD_REVISION@"
diff --git a/include/lld/Core/Atom.h b/include/lld/Core/Atom.h
index 42ca2bb8af8c..156a5d4a736f 100644
--- a/include/lld/Core/Atom.h
+++ b/include/lld/Core/Atom.h
@@ -1,4 +1,4 @@
-//===- Core/Atom.h - A node in linking graph ------------------------------===//
+//===- Core/Atom.h - A node in linking graph --------------------*- C++ -*-===//
//
// The LLVM Linker
//
@@ -11,6 +11,7 @@
#define LLD_CORE_ATOM_H
#include "lld/Core/LLVM.h"
+#include "llvm/ADT/StringRef.h"
namespace lld {
@@ -28,6 +29,7 @@ class OwningAtomPtr;
///
class Atom {
template<typename T> friend class OwningAtomPtr;
+
public:
/// Whether this atom is defined or a proxy for an undefined symbol
enum Definition {
@@ -47,7 +49,6 @@ public:
/// loader (e.g. visibility=default).
};
-
/// file - returns the File that produced/owns this Atom
virtual const File& file() const = 0;
@@ -69,7 +70,7 @@ protected:
/// object. Therefore, no one but the owning File object should call
/// delete on an Atom. In fact, some File objects may bulk allocate
/// an array of Atoms, so they cannot be individually deleted by anyone.
- virtual ~Atom() {}
+ virtual ~Atom() = default;
private:
Definition _definition;
@@ -81,9 +82,10 @@ template<typename T>
class OwningAtomPtr {
private:
OwningAtomPtr(const OwningAtomPtr &) = delete;
- void operator=(const OwningAtomPtr&) = delete;
+ void operator=(const OwningAtomPtr &) = delete;
+
public:
- OwningAtomPtr() : atom(nullptr) { }
+ OwningAtomPtr() = default;
OwningAtomPtr(T *atom) : atom(atom) { }
~OwningAtomPtr() {
@@ -121,9 +123,9 @@ public:
}
private:
- T *atom;
+ T *atom = nullptr;
};
-} // namespace lld
+} // end namespace lld
#endif // LLD_CORE_ATOM_H
diff --git a/include/lld/Core/DefinedAtom.h b/include/lld/Core/DefinedAtom.h
index e3193f8aaf2e..7f623d2ea5e6 100644
--- a/include/lld/Core/DefinedAtom.h
+++ b/include/lld/Core/DefinedAtom.h
@@ -354,10 +354,6 @@ public:
return atomContentType == typeCFI;
}
- // Returns true if lhs should be placed before rhs in the final output.
- static bool compareByPosition(const DefinedAtom *lhs,
- const DefinedAtom *rhs);
-
protected:
// DefinedAtom is an abstract base class. Only subclasses can access
// constructor.
diff --git a/include/lld/Core/LinkingContext.h b/include/lld/Core/LinkingContext.h
index 7e4edaf22cf3..b3a999b00fbd 100644
--- a/include/lld/Core/LinkingContext.h
+++ b/include/lld/Core/LinkingContext.h
@@ -1,4 +1,4 @@
-//===- lld/Core/LinkingContext.h - Linker Target Info Interface -----------===//
+//===- lld/Core/LinkingContext.h - Linker Target Info Interface -*- C++ -*-===//
//
// The LLVM Linker
//
@@ -10,17 +10,21 @@
#ifndef LLD_CORE_LINKING_CONTEXT_H
#define LLD_CORE_LINKING_CONTEXT_H
-#include "lld/Core/Error.h"
-#include "lld/Core/LLVM.h"
#include "lld/Core/Node.h"
-#include "lld/Core/Reference.h"
#include "lld/Core/Reader.h"
-#include "llvm/Support/ErrorOr.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdint>
+#include <memory>
#include <string>
#include <vector>
namespace lld {
+
class PassManager;
class File;
class Writer;
@@ -117,12 +121,15 @@ public:
void setDeadStripping(bool enable) { _deadStrip = enable; }
void setGlobalsAreDeadStripRoots(bool v) { _globalsAreDeadStripRoots = v; }
+
void setPrintRemainingUndefines(bool print) {
_printRemainingUndefines = print;
}
+
void setAllowRemainingUndefines(bool allow) {
_allowRemainingUndefines = allow;
}
+
void setAllowShlibUndefines(bool allow) { _allowShlibUndefines = allow; }
void setLogInputFiles(bool log) { _logInputFiles = log; }
@@ -149,7 +156,7 @@ public:
/// during link. Flavors can override this function in their LinkingContext
/// to add more internal files. These internal files are positioned before
/// the actual input files.
- virtual void createInternalFiles(std::vector<std::unique_ptr<File> > &) const;
+ virtual void createInternalFiles(std::vector<std::unique_ptr<File>> &) const;
/// Return the list of undefined symbols that are specified in the
/// linker command line, using the -u option.
@@ -248,4 +255,4 @@ private:
} // end namespace lld
-#endif
+#endif // LLD_CORE_LINKING_CONTEXT_H
diff --git a/include/lld/Core/Node.h b/include/lld/Core/Node.h
index 8de0ecdbba6a..c30482409e7a 100644
--- a/include/lld/Core/Node.h
+++ b/include/lld/Core/Node.h
@@ -1,4 +1,4 @@
-//===- lld/Core/Node.h - Input file class ---------------------------------===//
+//===- lld/Core/Node.h - Input file class -----------------------*- C++ -*-===//
//
// The LLVM Linker
//
@@ -17,9 +17,8 @@
#define LLD_CORE_NODE_H
#include "lld/Core/File.h"
-#include "llvm/Option/ArgList.h"
+#include <algorithm>
#include <memory>
-#include <vector>
namespace lld {
@@ -29,8 +28,10 @@ namespace lld {
class Node {
public:
enum class Kind { File, GroupEnd };
+
explicit Node(Kind type) : _kind(type) {}
- virtual ~Node() {}
+ virtual ~Node() = default;
+
virtual Kind kind() const { return _kind; }
private:
@@ -69,6 +70,6 @@ protected:
std::unique_ptr<File> _file;
};
-} // namespace lld
+} // end namespace lld
#endif // LLD_CORE_NODE_H
diff --git a/include/lld/Core/Parallel.h b/include/lld/Core/Parallel.h
index 2dde97d9e3f0..f241453a4d39 100644
--- a/include/lld/Core/Parallel.h
+++ b/include/lld/Core/Parallel.h
@@ -121,7 +121,7 @@ public:
// Spawn all but one of the threads in another thread as spawning threads
// can take a while.
std::thread([&, threadCount] {
- for (std::size_t i = 1; i < threadCount; ++i) {
+ for (size_t i = 1; i < threadCount; ++i) {
std::thread([=] {
work();
}).detach();
@@ -270,26 +270,65 @@ template <class T> void parallel_sort(T *start, T *end) {
}
#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
-template <class Iterator, class Func>
-void parallel_for_each(Iterator begin, Iterator end, Func func) {
- std::for_each(begin, end, func);
+template <class IterTy, class FuncTy>
+void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
+ std::for_each(Begin, End, Fn);
+}
+
+template <class IndexTy, class FuncTy>
+void parallel_for(IndexTy Begin, IndexTy End, FuncTy Fn) {
+ for (IndexTy I = Begin; I != End; ++I)
+ Fn(I);
}
#elif defined(_MSC_VER)
// Use ppl parallel_for_each on Windows.
-template <class Iterator, class Func>
-void parallel_for_each(Iterator begin, Iterator end, Func func) {
- concurrency::parallel_for_each(begin, end, func);
+template <class IterTy, class FuncTy>
+void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
+ concurrency::parallel_for_each(Begin, End, Fn);
+}
+
+template <class IndexTy, class FuncTy>
+void parallel_for(IndexTy Begin, IndexTy End, FuncTy Fn) {
+ concurrency::parallel_for(Begin, End, Fn);
}
#else
-template <class Iterator, class Func>
-void parallel_for_each(Iterator begin, Iterator end, Func func) {
- TaskGroup tg;
- ptrdiff_t taskSize = 1024;
- while (taskSize <= std::distance(begin, end)) {
- tg.spawn([=, &func] { std::for_each(begin, begin + taskSize, func); });
- begin += taskSize;
+template <class IterTy, class FuncTy>
+void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
+ // TaskGroup has a relatively high overhead, so we want to reduce
+ // the number of spawn() calls. We'll create up to 1024 tasks here.
+ // (Note that 1024 is an arbitrary number. This code probably needs
+ // improving to take the number of available cores into account.)
+ ptrdiff_t TaskSize = std::distance(Begin, End) / 1024;
+ if (TaskSize == 0)
+ TaskSize = 1;
+
+ TaskGroup Tg;
+ while (TaskSize <= std::distance(Begin, End)) {
+ Tg.spawn([=, &Fn] { std::for_each(Begin, Begin + TaskSize, Fn); });
+ Begin += TaskSize;
}
- std::for_each(begin, end, func);
+ Tg.spawn([=, &Fn] { std::for_each(Begin, End, Fn); });
+}
+
+template <class IndexTy, class FuncTy>
+void parallel_for(IndexTy Begin, IndexTy End, FuncTy Fn) {
+ ptrdiff_t TaskSize = (End - Begin) / 1024;
+ if (TaskSize == 0)
+ TaskSize = 1;
+
+ TaskGroup Tg;
+ IndexTy I = Begin;
+ for (; I < End; I += TaskSize) {
+ Tg.spawn([=, &Fn] {
+ for (IndexTy J = I, E = I + TaskSize; J != E; ++J)
+ Fn(J);
+ });
+ Begin += TaskSize;
+ }
+ Tg.spawn([=, &Fn] {
+ for (IndexTy J = I; J < End; ++J)
+ Fn(J);
+ });
}
#endif
} // end namespace lld
diff --git a/include/lld/Core/Pass.h b/include/lld/Core/Pass.h
index 0527f02cd362..bfe3f9b10e0c 100644
--- a/include/lld/Core/Pass.h
+++ b/include/lld/Core/Pass.h
@@ -1,4 +1,4 @@
-//===------ Core/Pass.h - Base class for linker passes --------------------===//
+//===------ Core/Pass.h - Base class for linker passes ----------*- C++ -*-===//
//
// The LLVM Linker
//
@@ -10,13 +10,10 @@
#ifndef LLD_CORE_PASS_H
#define LLD_CORE_PASS_H
-#include "lld/Core/Atom.h"
-#include "lld/Core/File.h"
-#include "lld/Core/Reference.h"
#include "llvm/Support/Error.h"
-#include <vector>
namespace lld {
+
class SimpleFile;
/// Once the core linking is done (which resolves references, coalesces atoms
@@ -31,16 +28,16 @@ class SimpleFile;
/// new Atoms to the graph using the File's addAtom() method.
class Pass {
public:
- virtual ~Pass() { }
+ virtual ~Pass() = default;
/// Do the actual work of the Pass.
virtual llvm::Error perform(SimpleFile &mergedFile) = 0;
protected:
// Only subclassess can be instantiated.
- Pass() { }
+ Pass() = default;
};
-} // namespace lld
+} // end namespace lld
#endif // LLD_CORE_PASS_H
diff --git a/include/lld/Core/PassManager.h b/include/lld/Core/PassManager.h
index 71a25cc7f3cd..09b417a2985d 100644
--- a/include/lld/Core/PassManager.h
+++ b/include/lld/Core/PassManager.h
@@ -36,7 +36,7 @@ public:
for (std::unique_ptr<Pass> &pass : _passes)
if (llvm::Error EC = pass->perform(file))
return EC;
- return llvm::Error();
+ return llvm::Error::success();
}
private:
diff --git a/include/lld/Core/Reader.h b/include/lld/Core/Reader.h
index 66df4380dc76..5105eb1aa2be 100644
--- a/include/lld/Core/Reader.h
+++ b/include/lld/Core/Reader.h
@@ -12,9 +12,10 @@
#include "lld/Core/LLVM.h"
#include "lld/Core/Reference.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/YAMLTraits.h"
-#include <functional>
+#include "llvm/Support/MemoryBuffer.h"
#include <memory>
#include <vector>
@@ -23,10 +24,11 @@ using llvm::sys::fs::file_magic;
namespace llvm {
namespace yaml {
class IO;
-}
-}
+} // end namespace yaml
+} // end namespace llvm
namespace lld {
+
class File;
class LinkingContext;
class MachOLinkingContext;
@@ -37,7 +39,7 @@ class MachOLinkingContext;
/// Each file format (e.g. mach-o, etc) has a concrete subclass of Reader.
class Reader {
public:
- virtual ~Reader() {}
+ virtual ~Reader() = default;
/// Sniffs the file to determine if this Reader can parse it.
/// The method is called with:
@@ -52,7 +54,6 @@ public:
loadFile(std::unique_ptr<MemoryBuffer> mb, const class Registry &) const = 0;
};
-
/// \brief An abstract class for handling alternate yaml representations
/// of object files.
///
@@ -74,7 +75,6 @@ public:
virtual bool handledDocTag(llvm::yaml::IO &io, const lld::File *&f) const = 0;
};
-
/// A registry to hold the list of currently registered Readers and
/// tables which map Reference kind values to strings.
/// The linker does not directly invoke Readers. Instead, it registers
@@ -127,7 +127,6 @@ public:
void addKindTable(Reference::KindNamespace ns, Reference::KindArch arch,
const KindStrings array[]);
-
private:
struct KindEntry {
Reference::KindNamespace ns;
@@ -154,4 +153,4 @@ private:
} // end namespace lld
-#endif
+#endif // LLD_CORE_READER_H
diff --git a/include/lld/Core/Reference.h b/include/lld/Core/Reference.h
index 86de4f6a4236..1d3003c84616 100644
--- a/include/lld/Core/Reference.h
+++ b/include/lld/Core/Reference.h
@@ -1,4 +1,4 @@
-//===- Core/References.h - A Reference to Another Atom --------------------===//
+//===- Core/References.h - A Reference to Another Atom ----------*- C++ -*-===//
//
// The LLVM Linker
//
@@ -10,10 +10,10 @@
#ifndef LLD_CORE_REFERENCES_H
#define LLD_CORE_REFERENCES_H
-#include "lld/Core/LLVM.h"
-#include "llvm/ADT/StringSwitch.h"
+#include <cstdint>
namespace lld {
+
class Atom;
///
@@ -107,13 +107,13 @@ protected:
/// object. Therefore, no one but the owning File object should call
/// delete on an Reference. In fact, some File objects may bulk allocate
/// an array of References, so they cannot be individually deleted by anyone.
- virtual ~Reference() {}
+ virtual ~Reference() = default;
KindValue _kindValue;
uint8_t _kindNamespace;
uint8_t _kindArch;
};
-} // namespace lld
+} // end namespace lld
#endif // LLD_CORE_REFERENCES_H
diff --git a/include/lld/Core/Reproduce.h b/include/lld/Core/Reproduce.h
new file mode 100644
index 000000000000..cf2747493834
--- /dev/null
+++ b/include/lld/Core/Reproduce.h
@@ -0,0 +1,73 @@
+//===- Reproduce.h - Utilities for creating reproducers ---------*- C++ -*-===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_CORE_REPRODUCE_H
+#define LLD_CORE_REPRODUCE_H
+
+#include "lld/Core/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+
+class raw_fd_ostream;
+
+namespace opt { class Arg; }
+
+}
+
+namespace lld {
+
+// This class creates a .cpio file for --reproduce (ELF) or /linkrepro (COFF).
+//
+// If "--reproduce foo" is given, we create a file "foo.cpio" and
+// copy all input files to the archive, along with a response file
+// to re-run the same command with the same inputs.
+// It is useful for reporting issues to LLD developers.
+//
+// Cpio as a file format is a deliberate choice. It's standardized in
+// POSIX and very easy to create. cpio command is available virtually
+// on all Unix systems. See
+// http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_07
+// for the format details.
+class CpioFile {
+public:
+ static ErrorOr<CpioFile *> create(StringRef OutputPath);
+ void append(StringRef Path, StringRef Data);
+
+private:
+ CpioFile(std::unique_ptr<llvm::raw_fd_ostream> OS, StringRef Basename);
+
+ std::unique_ptr<llvm::raw_fd_ostream> OS;
+ llvm::StringSet<> Seen;
+ std::string Basename;
+};
+
+// Makes a given pathname an absolute path first, and then remove
+// beginning /. For example, "../foo.o" is converted to "home/john/foo.o",
+// assuming that the current directory is "/home/john/bar".
+std::string relativeToRoot(StringRef Path);
+
+// Quote a given string if it contains a space character.
+std::string quote(StringRef S);
+
+// Rewrite the given path if a file exists with that pathname, otherwise
+// returns the original path.
+std::string rewritePath(StringRef S);
+
+// Returns the string form of the given argument.
+std::string stringize(llvm::opt::Arg *Arg);
+
+// Replaces backslashes with slashes if Windows.
+std::string convertToUnixPathSeparator(StringRef S);
+}
+
+#endif
diff --git a/include/lld/Core/Simple.h b/include/lld/Core/Simple.h
index f75b40327db4..3aa7abf5d12b 100644
--- a/include/lld/Core/Simple.h
+++ b/include/lld/Core/Simple.h
@@ -25,6 +25,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
@@ -111,19 +112,17 @@ private:
AtomVector<AbsoluteAtom> _absolute;
};
-class SimpleReference : public Reference {
+class SimpleReference : public Reference,
+ public llvm::ilist_node<SimpleReference> {
public:
SimpleReference(Reference::KindNamespace ns, Reference::KindArch arch,
Reference::KindValue value, uint64_t off, const Atom *t,
Reference::Addend a)
- : Reference(ns, arch, value), _target(t), _offsetInAtom(off), _addend(a),
- _next(nullptr), _prev(nullptr) {
+ : Reference(ns, arch, value), _target(t), _offsetInAtom(off), _addend(a) {
}
SimpleReference()
: Reference(Reference::KindNamespace::all, Reference::KindArch::all, 0),
- _target(nullptr), _offsetInAtom(0), _addend(0), _next(nullptr),
- _prev(nullptr) {
- }
+ _target(nullptr), _offsetInAtom(0), _addend(0) {}
uint64_t offsetInAtom() const override { return _offsetInAtom; }
@@ -135,72 +134,17 @@ public:
Addend addend() const override { return _addend; }
void setAddend(Addend a) override { _addend = a; }
void setTarget(const Atom *newAtom) override { _target = newAtom; }
- SimpleReference *getNext() const { return _next; }
- SimpleReference *getPrev() const { return _prev; }
- void setNext(SimpleReference *n) { _next = n; }
- void setPrev(SimpleReference *p) { _prev = p; }
private:
const Atom *_target;
uint64_t _offsetInAtom;
Addend _addend;
- SimpleReference *_next;
- SimpleReference *_prev;
-};
-
-} // end namespace lld
-
-// ilist will lazily create a sentinal (so end() can return a node past the
-// end of the list). We need this trait so that the sentinal is allocated
-// via the BumpPtrAllocator.
-namespace llvm {
-
-template<>
-struct ilist_sentinel_traits<lld::SimpleReference> {
-
- ilist_sentinel_traits() : _allocator(nullptr) { }
-
- void setAllocator(llvm::BumpPtrAllocator *alloc) {
- _allocator = alloc;
- }
-
- lld::SimpleReference *createSentinel() const {
- return new (*_allocator) lld::SimpleReference();
- }
-
- static void destroySentinel(lld::SimpleReference*) {}
-
- static lld::SimpleReference *provideInitialHead() { return nullptr; }
-
- lld::SimpleReference *ensureHead(lld::SimpleReference *&head) const {
- if (!head) {
- head = createSentinel();
- noteHead(head, head);
- ilist_traits<lld::SimpleReference>::setNext(head, nullptr);
- return head;
- }
- return ilist_traits<lld::SimpleReference>::getPrev(head);
- }
-
- void noteHead(lld::SimpleReference *newHead,
- lld::SimpleReference *sentinel) const {
- ilist_traits<lld::SimpleReference>::setPrev(newHead, sentinel);
- }
-
-private:
- mutable llvm::BumpPtrAllocator *_allocator;
};
-} // end namespace llvm
-
-namespace lld {
-
class SimpleDefinedAtom : public DefinedAtom {
public:
explicit SimpleDefinedAtom(const File &f)
- : _file(f), _ordinal(f.getNextAtomOrdinalAndIncrement()) {
- _references.setAllocator(&f.allocator());
- }
+ : _file(f), _ordinal(f.getNextAtomOrdinalAndIncrement()) {}
~SimpleDefinedAtom() override {
_references.clearAndLeakNodesUnsafely();
@@ -232,23 +176,26 @@ public:
}
DefinedAtom::reference_iterator begin() const override {
- const void *it = reinterpret_cast<const void *>(&*_references.begin());
+ const void *it =
+ reinterpret_cast<const void *>(_references.begin().getNodePtr());
return reference_iterator(*this, it);
}
DefinedAtom::reference_iterator end() const override {
- const void *it = reinterpret_cast<const void *>(&*_references.end());
+ const void *it =
+ reinterpret_cast<const void *>(_references.end().getNodePtr());
return reference_iterator(*this, it);
}
const Reference *derefIterator(const void *it) const override {
- return reinterpret_cast<const Reference*>(it);
+ return &*RefList::const_iterator(
+ *reinterpret_cast<const llvm::ilist_node<SimpleReference> *>(it));
}
void incrementIterator(const void *&it) const override {
- const SimpleReference* node = reinterpret_cast<const SimpleReference*>(it);
- const SimpleReference* next = node->getNext();
- it = reinterpret_cast<const void*>(next);
+ RefList::const_iterator ref(
+ *reinterpret_cast<const llvm::ilist_node<SimpleReference> *>(it));
+ it = reinterpret_cast<const void *>(std::next(ref).getNodePtr());
}
void addReference(Reference::KindNamespace ns,
diff --git a/include/lld/Core/SymbolTable.h b/include/lld/Core/SymbolTable.h
index db610ad14066..ba4951e5bd13 100644
--- a/include/lld/Core/SymbolTable.h
+++ b/include/lld/Core/SymbolTable.h
@@ -46,22 +46,12 @@ public:
/// @brief add atom to symbol table
bool add(const AbsoluteAtom &);
- /// @brief checks if name is in symbol table and if so atom is not
- /// UndefinedAtom
- bool isDefined(StringRef sym);
-
/// @brief returns atom in symbol table for specified name (or nullptr)
const Atom *findByName(StringRef sym);
/// @brief returns vector of remaining UndefinedAtoms
std::vector<const UndefinedAtom *> undefines();
- /// returns vector of tentative definitions
- std::vector<StringRef> tentativeDefinitions();
-
- /// @brief add atom to replacement table
- void addReplacement(const Atom *replaced, const Atom *replacement);
-
/// @brief if atom has been coalesced away, return replacement, else return atom
const Atom *replacement(const Atom *);
diff --git a/include/lld/Driver/Driver.h b/include/lld/Driver/Driver.h
index 312f4f812b77..a3265c85716a 100644
--- a/include/lld/Driver/Driver.h
+++ b/include/lld/Driver/Driver.h
@@ -19,7 +19,7 @@ bool link(llvm::ArrayRef<const char *> Args);
}
namespace elf {
-bool link(llvm::ArrayRef<const char *> Args,
+bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly,
llvm::raw_ostream &Diag = llvm::errs());
}
diff --git a/include/lld/ReaderWriter/MachOLinkingContext.h b/include/lld/ReaderWriter/MachOLinkingContext.h
index 7b673f0dad3e..a9e80f50b23d 100644
--- a/include/lld/ReaderWriter/MachOLinkingContext.h
+++ b/include/lld/ReaderWriter/MachOLinkingContext.h
@@ -377,6 +377,10 @@ public:
uint32_t dylibCompatVersion(StringRef installName) const;
+ ArrayRef<mach_o::MachODylibFile*> allDylibs() const {
+ return _allDylibs;
+ }
+
/// Creates a copy (owned by this MachOLinkingContext) of a string.
StringRef copy(StringRef str) { return str.copy(_allocator); }
@@ -485,7 +489,7 @@ private:
mutable std::unique_ptr<Writer> _writer;
std::vector<SectionAlign> _sectAligns;
mutable llvm::StringMap<mach_o::MachODylibFile*> _pathToDylibMap;
- mutable std::set<mach_o::MachODylibFile*> _allDylibs;
+ mutable std::vector<mach_o::MachODylibFile*> _allDylibs;
mutable std::set<mach_o::MachODylibFile*> _upwardDylibs;
mutable std::vector<std::unique_ptr<File>> _indirectDylibs;
mutable std::mutex _dylibsMutex;
diff --git a/include/lld/Support/Memory.h b/include/lld/Support/Memory.h
new file mode 100644
index 000000000000..46db4a39f696
--- /dev/null
+++ b/include/lld/Support/Memory.h
@@ -0,0 +1,63 @@
+//===- Memory.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines arena allocators.
+//
+// Almost all large objects, such as files, sections or symbols, are
+// used for the entire lifetime of the linker once they are created.
+// This usage characteristic makes arena allocator an attractive choice
+// where the entire linker is one arena. With an arena, newly created
+// objects belong to the arena and freed all at once when everything is done.
+// Arena allocators are efficient and easy to understand.
+// Most objects are allocated using the arena allocators defined by this file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_MEMORY_H
+#define LLD_MEMORY_H
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/StringSaver.h"
+#include <vector>
+
+namespace lld {
+
+// Use this arena if your object doesn't have a destructor.
+extern llvm::BumpPtrAllocator BAlloc;
+extern llvm::StringSaver Saver;
+
+// These two classes are hack to keep track of all
+// SpecificBumpPtrAllocator instances.
+struct SpecificAllocBase {
+ SpecificAllocBase() { Instances.push_back(this); }
+ virtual ~SpecificAllocBase() = default;
+ virtual void reset() = 0;
+ static std::vector<SpecificAllocBase *> Instances;
+};
+
+template <class T> struct SpecificAlloc : public SpecificAllocBase {
+ void reset() override { Alloc.DestroyAll(); }
+ llvm::SpecificBumpPtrAllocator<T> Alloc;
+};
+
+// Use this arena if your object has a destructor.
+// Your destructor will be invoked from freeArena().
+template <typename T, typename... U> inline T *make(U &&... Args) {
+ static SpecificAlloc<T> Alloc;
+ return new (Alloc.Alloc.Allocate()) T(std::forward<U>(Args)...);
+}
+
+inline void freeArena() {
+ for (SpecificAllocBase *Alloc : SpecificAllocBase::Instances)
+ Alloc->reset();
+ BAlloc.Reset();
+}
+}
+
+#endif