Move MCSymbol Value in to the union of Offset and CommonSize.
[oota-llvm.git] / include / llvm / MC / MCSymbol.h
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/PointerUnion.h"
18 #include "llvm/ADT/StringMap.h"
19 #include "llvm/MC/MCAssembler.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/Support/Compiler.h"
22
23 namespace llvm {
24 class MCAsmInfo;
25 class MCExpr;
26 class MCSymbol;
27 class MCFragment;
28 class MCSection;
29 class MCContext;
30 class raw_ostream;
31
32 /// MCSymbol - Instances of this class represent a symbol name in the MC file,
33 /// and MCSymbols are created and uniqued by the MCContext class.  MCSymbols
34 /// should only be constructed with valid names for the object file.
35 ///
36 /// If the symbol is defined/emitted into the current translation unit, the
37 /// Section member is set to indicate what section it lives in.  Otherwise, if
38 /// it is a reference to an external entity, it has a null section.
39 class MCSymbol {
40 protected:
41   /// The kind of the symbol.  If it is any value other than unset then this
42   /// class is actually one of the appropriate subclasses of MCSymbol.
43   enum SymbolKind {
44     SymbolKindUnset,
45     SymbolKindCOFF,
46     SymbolKindELF,
47     SymbolKindMachO,
48   };
49
50   // Special sentinal value for the absolute pseudo section.
51   //
52   // FIXME: Use a PointerInt wrapper for this?
53   static MCSection *AbsolutePseudoSection;
54
55   /// If a symbol has a Fragment, the section is implied, so we only need
56   /// one pointer.
57   /// FIXME: We might be able to simplify this by having the asm streamer create
58   /// dummy fragments.
59   /// If this is a section, then it gives the symbol is defined in. This is null
60   /// for undefined symbols, and the special AbsolutePseudoSection value for
61   /// absolute symbols. If this is a variable symbol, this caches the variable
62   /// value's section.
63   ///
64   /// If this is a fragment, then it gives the fragment this symbol's value is
65   /// relative to, if any.
66   mutable PointerUnion<MCSection *, MCFragment *> SectionOrFragment;
67
68   /// IsTemporary - True if this is an assembler temporary label, which
69   /// typically does not survive in the .o file's symbol table.  Usually
70   /// "Lfoo" or ".foo".
71   unsigned IsTemporary : 1;
72
73   /// \brief True if this symbol can be redefined.
74   unsigned IsRedefinable : 1;
75
76   /// IsUsed - True if this symbol has been used.
77   mutable unsigned IsUsed : 1;
78
79   mutable bool IsRegistered : 1;
80
81   /// This symbol is visible outside this translation unit.
82   mutable unsigned IsExternal : 1;
83
84   /// This symbol is private extern.
85   mutable unsigned IsPrivateExtern : 1;
86
87   /// True if this symbol is named.
88   /// A named symbol will have a pointer to the name allocated in the bytes
89   /// immediately prior to the MCSymbol.
90   unsigned HasName : 1;
91
92   /// LLVM RTTI discriminator. This is actually a SymbolKind enumerator, but is
93   /// unsigned to avoid sign extension and achieve better bitpacking with MSVC.
94   unsigned Kind : 2;
95
96   /// A symbol can contain an Offset, or Value, or be Common, but never more
97   /// than one of these.
98   enum Contents : uint8_t {
99     SymContentsUnset,
100     SymContentsOffset,
101     SymContentsVariable,
102     SymContentsCommon,
103   };
104
105   Contents SymbolContents : 2;
106
107   /// Index field, for use by the object file implementation.
108   mutable uint32_t Index = 0;
109
110   union {
111     /// The offset to apply to the fragment address to form this symbol's value.
112     uint64_t Offset;
113
114     /// The size of the symbol, if it is 'common'.
115     uint64_t CommonSize;
116
117     /// If non-null, the value for a variable symbol.
118     const MCExpr *Value;
119   };
120
121   /// The alignment of the symbol, if it is 'common', or -1.
122   //
123   // FIXME: Pack this in with other fields?
124   unsigned CommonAlign = -1U;
125
126   /// The Flags field is used by object file implementations to store
127   /// additional per symbol information which is not easily classified.
128   mutable uint32_t Flags = 0;
129
130 protected: // MCContext creates and uniques these.
131   friend class MCExpr;
132   friend class MCContext;
133
134   /// \brief The name for a symbol.
135   /// MCSymbol contains a uint64_t so is probably aligned to 8.  On a 32-bit
136   /// system, the name is a pointer so isn't going to satisfy the 8 byte
137   /// alignment of uint64_t.  Account for that here.
138   typedef union {
139     const StringMapEntry<bool> *NameEntry;
140     uint64_t AlignmentPadding;
141   } NameEntryStorageTy;
142
143   MCSymbol(SymbolKind Kind, const StringMapEntry<bool> *Name, bool isTemporary)
144       : IsTemporary(isTemporary),
145         IsRedefinable(false), IsUsed(false), IsRegistered(false),
146         IsExternal(false), IsPrivateExtern(false), HasName(!!Name),
147         Kind(Kind), SymbolContents(SymContentsUnset) {
148     Offset = 0;
149     if (Name)
150       getNameEntryPtr() = Name;
151   }
152
153   // Provide custom new/delete as we will only allocate space for a name
154   // if we need one.
155   void *operator new(size_t s, const StringMapEntry<bool> *Name,
156                      MCContext &Ctx);
157
158 private:
159
160   void operator delete(void *);
161   /// \brief Placement delete - required by std, but never called.
162   void operator delete(void*, unsigned) {
163     llvm_unreachable("Constructor throws?");
164   }
165   /// \brief Placement delete - required by std, but never called.
166   void operator delete(void*, unsigned, bool) {
167     llvm_unreachable("Constructor throws?");
168   }
169
170   MCSymbol(const MCSymbol &) = delete;
171   void operator=(const MCSymbol &) = delete;
172   MCSection *getSectionPtr() const {
173     if (MCFragment *F = getFragment())
174       return F->getParent();
175     assert(!SectionOrFragment.is<MCFragment *>() && "Section or null expected");
176     MCSection *Section = SectionOrFragment.dyn_cast<MCSection *>();
177     if (Section || !isVariable())
178       return Section;
179     return Section = getVariableValue()->findAssociatedSection();
180   }
181
182   /// \brief Get a reference to the name field.  Requires that we have a name
183   const StringMapEntry<bool> *&getNameEntryPtr() {
184     assert(HasName && "Name is required");
185     NameEntryStorageTy *Name = reinterpret_cast<NameEntryStorageTy *>(this);
186     return (*(Name - 1)).NameEntry;
187   }
188   const StringMapEntry<bool> *&getNameEntryPtr() const {
189     return const_cast<MCSymbol*>(this)->getNameEntryPtr();
190   }
191
192 public:
193   /// getName - Get the symbol name.
194   StringRef getName() const {
195     if (!HasName)
196       return StringRef();
197
198     return getNameEntryPtr()->first();
199   }
200
201   bool isRegistered() const { return IsRegistered; }
202   void setIsRegistered(bool Value) const { IsRegistered = Value; }
203
204   /// \name Accessors
205   /// @{
206
207   /// isTemporary - Check if this is an assembler temporary symbol.
208   bool isTemporary() const { return IsTemporary; }
209
210   /// isUsed - Check if this is used.
211   bool isUsed() const { return IsUsed; }
212   void setUsed(bool Value) const { IsUsed = Value; }
213
214   /// \brief Check if this symbol is redefinable.
215   bool isRedefinable() const { return IsRedefinable; }
216   /// \brief Mark this symbol as redefinable.
217   void setRedefinable(bool Value) { IsRedefinable = Value; }
218   /// \brief Prepare this symbol to be redefined.
219   void redefineIfPossible() {
220     if (IsRedefinable) {
221       if (SymbolContents == SymContentsVariable) {
222         Value = nullptr;
223         SymbolContents = SymContentsUnset;
224       }
225       SectionOrFragment = nullptr;
226       IsRedefinable = false;
227     }
228   }
229
230   /// @}
231   /// \name Associated Sections
232   /// @{
233
234   /// isDefined - Check if this symbol is defined (i.e., it has an address).
235   ///
236   /// Defined symbols are either absolute or in some section.
237   bool isDefined() const { return getSectionPtr() != nullptr; }
238
239   /// isInSection - Check if this symbol is defined in some section (i.e., it
240   /// is defined but not absolute).
241   bool isInSection() const { return isDefined() && !isAbsolute(); }
242
243   /// isUndefined - Check if this symbol undefined (i.e., implicitly defined).
244   bool isUndefined() const { return !isDefined(); }
245
246   /// isAbsolute - Check if this is an absolute symbol.
247   bool isAbsolute() const { return getSectionPtr() == AbsolutePseudoSection; }
248
249   /// Get the section associated with a defined, non-absolute symbol.
250   MCSection &getSection() const {
251     assert(isInSection() && "Invalid accessor!");
252     return *getSectionPtr();
253   }
254
255   /// Mark the symbol as defined in the section \p S.
256   void setSection(MCSection &S) {
257     assert(!isVariable() && "Cannot set section of variable");
258     assert(!SectionOrFragment.is<MCFragment *>() && "Section or null expected");
259     SectionOrFragment = &S;
260   }
261
262   /// Mark the symbol as undefined.
263   void setUndefined() {
264     SectionOrFragment = nullptr;
265   }
266
267   bool isELF() const { return Kind == SymbolKindELF; }
268
269   bool isCOFF() const { return Kind == SymbolKindCOFF; }
270
271   bool isMachO() const { return Kind == SymbolKindMachO; }
272
273   /// @}
274   /// \name Variable Symbols
275   /// @{
276
277   /// isVariable - Check if this is a variable symbol.
278   bool isVariable() const {
279     return SymbolContents == SymContentsVariable;
280   }
281
282   /// getVariableValue() - Get the value for variable symbols.
283   const MCExpr *getVariableValue() const {
284     assert(isVariable() && "Invalid accessor!");
285     IsUsed = true;
286     return Value;
287   }
288
289   void setVariableValue(const MCExpr *Value);
290
291   /// @}
292
293   /// Get the (implementation defined) index.
294   uint32_t getIndex() const {
295     return Index;
296   }
297
298   /// Set the (implementation defined) index.
299   void setIndex(uint32_t Value) const {
300     Index = Value;
301   }
302
303   uint64_t getOffset() const {
304     assert((SymbolContents == SymContentsUnset ||
305             SymbolContents == SymContentsOffset) &&
306            "Cannot get offset for a common/variable symbol");
307     return Offset;
308   }
309   void setOffset(uint64_t Value) {
310     assert((SymbolContents == SymContentsUnset ||
311             SymbolContents == SymContentsOffset) &&
312            "Cannot set offset for a common/variable symbol");
313     Offset = Value;
314     SymbolContents = SymContentsOffset;
315   }
316
317   /// Return the size of a 'common' symbol.
318   uint64_t getCommonSize() const {
319     assert(isCommon() && "Not a 'common' symbol!");
320     return CommonSize;
321   }
322
323   /// Mark this symbol as being 'common'.
324   ///
325   /// \param Size - The size of the symbol.
326   /// \param Align - The alignment of the symbol.
327   void setCommon(uint64_t Size, unsigned Align) {
328     assert(getOffset() == 0);
329     CommonSize = Size;
330     CommonAlign = Align;
331     SymbolContents = SymContentsCommon;
332   }
333
334   ///  Return the alignment of a 'common' symbol.
335   unsigned getCommonAlignment() const {
336     assert(isCommon() && "Not a 'common' symbol!");
337     return CommonAlign;
338   }
339
340   /// Declare this symbol as being 'common'.
341   ///
342   /// \param Size - The size of the symbol.
343   /// \param Align - The alignment of the symbol.
344   /// \return True if symbol was already declared as a different type
345   bool declareCommon(uint64_t Size, unsigned Align) {
346     assert(isCommon() || getOffset() == 0);
347     if(isCommon()) {
348       if(CommonSize != Size || CommonAlign != Align)
349        return true;
350     } else
351       setCommon(Size, Align);
352     return false;
353   }
354
355   /// Is this a 'common' symbol.
356   bool isCommon() const {
357     return SymbolContents == SymContentsCommon;
358   }
359
360   MCFragment *getFragment() const {
361     return SectionOrFragment.dyn_cast<MCFragment *>();
362   }
363   void setFragment(MCFragment *Value) const {
364     SectionOrFragment = Value;
365   }
366
367   bool isExternal() const { return IsExternal; }
368   void setExternal(bool Value) const { IsExternal = Value; }
369
370   bool isPrivateExtern() const { return IsPrivateExtern; }
371   void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
372
373   /// print - Print the value to the stream \p OS.
374   void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
375
376   /// dump - Print the value to stderr.
377   void dump() const;
378
379 protected:
380   /// Get the (implementation defined) symbol flags.
381   uint32_t getFlags() const { return Flags; }
382
383   /// Set the (implementation defined) symbol flags.
384   void setFlags(uint32_t Value) const { Flags = Value; }
385
386   /// Modify the flags via a mask
387   void modifyFlags(uint32_t Value, uint32_t Mask) const {
388     Flags = (Flags & ~Mask) | Value;
389   }
390 };
391
392 inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
393   Sym.print(OS, nullptr);
394   return OS;
395 }
396 } // end namespace llvm
397
398 #endif