1 //===- MCSymbol.h - Machine Code Symbols ------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the declaration of the MCSymbol class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_MC_MCSYMBOL_H 15 #define LLVM_MC_MCSYMBOL_H 16 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/MC/MCExpr.h" 19 #include "llvm/Support/Compiler.h" 20 21 namespace llvm { 22 class MCExpr; 23 class MCSection; 24 class MCContext; 25 class raw_ostream; 26 27 /// MCSymbol - Instances of this class represent a symbol name in the MC file, 28 /// and MCSymbols are created and unique'd by the MCContext class. MCSymbols 29 /// should only be constructed with valid names for the object file. 30 /// 31 /// If the symbol is defined/emitted into the current translation unit, the 32 /// Section member is set to indicate what section it lives in. Otherwise, if 33 /// it is a reference to an external entity, it has a null section. 34 class MCSymbol { 35 // Special sentinal value for the absolute pseudo section. 36 // 37 // FIXME: Use a PointerInt wrapper for this? 38 static const MCSection *AbsolutePseudoSection; 39 40 /// Name - The name of the symbol. The referred-to string data is actually 41 /// held by the StringMap that lives in MCContext. 42 StringRef Name; 43 44 /// Section - The section the symbol is defined in. This is null for 45 /// undefined symbols, and the special AbsolutePseudoSection value for 46 /// absolute symbols. If this is a variable symbol, this caches the 47 /// variable value's section. 48 mutable const MCSection *Section; 49 50 /// Value - If non-null, the value for a variable symbol. 51 const MCExpr *Value; 52 53 /// IsTemporary - True if this is an assembler temporary label, which 54 /// typically does not survive in the .o file's symbol table. Usually 55 /// "Lfoo" or ".foo". 56 unsigned IsTemporary : 1; 57 58 /// \brief True if this symbol can be redefined. 59 unsigned IsRedefinable : 1; 60 61 /// IsUsed - True if this symbol has been used. 62 mutable unsigned IsUsed : 1; 63 64 private: // MCContext creates and uniques these. 65 friend class MCExpr; 66 friend class MCContext; MCSymbol(StringRef name,bool isTemporary)67 MCSymbol(StringRef name, bool isTemporary) 68 : Name(name), Section(nullptr), Value(nullptr), 69 IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false) {} 70 71 MCSymbol(const MCSymbol&) = delete; 72 void operator=(const MCSymbol&) = delete; getSectionPtr()73 const MCSection *getSectionPtr() const { 74 if (Section || !Value) 75 return Section; 76 return Section = Value->FindAssociatedSection(); 77 } 78 79 public: 80 /// getName - Get the symbol name. getName()81 StringRef getName() const { return Name; } 82 83 /// @name Accessors 84 /// @{ 85 86 /// isTemporary - Check if this is an assembler temporary symbol. isTemporary()87 bool isTemporary() const { return IsTemporary; } 88 89 /// isUsed - Check if this is used. isUsed()90 bool isUsed() const { return IsUsed; } setUsed(bool Value)91 void setUsed(bool Value) const { IsUsed = Value; } 92 93 /// \brief Check if this symbol is redefinable. isRedefinable()94 bool isRedefinable() const { return IsRedefinable; } 95 /// \brief Mark this symbol as redefinable. setRedefinable(bool Value)96 void setRedefinable(bool Value) { IsRedefinable = Value; } 97 /// \brief Prepare this symbol to be redefined. redefineIfPossible()98 void redefineIfPossible() { 99 if (IsRedefinable) { 100 Value = nullptr; 101 Section = nullptr; 102 IsRedefinable = false; 103 } 104 } 105 106 /// @} 107 /// @name Associated Sections 108 /// @{ 109 110 /// isDefined - Check if this symbol is defined (i.e., it has an address). 111 /// 112 /// Defined symbols are either absolute or in some section. isDefined()113 bool isDefined() const { 114 return getSectionPtr() != nullptr; 115 } 116 117 /// isInSection - Check if this symbol is defined in some section (i.e., it 118 /// is defined but not absolute). isInSection()119 bool isInSection() const { 120 return isDefined() && !isAbsolute(); 121 } 122 123 /// isUndefined - Check if this symbol undefined (i.e., implicitly defined). isUndefined()124 bool isUndefined() const { 125 return !isDefined(); 126 } 127 128 /// isAbsolute - Check if this is an absolute symbol. isAbsolute()129 bool isAbsolute() const { 130 return getSectionPtr() == AbsolutePseudoSection; 131 } 132 133 /// getSection - Get the section associated with a defined, non-absolute 134 /// symbol. getSection()135 const MCSection &getSection() const { 136 assert(isInSection() && "Invalid accessor!"); 137 return *getSectionPtr(); 138 } 139 140 /// setSection - Mark the symbol as defined in the section \p S. setSection(const MCSection & S)141 void setSection(const MCSection &S) { 142 assert(!isVariable() && "Cannot set section of variable"); 143 Section = &S; 144 } 145 146 /// setUndefined - Mark the symbol as undefined. setUndefined()147 void setUndefined() { 148 Section = nullptr; 149 } 150 151 /// @} 152 /// @name Variable Symbols 153 /// @{ 154 155 /// isVariable - Check if this is a variable symbol. isVariable()156 bool isVariable() const { 157 return Value != nullptr; 158 } 159 160 /// getVariableValue() - Get the value for variable symbols. getVariableValue()161 const MCExpr *getVariableValue() const { 162 assert(isVariable() && "Invalid accessor!"); 163 IsUsed = true; 164 return Value; 165 } 166 167 // AliasedSymbol() - If this is an alias (a = b), return the symbol 168 // we ultimately point to. For a non-alias, this just returns the symbol 169 // itself. 170 const MCSymbol &AliasedSymbol() const; 171 172 void setVariableValue(const MCExpr *Value); 173 174 /// @} 175 176 /// print - Print the value to the stream \p OS. 177 void print(raw_ostream &OS) const; 178 179 /// dump - Print the value to stderr. 180 void dump() const; 181 }; 182 183 inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) { 184 Sym.print(OS); 185 return OS; 186 } 187 } // end namespace llvm 188 189 #endif 190