diff options
-rw-r--r-- | lld/include/lld/Core/AbsoluteAtom.h | 18 | ||||
-rw-r--r-- | lld/include/lld/Core/Atom.h | 27 | ||||
-rw-r--r-- | lld/include/lld/Core/DefinedAtom.h | 15 | ||||
-rw-r--r-- | lld/include/lld/Core/SharedLibraryAtom.h | 17 | ||||
-rw-r--r-- | lld/include/lld/Core/UndefinedAtom.h | 16 | ||||
-rw-r--r-- | lld/lib/Core/Resolver.cpp | 32 | ||||
-rw-r--r-- | lld/lib/Core/SymbolTable.cpp | 13 | ||||
-rw-r--r-- | lld/lib/Passes/GOTPass.cpp | 3 | ||||
-rw-r--r-- | lld/lib/Passes/StubsPass.cpp | 5 |
9 files changed, 58 insertions, 88 deletions
diff --git a/lld/include/lld/Core/AbsoluteAtom.h b/lld/include/lld/Core/AbsoluteAtom.h index 5fa71764852..6496c41f14f 100644 --- a/lld/include/lld/Core/AbsoluteAtom.h +++ b/lld/include/lld/Core/AbsoluteAtom.h @@ -18,21 +18,15 @@ namespace lld { /// It exists to represent content at fixed addresses in memory. class AbsoluteAtom : public Atom { public: - virtual Definition definition() const { - return Atom::definitionAbsolute; - } - - /// like dynamic_cast, if atom is definitionAbsolute - /// returns atom cast to AbsoluteAtom*, else returns nullptr - virtual const AbsoluteAtom* absoluteAtom() const { - return this; - } - virtual uint64_t value() const = 0; - + static inline bool classof(const Atom *a) { + return a->definition() == definitionAbsolute; + } + static inline bool classof(const AbsoluteAtom *) { return true; } + protected: - AbsoluteAtom() {} + AbsoluteAtom() : Atom(definitionAbsolute) {} virtual ~AbsoluteAtom() {} }; diff --git a/lld/include/lld/Core/Atom.h b/lld/include/lld/Core/Atom.h index e1009d85d1b..62927c138b3 100644 --- a/lld/include/lld/Core/Atom.h +++ b/lld/include/lld/Core/Atom.h @@ -21,10 +21,6 @@ namespace llvm { namespace lld { class File; -class DefinedAtom; -class UndefinedAtom; -class SharedLibraryAtom; -class AbsoluteAtom; /// /// The linker has a Graph Theory model of linking. An object file is seen @@ -52,33 +48,22 @@ public: /// definition - Whether this atom is a definition or represents an undefined /// symbol. - virtual Definition definition() const = 0; - - /// definedAtom - like dynamic_cast, if atom is definitionRegular - /// returns atom cast to DefinedAtom*, else returns nullptr; - virtual const DefinedAtom* definedAtom() const { return nullptr; } + Definition definition() const { return _definition; }; - /// undefinedAtom - like dynamic_cast, if atom is definitionUndefined - /// returns atom cast to UndefinedAtom*, else returns nullptr; - virtual const UndefinedAtom* undefinedAtom() const { return nullptr; } - - /// sharedLibraryAtom - like dynamic_cast, if atom is definitionSharedLibrary - /// returns atom cast to SharedLibraryAtom*, else returns nullptr; - virtual const SharedLibraryAtom* sharedLibraryAtom() const { return nullptr; } - - /// absoluteAtom - like dynamic_cast, if atom is definitionAbsolute - /// returns atom cast to AbsoluteAtom*, else returns nullptr; - virtual const AbsoluteAtom* absoluteAtom() const { return nullptr; } + static inline bool classof(const Atom *a) { return true; } protected: /// Atom is an abstract base class. Only subclasses can access constructor. - Atom() {} + Atom(Definition def) : _definition(def) {} /// The memory for Atom objects is always managed by the owning File /// 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() {} + +private: + Definition _definition; }; } // namespace lld diff --git a/lld/include/lld/Core/DefinedAtom.h b/lld/include/lld/Core/DefinedAtom.h index 9bdc208d759..8d633016fbf 100644 --- a/lld/include/lld/Core/DefinedAtom.h +++ b/lld/include/lld/Core/DefinedAtom.h @@ -88,15 +88,6 @@ class File; /// class DefinedAtom : public Atom { public: - /// Whether this atom is defined or a proxy for an undefined symbol - virtual Definition definition() const { - return Atom::definitionRegular; - } - - virtual const DefinedAtom* definedAtom() const { - return this; - } - /// The scope in which this atom is acessible to other atoms. enum Scope { scopeTranslationUnit, ///< Accessible only to atoms in the same translation @@ -293,11 +284,15 @@ public: /// Returns an iterator to the end of this Atom's References virtual reference_iterator referencesEnd() const = 0; + static inline bool classof(const Atom *a) { + return a->definition() == definitionRegular; + } + static inline bool classof(const DefinedAtom *) { return true; } protected: /// DefinedAtom is an abstract base class. /// Only subclasses can access constructor. - DefinedAtom() { } + DefinedAtom() : Atom(definitionRegular) { } /// The memory for DefinedAtom objects is always managed by the owning File /// object. Therefore, no one but the owning File object should call diff --git a/lld/include/lld/Core/SharedLibraryAtom.h b/lld/include/lld/Core/SharedLibraryAtom.h index 62381f31314..9e8f219ca56 100644 --- a/lld/include/lld/Core/SharedLibraryAtom.h +++ b/lld/include/lld/Core/SharedLibraryAtom.h @@ -22,16 +22,6 @@ namespace lld { /// It exists to represent a symbol which will be bound at runtime. class SharedLibraryAtom : public Atom { public: - virtual Definition definition() const { - return Atom::definitionSharedLibrary; - } - - /// like dynamic_cast, if atom is definitionSharedLibrary - /// returns atom cast to SharedLibraryAtom*, else returns nullptr - virtual const SharedLibraryAtom* sharedLibraryAtom() const { - return this; - } - /// Returns shared library name used to load it at runtime. /// On linux that is the DT_NEEDED name. /// On Darwin it is the LC_DYLIB_LOAD dylib name. @@ -40,9 +30,14 @@ public: /// Returns if shared library symbol can be missing at runtime and if /// so the loader should silently resolve address of symbol to be nullptr. virtual bool canBeNullAtRuntime() const = 0; + + static inline bool classof(const Atom *a) { + return a->definition() == definitionSharedLibrary; + } + static inline bool classof(const SharedLibraryAtom *) { return true; } protected: - SharedLibraryAtom() {} + SharedLibraryAtom() : Atom(definitionSharedLibrary) {} virtual ~SharedLibraryAtom() {} }; diff --git a/lld/include/lld/Core/UndefinedAtom.h b/lld/include/lld/Core/UndefinedAtom.h index 933b205a18c..6b6a778f14b 100644 --- a/lld/include/lld/Core/UndefinedAtom.h +++ b/lld/include/lld/Core/UndefinedAtom.h @@ -18,16 +18,6 @@ namespace lld { /// It exists as a place holder for a future atom. class UndefinedAtom : public Atom { public: - virtual Definition definition() const { - return Atom::definitionUndefined; - } - - /// like dynamic_cast, if atom is definitionUndefined - /// returns atom cast to UndefinedAtom*, else returns nullptr - virtual const UndefinedAtom* undefinedAtom() const { - return this; - } - /// Whether this undefined symbol needs to be resolved, /// or whether it can just evaluate to nullptr. /// This concept is often called "weak", but that term @@ -61,9 +51,13 @@ public: virtual CanBeNull canBeNull() const = 0; + static inline bool classof(const Atom *a) { + return a->definition() == definitionUndefined; + } + static inline bool classof(const UndefinedAtom *) { return true; } protected: - UndefinedAtom() {} + UndefinedAtom() : Atom(definitionUndefined) {} virtual ~UndefinedAtom() {} }; diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp index 13541840736..cbef66f6597 100644 --- a/lld/lib/Core/Resolver.cpp +++ b/lld/lib/Core/Resolver.cpp @@ -15,6 +15,7 @@ #include "lld/Core/SymbolTable.h" #include "lld/Core/UndefinedAtom.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> @@ -33,7 +34,7 @@ public: if ( _liveAtoms.count(atom) ) return false; // don't remove if marked never-dead-strip - if ( const DefinedAtom* defAtom = atom->definedAtom() ) { + if (const DefinedAtom* defAtom = llvm::dyn_cast<DefinedAtom>(atom)) { if ( defAtom->deadStrip() == DefinedAtom::deadStripNever ) return false; } @@ -194,7 +195,7 @@ void Resolver::resolveUndefines() { std::vector<const Atom *> tents; for (std::vector<const Atom *>::iterator ait = _atoms.begin(); ait != _atoms.end(); ++ait) { - if ( const DefinedAtom* defAtom = (*ait)->definedAtom() ) { + if (const DefinedAtom* defAtom = llvm::dyn_cast<DefinedAtom>(*ait)) { if ( defAtom->merge() == DefinedAtom::mergeAsTentative ) tents.push_back(defAtom); } @@ -206,7 +207,8 @@ void Resolver::resolveUndefines() { llvm::StringRef tentName = (*dit)->name(); const Atom *curAtom = _symbolTable.findByName(tentName); assert(curAtom != nullptr); - if ( const DefinedAtom* curDefAtom = curAtom->definedAtom() ) { + if (const DefinedAtom* curDefAtom = + llvm::dyn_cast<DefinedAtom>(curAtom)) { if (curDefAtom->merge() == DefinedAtom::mergeAsTentative ) _inputFiles.searchLibraries(tentName, searchDylibs, true, true, *this); @@ -221,7 +223,7 @@ void Resolver::resolveUndefines() { // to the new defined atom void Resolver::updateReferences() { for (auto ait = _atoms.begin(); ait != _atoms.end(); ++ait) { - if ( const DefinedAtom* defAtom = (*ait)->definedAtom() ) { + if (const DefinedAtom* defAtom = llvm::dyn_cast<DefinedAtom>(*ait)) { for (auto rit=defAtom->referencesBegin(), end=defAtom->referencesEnd(); rit != end; ++rit) { const Reference* ref = *rit; @@ -259,7 +261,7 @@ void Resolver::markLive(const Atom &atom, WhyLiveBackChain *previous) { WhyLiveBackChain thisChain; thisChain.previous = previous; thisChain.referer = &atom; - if ( const DefinedAtom* defAtom = atom.definedAtom() ) { + if ( const DefinedAtom* defAtom = llvm::dyn_cast<DefinedAtom>(&atom)) { for (auto rit=defAtom->referencesBegin(), end=defAtom->referencesEnd(); rit != end; ++rit) { const Reference* ref = *rit; @@ -342,7 +344,7 @@ void Resolver::removeCoalescedAwayAtoms() { void Resolver::checkDylibSymbolCollisions() { for (std::vector<const Atom *>::const_iterator it = _atoms.begin(); it != _atoms.end(); ++it) { - const DefinedAtom* defAtom = (*it)->definedAtom(); + const DefinedAtom* defAtom = llvm::dyn_cast<DefinedAtom>(*it); if (defAtom == nullptr) continue; if ( defAtom->merge() != DefinedAtom::mergeAsTentative ) @@ -389,25 +391,23 @@ void Resolver::resolve() { } void Resolver::MergedFile::addAtom(const Atom& atom) { - if ( const DefinedAtom* defAtom = atom.definedAtom() ) { + if (const DefinedAtom* defAtom = llvm::dyn_cast<DefinedAtom>(&atom)) { _definedAtoms._atoms.push_back(defAtom); - } - else if ( const UndefinedAtom* undefAtom = atom.undefinedAtom() ) { + } else if (const UndefinedAtom* undefAtom = + llvm::dyn_cast<UndefinedAtom>(&atom)) { _undefinedAtoms._atoms.push_back(undefAtom); - } - else if ( const SharedLibraryAtom* slAtom = atom.sharedLibraryAtom() ) { + } else if (const SharedLibraryAtom* slAtom = + llvm::dyn_cast<SharedLibraryAtom>(&atom)) { _sharedLibraryAtoms._atoms.push_back(slAtom); - } - else if ( const AbsoluteAtom* abAtom = atom.absoluteAtom() ) { + } else if (const AbsoluteAtom* abAtom = llvm::dyn_cast<AbsoluteAtom>(&atom)) { _absoluteAtoms._atoms.push_back(abAtom); - } - else { + } else { assert(0 && "atom has unknown definition kind"); } } void Resolver::MergedFile::addAtoms(std::vector<const Atom*>& all) { - for(std::vector<const Atom*>::iterator it=all.begin(); it != all.end(); ++it) { + for(std::vector<const Atom*>::iterator it=all.begin(); it != all.end(); ++it){ this->addAtom(**it); } } diff --git a/lld/lib/Core/SymbolTable.cpp b/lld/lib/Core/SymbolTable.cpp index 277ce3b60e7..b748e00b671 100644 --- a/lld/lib/Core/SymbolTable.cpp +++ b/lld/lib/Core/SymbolTable.cpp @@ -20,6 +20,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMapInfo.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include <algorithm> @@ -160,8 +161,10 @@ void SymbolTable::addByName(const Atom & newAtom) { } break; case NCR_DupUndef: { - const UndefinedAtom* existingUndef = existing->undefinedAtom(); - const UndefinedAtom* newUndef = newAtom.undefinedAtom(); + const UndefinedAtom* existingUndef = + llvm::dyn_cast<UndefinedAtom>(existing); + const UndefinedAtom* newUndef = + llvm::dyn_cast<UndefinedAtom>(&newAtom); assert(existingUndef != nullptr); assert(newUndef != nullptr); if ( existingUndef->canBeNull() == newUndef->canBeNull() ) { @@ -176,8 +179,10 @@ void SymbolTable::addByName(const Atom & newAtom) { } break; case NCR_DupShLib: { - const SharedLibraryAtom* existingShLib = existing->sharedLibraryAtom(); - const SharedLibraryAtom* newShLib = newAtom.sharedLibraryAtom(); + const SharedLibraryAtom* existingShLib = + llvm::dyn_cast<SharedLibraryAtom>(existing); + const SharedLibraryAtom* newShLib = + llvm::dyn_cast<SharedLibraryAtom>(&newAtom); assert(existingShLib != nullptr); assert(newShLib != nullptr); if ( (existingShLib->canBeNullAtRuntime() diff --git a/lld/lib/Passes/GOTPass.cpp b/lld/lib/Passes/GOTPass.cpp index 0d92a1e1d1f..29cd38b9c08 100644 --- a/lld/lib/Passes/GOTPass.cpp +++ b/lld/lib/Passes/GOTPass.cpp @@ -38,6 +38,7 @@ #include "lld/Core/Reference.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Casting.h" namespace lld { @@ -57,7 +58,7 @@ void GOTPass::perform() { if ( _platform.isGOTAccess(ref->kind(), canBypassGOT) ) { const Atom* target = ref->target(); assert(target != nullptr); - const DefinedAtom* defTarget = target->definedAtom(); + const DefinedAtom* defTarget = llvm::dyn_cast<DefinedAtom>(target); bool replaceTargetWithGOTAtom = false; if ( target->definition() == Atom::definitionSharedLibrary ) { // Accesses to shared library symbols must go through GOT. diff --git a/lld/lib/Passes/StubsPass.cpp b/lld/lib/Passes/StubsPass.cpp index 32d906d5d50..9b9b6e042e8 100644 --- a/lld/lib/Passes/StubsPass.cpp +++ b/lld/lib/Passes/StubsPass.cpp @@ -21,6 +21,7 @@ #include "lld/Core/Reference.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Casting.h" namespace lld { @@ -47,8 +48,8 @@ void StubsPass::perform() { if ( target->definition() == Atom::definitionSharedLibrary ) { // Calls to shared libraries go through stubs. replaceCalleeWithStub = true; - } - else if ( const DefinedAtom* defTarget = target->definedAtom() ) { + } else if (const DefinedAtom* defTarget = + llvm::dyn_cast<DefinedAtom>(target)) { if ( defTarget->interposable() != DefinedAtom::interposeNo ) { // Calls to interposable functions in same linkage unit // must also go through a stub. |