X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FMC%2FMCSymbol.h;h=078f3d77e55cd04ca19074e164bf68610677dee3;hb=d99ce2f6305eb090d47188bb041c960413fc3aa1;hp=137251b63564b9da66ef4e54c61d2a006c0aa34e;hpb=f7e0685b9ae2114fae77d0acc0d6fac92c8d9ee4;p=oota-llvm.git diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index 137251b6356..078f3d77e55 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -14,12 +14,14 @@ #ifndef LLVM_MC_MCSYMBOL_H #define LLVM_MC_MCSYMBOL_H +#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 { +class MCAsmInfo; class MCExpr; class MCSymbol; class MCFragment; @@ -35,6 +37,16 @@ class raw_ostream; /// Section member is set to indicate what section it lives in. Otherwise, if /// it is a reference to an external entity, it has a null section. class MCSymbol { +protected: + /// The kind of the symbol. If it is any value other than unset then this + /// class is actually one of the appropriate subclasses of MCSymbol. + enum SymbolKind { + SymbolKindUnset, + SymbolKindCOFF, + SymbolKindELF, + SymbolKindMachO, + }; + // Special sentinal value for the absolute pseudo section. // // FIXME: Use a PointerInt wrapper for this? @@ -48,16 +60,14 @@ class MCSymbol { /// one pointer. /// FIXME: We might be able to simplify this by having the asm streamer create /// dummy fragments. - union { - /// The section the symbol is defined in. This is null for undefined - /// symbols, and the special AbsolutePseudoSection value for absolute - /// symbols. If this is a variable symbol, this caches the variable value's - /// section. - mutable MCSection *Section; - - /// The fragment this symbol's value is relative to, if any. - mutable MCFragment *Fragment; - }; + /// If this is a section, then it gives the symbol is defined in. This is null + /// for undefined symbols, and the special AbsolutePseudoSection value for + /// absolute symbols. If this is a variable symbol, this caches the variable + /// value's section. + /// + /// If this is a fragment, then it gives the fragment this symbol's value is + /// relative to, if any. + mutable PointerUnion SectionOrFragment; /// Value - If non-null, the value for a variable symbol. const MCExpr *Value; @@ -81,9 +91,9 @@ class MCSymbol { /// This symbol is private extern. mutable unsigned IsPrivateExtern : 1; - mutable unsigned HasFragment : 1; - - unsigned IsELF : 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; /// Index field, for use by the object file implementation. mutable uint32_t Index = 0; @@ -108,11 +118,11 @@ class MCSymbol { protected: // MCContext creates and uniques these. friend class MCExpr; friend class MCContext; - MCSymbol(bool IsELF, const StringMapEntry *Name, bool isTemporary) - : Name(Name), Section(nullptr), Value(nullptr), IsTemporary(isTemporary), + MCSymbol(SymbolKind Kind, const StringMapEntry *Name, bool isTemporary) + : Name(Name), Value(nullptr), IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false), IsRegistered(false), - IsExternal(false), IsPrivateExtern(false), HasFragment(false), - IsELF(IsELF) { + IsExternal(false), IsPrivateExtern(false), + Kind(Kind) { Offset = 0; } @@ -122,7 +132,8 @@ private: MCSection *getSectionPtr() const { if (MCFragment *F = getFragment()) return F->getParent(); - assert(!HasFragment); + assert(!SectionOrFragment.is() && "Section or null expected"); + MCSection *Section = SectionOrFragment.dyn_cast(); if (Section || !Value) return Section; return Section = Value->findAssociatedSection(); @@ -153,8 +164,7 @@ public: void redefineIfPossible() { if (IsRedefinable) { Value = nullptr; - Section = nullptr; - HasFragment = false; + SectionOrFragment = nullptr; IsRedefinable = false; } } @@ -187,17 +197,20 @@ public: /// Mark the symbol as defined in the section \p S. void setSection(MCSection &S) { assert(!isVariable() && "Cannot set section of variable"); - assert(!HasFragment); - Section = &S; + assert(!SectionOrFragment.is() && "Section or null expected"); + SectionOrFragment = &S; } /// Mark the symbol as undefined. void setUndefined() { - HasFragment = false; - Section = nullptr; + SectionOrFragment = nullptr; } - bool isELF() const { return IsELF; } + bool isELF() const { return Kind == SymbolKindELF; } + + bool isCOFF() const { return Kind == SymbolKindCOFF; } + + bool isMachO() const { return Kind == SymbolKindMachO; } /// @} /// \name Variable Symbols @@ -258,28 +271,29 @@ public: return CommonAlign; } + /// Declare this symbol as being 'common'. + /// + /// \param Size - The size of the symbol. + /// \param Align - The alignment of the symbol. + /// \return True if symbol was already declared as a different type + bool declareCommon(uint64_t Size, unsigned Align) { + assert(isCommon() || getOffset() == 0); + if(isCommon()) { + if(CommonSize != Size || CommonAlign != Align) + return true; + } else + setCommon(Size, Align); + return false; + } + /// Is this a 'common' symbol. bool isCommon() const { return CommonAlign != -1U; } - /// Get the (implementation defined) symbol flags. - uint32_t getFlags() const { return Flags; } - - /// Set the (implementation defined) symbol flags. - void setFlags(uint32_t Value) const { Flags = Value; } - - /// Modify the flags via a mask - void modifyFlags(uint32_t Value, uint32_t Mask) const { - Flags = (Flags & ~Mask) | Value; - } - MCFragment *getFragment() const { - if (!HasFragment) - return nullptr; - return Fragment; + return SectionOrFragment.dyn_cast(); } void setFragment(MCFragment *Value) const { - HasFragment = true; - Fragment = Value; + SectionOrFragment = Value; } bool isExternal() const { return IsExternal; } @@ -289,14 +303,26 @@ public: void setPrivateExtern(bool Value) { IsPrivateExtern = Value; } /// print - Print the value to the stream \p OS. - void print(raw_ostream &OS) const; + void print(raw_ostream &OS, const MCAsmInfo *MAI) const; /// dump - Print the value to stderr. void dump() const; + +protected: + /// Get the (implementation defined) symbol flags. + uint32_t getFlags() const { return Flags; } + + /// Set the (implementation defined) symbol flags. + void setFlags(uint32_t Value) const { Flags = Value; } + + /// Modify the flags via a mask + void modifyFlags(uint32_t Value, uint32_t Mask) const { + Flags = (Flags & ~Mask) | Value; + } }; inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) { - Sym.print(OS); + Sym.print(OS, nullptr); return OS; } } // end namespace llvm