summaryrefslogtreecommitdiff
path: root/include/lld/Core/File.h
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:48:50 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:48:50 +0000
commit1c98619801a5705c688e683be3ef9d70169a0686 (patch)
tree8422105cd1a94c368315f2db16b9ac746cf7c000 /include/lld/Core/File.h
parentf4f3ce4613680903220815690ad79fc7ba0a2e26 (diff)
Notes
Diffstat (limited to 'include/lld/Core/File.h')
-rw-r--r--include/lld/Core/File.h120
1 files changed, 91 insertions, 29 deletions
diff --git a/include/lld/Core/File.h b/include/lld/Core/File.h
index 494e50065340b..20418688dfa0b 100644
--- a/include/lld/Core/File.h
+++ b/include/lld/Core/File.h
@@ -14,8 +14,8 @@
#include "lld/Core/DefinedAtom.h"
#include "lld/Core/SharedLibraryAtom.h"
#include "lld/Core/UndefinedAtom.h"
-#include "lld/Core/range.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
#include <functional>
@@ -45,9 +45,18 @@ public:
/// \brief Kinds of files that are supported.
enum Kind {
- kindObject, ///< object file (.o)
- kindSharedLibrary, ///< shared library (.so)
- kindArchiveLibrary ///< archive (.a)
+ kindErrorObject, ///< a error object file (.o)
+ kindNormalizedObject, ///< a normalized file (.o)
+ kindMachObject, ///< a MachO object file (.o)
+ kindCEntryObject, ///< a file for CEntries
+ kindHeaderObject, ///< a file for file headers
+ kindEntryObject, ///< a file for the entry
+ kindUndefinedSymsObject, ///< a file for undefined symbols
+ kindStubHelperObject, ///< a file for stub helpers
+ kindResolverMergedObject, ///< the resolver merged file.
+ kindSectCreateObject, ///< a sect create object file (.o)
+ kindSharedLibrary, ///< shared library (.so)
+ kindArchiveLibrary ///< archive (.a)
};
/// \brief Returns file kind. Need for dyn_cast<> on File objects.
@@ -97,17 +106,69 @@ public:
}
/// The type of atom mutable container.
- template <typename T> using AtomVector = std::vector<const T *>;
+ template <typename T> using AtomVector = std::vector<OwningAtomPtr<T>>;
- /// The range type for the atoms. It's backed by a std::vector, but hides
- /// its member functions so that you can only call begin or end.
+ /// The range type for the atoms.
template <typename T> class AtomRange {
public:
- AtomRange(AtomVector<T> v) : _v(v) {}
- typename AtomVector<T>::const_iterator begin() const { return _v.begin(); }
- typename AtomVector<T>::const_iterator end() const { return _v.end(); }
- typename AtomVector<T>::iterator begin() { return _v.begin(); }
- typename AtomVector<T>::iterator end() { return _v.end(); }
+ AtomRange(AtomVector<T> &v) : _v(v) {}
+ AtomRange(const AtomVector<T> &v) : _v(const_cast<AtomVector<T> &>(v)) {}
+
+ typedef std::pointer_to_unary_function<const OwningAtomPtr<T>&,
+ const T*> ConstDerefFn;
+
+ typedef std::pointer_to_unary_function<OwningAtomPtr<T>&, T*> DerefFn;
+
+ typedef llvm::mapped_iterator<typename AtomVector<T>::const_iterator,
+ ConstDerefFn> ConstItTy;
+ typedef llvm::mapped_iterator<typename AtomVector<T>::iterator,
+ DerefFn> ItTy;
+
+ static const T* DerefConst(const OwningAtomPtr<T> &p) {
+ return p.get();
+ }
+
+ static T* Deref(OwningAtomPtr<T> &p) {
+ return p.get();
+ }
+
+ ConstItTy begin() const {
+ return ConstItTy(_v.begin(), ConstDerefFn(DerefConst));
+ }
+ ConstItTy end() const {
+ return ConstItTy(_v.end(), ConstDerefFn(DerefConst));
+ }
+
+ ItTy begin() {
+ return ItTy(_v.begin(), DerefFn(Deref));
+ }
+ ItTy end() {
+ return ItTy(_v.end(), DerefFn(Deref));
+ }
+
+ llvm::iterator_range<typename AtomVector<T>::iterator> owning_ptrs() {
+ return llvm::make_range(_v.begin(), _v.end());
+ }
+
+ llvm::iterator_range<typename AtomVector<T>::iterator> owning_ptrs() const {
+ return llvm::make_range(_v.begin(), _v.end());
+ }
+
+ bool empty() const {
+ return _v.empty();
+ }
+
+ size_t size() const {
+ return _v.size();
+ }
+
+ const OwningAtomPtr<T> &operator[](size_t idx) const {
+ return _v[idx];
+ }
+
+ OwningAtomPtr<T> &operator[](size_t idx) {
+ return _v[idx];
+ }
private:
AtomVector<T> &_v;
@@ -115,19 +176,25 @@ public:
/// \brief Must be implemented to return the AtomVector object for
/// all DefinedAtoms in this File.
- virtual const AtomVector<DefinedAtom> &defined() const = 0;
+ virtual const AtomRange<DefinedAtom> defined() const = 0;
/// \brief Must be implemented to return the AtomVector object for
/// all UndefinedAtomw in this File.
- virtual const AtomVector<UndefinedAtom> &undefined() const = 0;
+ virtual const AtomRange<UndefinedAtom> undefined() const = 0;
/// \brief Must be implemented to return the AtomVector object for
/// all SharedLibraryAtoms in this File.
- virtual const AtomVector<SharedLibraryAtom> &sharedLibrary() const = 0;
+ virtual const AtomRange<SharedLibraryAtom> sharedLibrary() const = 0;
/// \brief Must be implemented to return the AtomVector object for
/// all AbsoluteAtoms in this File.
- virtual const AtomVector<AbsoluteAtom> &absolute() const = 0;
+ virtual const AtomRange<AbsoluteAtom> absolute() const = 0;
+
+ /// Drop all of the atoms owned by this file. This will result in all of
+ /// the atoms running their destructors.
+ /// This is required because atoms may be allocated on a BumpPtrAllocator
+ /// of a different file. We need to destruct all atoms before any files.
+ virtual void clearAtoms() = 0;
/// \brief If a file is parsed using a different method than doParse(),
/// one must use this method to set the last error status, so that
@@ -137,14 +204,6 @@ public:
std::error_code parse();
- // This function is called just before the core linker tries to use
- // a file. Currently the PECOFF reader uses this to trigger the
- // driver to parse .drectve section (which contains command line options).
- // If you want to do something having side effects, don't do that in
- // doParse() because a file could be pre-loaded speculatively.
- // Use this hook instead.
- virtual void beforeLink() {}
-
// Usually each file owns a std::unique_ptr<MemoryBuffer>.
// However, there's one special case. If a file is an archive file,
// the archive file and its children all shares the same memory buffer.
@@ -190,23 +249,26 @@ private:
class ErrorFile : public File {
public:
ErrorFile(StringRef path, std::error_code ec)
- : File(path, kindObject), _ec(ec) {}
+ : File(path, kindErrorObject), _ec(ec) {}
std::error_code doParse() override { return _ec; }
- const AtomVector<DefinedAtom> &defined() const override {
+ const AtomRange<DefinedAtom> defined() const override {
llvm_unreachable("internal error");
}
- const AtomVector<UndefinedAtom> &undefined() const override {
+ const AtomRange<UndefinedAtom> undefined() const override {
llvm_unreachable("internal error");
}
- const AtomVector<SharedLibraryAtom> &sharedLibrary() const override {
+ const AtomRange<SharedLibraryAtom> sharedLibrary() const override {
llvm_unreachable("internal error");
}
- const AtomVector<AbsoluteAtom> &absolute() const override {
+ const AtomRange<AbsoluteAtom> absolute() const override {
llvm_unreachable("internal error");
}
+ void clearAtoms() override {
+ }
+
private:
std::error_code _ec;
};