diff options
Diffstat (limited to 'include/llvm/MC/MCSymbol.h')
-rw-r--r-- | include/llvm/MC/MCSymbol.h | 69 |
1 files changed, 59 insertions, 10 deletions
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index 078f3d77e55c..0acf6e50ba48 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -17,7 +17,6 @@ #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringMap.h" #include "llvm/MC/MCAssembler.h" -#include "llvm/MC/MCExpr.h" #include "llvm/Support/Compiler.h" namespace llvm { @@ -52,10 +51,6 @@ protected: // FIXME: Use a PointerInt wrapper for this? static MCSection *AbsolutePseudoSection; - /// Name - The name of the symbol. The referred-to string data is actually - /// held by the StringMap that lives in MCContext. - const StringMapEntry<bool> *Name; - /// If a symbol has a Fragment, the section is implied, so we only need /// one pointer. /// FIXME: We might be able to simplify this by having the asm streamer create @@ -91,10 +86,18 @@ protected: /// This symbol is private extern. mutable unsigned IsPrivateExtern : 1; + /// True if this symbol is named. + /// A named symbol will have a pointer to the name allocated in the bytes + /// immediately prior to the MCSymbol. + unsigned HasName : 1; + /// LLVM RTTI discriminator. This is actually a SymbolKind enumerator, but is /// unsigned to avoid sign extension and achieve better bitpacking with MSVC. unsigned Kind : 2; + /// True if we have created a relocation that uses this symbol. + mutable unsigned IsUsedInReloc : 1; + /// Index field, for use by the object file implementation. mutable uint32_t Index = 0; @@ -118,15 +121,43 @@ protected: protected: // MCContext creates and uniques these. friend class MCExpr; friend class MCContext; + + /// \brief The name for a symbol. + /// MCSymbol contains a uint64_t so is probably aligned to 8. On a 32-bit + /// system, the name is a pointer so isn't going to satisfy the 8 byte + /// alignment of uint64_t. Account for that here. + typedef union { + const StringMapEntry<bool> *NameEntry; + uint64_t AlignmentPadding; + } NameEntryStorageTy; + MCSymbol(SymbolKind Kind, const StringMapEntry<bool> *Name, bool isTemporary) - : Name(Name), Value(nullptr), IsTemporary(isTemporary), - IsRedefinable(false), IsUsed(false), IsRegistered(false), - IsExternal(false), IsPrivateExtern(false), - Kind(Kind) { + : Value(nullptr), IsTemporary(isTemporary), IsRedefinable(false), + IsUsed(false), IsRegistered(false), IsExternal(false), + IsPrivateExtern(false), HasName(!!Name), Kind(Kind), + IsUsedInReloc(false) { Offset = 0; + if (Name) + getNameEntryPtr() = Name; } + // Provide custom new/delete as we will only allocate space for a name + // if we need one. + void *operator new(size_t s, const StringMapEntry<bool> *Name, + MCContext &Ctx); + private: + + void operator delete(void *); + /// \brief Placement delete - required by std, but never called. + void operator delete(void*, unsigned) { + llvm_unreachable("Constructor throws?"); + } + /// \brief Placement delete - required by std, but never called. + void operator delete(void*, unsigned, bool) { + llvm_unreachable("Constructor throws?"); + } + MCSymbol(const MCSymbol &) = delete; void operator=(const MCSymbol &) = delete; MCSection *getSectionPtr() const { @@ -139,13 +170,31 @@ private: return Section = Value->findAssociatedSection(); } + /// \brief Get a reference to the name field. Requires that we have a name + const StringMapEntry<bool> *&getNameEntryPtr() { + assert(HasName && "Name is required"); + NameEntryStorageTy *Name = reinterpret_cast<NameEntryStorageTy *>(this); + return (*(Name - 1)).NameEntry; + } + const StringMapEntry<bool> *&getNameEntryPtr() const { + return const_cast<MCSymbol*>(this)->getNameEntryPtr(); + } + public: /// getName - Get the symbol name. - StringRef getName() const { return Name ? Name->first() : ""; } + StringRef getName() const { + if (!HasName) + return StringRef(); + + return getNameEntryPtr()->first(); + } bool isRegistered() const { return IsRegistered; } void setIsRegistered(bool Value) const { IsRegistered = Value; } + void setUsedInReloc() const { IsUsedInReloc = true; } + bool isUsedInReloc() const { return IsUsedInReloc; } + /// \name Accessors /// @{ |