MC: Add target hook to control symbol quoting
[oota-llvm.git] / include / llvm / MC / MCSymbol.h
index 7f74f378d465102a949a409a8d23103225d53227..078f3d77e55cd04ca19074e164bf68610677dee3 100644 (file)
 #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<MCSection *, MCFragment *> 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<bool> *Name, bool isTemporary)
-      : Name(Name), Section(nullptr), Value(nullptr), IsTemporary(isTemporary),
+  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), 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<MCFragment *>() && "Section or null expected");
+    MCSection *Section = SectionOrFragment.dyn_cast<MCSection *>();
     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<MCFragment *>() && "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
@@ -276,25 +289,11 @@ public:
   /// 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<MCFragment *>();
   }
   void setFragment(MCFragment *Value) const {
-    HasFragment = true;
-    Fragment = Value;
+    SectionOrFragment = Value;
   }
 
   bool isExternal() const { return IsExternal; }
@@ -304,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