LLVM  mainline
MCSymbol.h
Go to the documentation of this file.
00001 //===- MCSymbol.h - Machine Code Symbols ------------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the declaration of the MCSymbol class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_MC_MCSYMBOL_H
00015 #define LLVM_MC_MCSYMBOL_H
00016 
00017 #include "llvm/ADT/PointerIntPair.h"
00018 #include "llvm/ADT/StringMap.h"
00019 #include "llvm/MC/MCExpr.h"
00020 #include "llvm/Support/Compiler.h"
00021 
00022 namespace llvm {
00023 class MCExpr;
00024 class MCSymbol;
00025 class MCFragment;
00026 class MCSection;
00027 class MCContext;
00028 class raw_ostream;
00029 
00030 // TODO: Merge completely with MCSymbol.
00031 class MCSymbolData {
00032   /// Fragment - The fragment this symbol's value is relative to, if any. Also
00033   /// stores if this symbol is visible outside this translation unit (bit 0) or
00034   /// if it is private extern (bit 1).
00035   PointerIntPair<MCFragment *, 2> Fragment;
00036 
00037   union {
00038     /// Offset - The offset to apply to the fragment address to form this
00039     /// symbol's value.
00040     uint64_t Offset;
00041 
00042     /// CommonSize - The size of the symbol, if it is 'common'.
00043     uint64_t CommonSize;
00044   };
00045 
00046   /// SymbolSize - An expression describing how to calculate the size of
00047   /// a symbol. If a symbol has no size this field will be NULL.
00048   const MCExpr *SymbolSize = nullptr;
00049 
00050   /// CommonAlign - The alignment of the symbol, if it is 'common', or -1.
00051   //
00052   // FIXME: Pack this in with other fields?
00053   unsigned CommonAlign = -1U;
00054 
00055   /// Flags - The Flags field is used by object file implementations to store
00056   /// additional per symbol information which is not easily classified.
00057   uint32_t Flags = 0;
00058 
00059 public:
00060   MCSymbolData() { Offset = 0; }
00061 
00062   MCFragment *getFragment() const { return Fragment.getPointer(); }
00063   void setFragment(MCFragment *Value) { Fragment.setPointer(Value); }
00064 
00065   uint64_t getOffset() const {
00066     assert(!isCommon());
00067     return Offset;
00068   }
00069   void setOffset(uint64_t Value) {
00070     assert(!isCommon());
00071     Offset = Value;
00072   }
00073 
00074   /// @}
00075   /// \name Symbol Attributes
00076   /// @{
00077 
00078   bool isExternal() const { return Fragment.getInt() & 1; }
00079   void setExternal(bool Value) {
00080     Fragment.setInt((Fragment.getInt() & ~1) | unsigned(Value));
00081   }
00082 
00083   bool isPrivateExtern() const { return Fragment.getInt() & 2; }
00084   void setPrivateExtern(bool Value) {
00085     Fragment.setInt((Fragment.getInt() & ~2) | (unsigned(Value) << 1));
00086   }
00087 
00088   /// isCommon - Is this a 'common' symbol.
00089   bool isCommon() const { return CommonAlign != -1U; }
00090 
00091   /// setCommon - Mark this symbol as being 'common'.
00092   ///
00093   /// \param Size - The size of the symbol.
00094   /// \param Align - The alignment of the symbol.
00095   void setCommon(uint64_t Size, unsigned Align) {
00096     assert(getOffset() == 0);
00097     CommonSize = Size;
00098     CommonAlign = Align;
00099   }
00100 
00101   /// getCommonSize - Return the size of a 'common' symbol.
00102   uint64_t getCommonSize() const {
00103     assert(isCommon() && "Not a 'common' symbol!");
00104     return CommonSize;
00105   }
00106 
00107   void setSize(const MCExpr *SS) { SymbolSize = SS; }
00108 
00109   const MCExpr *getSize() const { return SymbolSize; }
00110 
00111   /// getCommonAlignment - Return the alignment of a 'common' symbol.
00112   unsigned getCommonAlignment() const {
00113     assert(isCommon() && "Not a 'common' symbol!");
00114     return CommonAlign;
00115   }
00116 
00117   /// getFlags - Get the (implementation defined) symbol flags.
00118   uint32_t getFlags() const { return Flags; }
00119 
00120   /// setFlags - Set the (implementation defined) symbol flags.
00121   void setFlags(uint32_t Value) { Flags = Value; }
00122 
00123   /// modifyFlags - Modify the flags via a mask
00124   void modifyFlags(uint32_t Value, uint32_t Mask) {
00125     Flags = (Flags & ~Mask) | Value;
00126   }
00127 
00128   /// @}
00129 
00130   void dump() const;
00131 };
00132 
00133 /// MCSymbol - Instances of this class represent a symbol name in the MC file,
00134 /// and MCSymbols are created and uniqued by the MCContext class.  MCSymbols
00135 /// should only be constructed with valid names for the object file.
00136 ///
00137 /// If the symbol is defined/emitted into the current translation unit, the
00138 /// Section member is set to indicate what section it lives in.  Otherwise, if
00139 /// it is a reference to an external entity, it has a null section.
00140 class MCSymbol {
00141   // Special sentinal value for the absolute pseudo section.
00142   //
00143   // FIXME: Use a PointerInt wrapper for this?
00144   static MCSection *AbsolutePseudoSection;
00145 
00146   /// Name - The name of the symbol.  The referred-to string data is actually
00147   /// held by the StringMap that lives in MCContext.
00148   const StringMapEntry<bool> *Name;
00149 
00150   /// The section the symbol is defined in. This is null for undefined symbols,
00151   /// and the special AbsolutePseudoSection value for absolute symbols. If this
00152   /// is a variable symbol, this caches the variable value's section.
00153   mutable MCSection *Section;
00154 
00155   /// Value - If non-null, the value for a variable symbol.
00156   const MCExpr *Value;
00157 
00158   /// IsTemporary - True if this is an assembler temporary label, which
00159   /// typically does not survive in the .o file's symbol table.  Usually
00160   /// "Lfoo" or ".foo".
00161   unsigned IsTemporary : 1;
00162 
00163   /// \brief True if this symbol can be redefined.
00164   unsigned IsRedefinable : 1;
00165 
00166   /// IsUsed - True if this symbol has been used.
00167   mutable unsigned IsUsed : 1;
00168 
00169   mutable bool HasData : 1;
00170 
00171   /// Index field, for use by the object file implementation.
00172   mutable uint64_t Index : 60;
00173 
00174   mutable MCSymbolData Data;
00175 
00176 private: // MCContext creates and uniques these.
00177   friend class MCExpr;
00178   friend class MCContext;
00179   MCSymbol(const StringMapEntry<bool> *Name, bool isTemporary)
00180       : Name(Name), Section(nullptr), Value(nullptr), IsTemporary(isTemporary),
00181         IsRedefinable(false), IsUsed(false), HasData(false), Index(0) {}
00182 
00183   MCSymbol(const MCSymbol &) = delete;
00184   void operator=(const MCSymbol &) = delete;
00185   MCSection *getSectionPtr() const {
00186     if (Section || !Value)
00187       return Section;
00188     return Section = Value->FindAssociatedSection();
00189   }
00190 
00191 public:
00192   /// getName - Get the symbol name.
00193   StringRef getName() const { return Name ? Name->first() : ""; }
00194 
00195   bool hasData() const { return HasData; }
00196 
00197   /// Get associated symbol data.
00198   MCSymbolData &getData() const {
00199     assert(HasData && "Missing symbol data!");
00200     return Data;
00201   }
00202 
00203   /// Initialize symbol data.
00204   ///
00205   /// Nothing really to do here, but this is enables an assertion that \a
00206   /// MCAssembler::getOrCreateSymbolData() has actually been called before
00207   /// anyone calls \a getData().
00208   void initializeData() const { HasData = true; }
00209 
00210   /// \name Accessors
00211   /// @{
00212 
00213   /// isTemporary - Check if this is an assembler temporary symbol.
00214   bool isTemporary() const { return IsTemporary; }
00215 
00216   /// isUsed - Check if this is used.
00217   bool isUsed() const { return IsUsed; }
00218   void setUsed(bool Value) const { IsUsed = Value; }
00219 
00220   /// \brief Check if this symbol is redefinable.
00221   bool isRedefinable() const { return IsRedefinable; }
00222   /// \brief Mark this symbol as redefinable.
00223   void setRedefinable(bool Value) { IsRedefinable = Value; }
00224   /// \brief Prepare this symbol to be redefined.
00225   void redefineIfPossible() {
00226     if (IsRedefinable) {
00227       Value = nullptr;
00228       Section = nullptr;
00229       IsRedefinable = false;
00230     }
00231   }
00232 
00233   /// @}
00234   /// \name Associated Sections
00235   /// @{
00236 
00237   /// isDefined - Check if this symbol is defined (i.e., it has an address).
00238   ///
00239   /// Defined symbols are either absolute or in some section.
00240   bool isDefined() const { return getSectionPtr() != nullptr; }
00241 
00242   /// isInSection - Check if this symbol is defined in some section (i.e., it
00243   /// is defined but not absolute).
00244   bool isInSection() const { return isDefined() && !isAbsolute(); }
00245 
00246   /// isUndefined - Check if this symbol undefined (i.e., implicitly defined).
00247   bool isUndefined() const { return !isDefined(); }
00248 
00249   /// isAbsolute - Check if this is an absolute symbol.
00250   bool isAbsolute() const { return getSectionPtr() == AbsolutePseudoSection; }
00251 
00252   /// Get the section associated with a defined, non-absolute symbol.
00253   MCSection &getSection() const {
00254     assert(isInSection() && "Invalid accessor!");
00255     return *getSectionPtr();
00256   }
00257 
00258   /// Mark the symbol as defined in the section \p S.
00259   void setSection(MCSection &S) {
00260     assert(!isVariable() && "Cannot set section of variable");
00261     Section = &S;
00262   }
00263 
00264   /// setUndefined - Mark the symbol as undefined.
00265   void setUndefined() { Section = nullptr; }
00266 
00267   /// @}
00268   /// \name Variable Symbols
00269   /// @{
00270 
00271   /// isVariable - Check if this is a variable symbol.
00272   bool isVariable() const { return Value != nullptr; }
00273 
00274   /// getVariableValue() - Get the value for variable symbols.
00275   const MCExpr *getVariableValue() const {
00276     assert(isVariable() && "Invalid accessor!");
00277     IsUsed = true;
00278     return Value;
00279   }
00280 
00281   void setVariableValue(const MCExpr *Value);
00282 
00283   /// @}
00284 
00285   /// Get the (implementation defined) index.
00286   uint64_t getIndex() const {
00287     assert(HasData && "Uninitialized symbol data");
00288     return Index;
00289   }
00290 
00291   /// Set the (implementation defined) index.
00292   void setIndex(uint64_t Value) const {
00293     assert(HasData && "Uninitialized symbol data");
00294     assert(!(Value >> 60) && "Not enough bits for value");
00295     Index = Value;
00296   }
00297 
00298   /// print - Print the value to the stream \p OS.
00299   void print(raw_ostream &OS) const;
00300 
00301   /// dump - Print the value to stderr.
00302   void dump() const;
00303 };
00304 
00305 inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
00306   Sym.print(OS);
00307   return OS;
00308 }
00309 } // end namespace llvm
00310 
00311 #endif