ARMAsmBackend uses a factory method to generate binary file format specific
[oota-llvm.git] / include / llvm / MC / MCAssembler.h
index 0d12a5d5c8d7471c84d45ac699c57db7c507de4e..1cb34c2fe33bfc2822b11a4798fdcaef4d873a3f 100644 (file)
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/ilist.h"
 #include "llvm/ADT/ilist_node.h"
+#include "llvm/MC/MCDirectives.h"
 #include "llvm/MC/MCFixup.h"
 #include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCLinkerOptimizationHint.h"
 #include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/DataTypes.h"
@@ -66,8 +68,7 @@ private:
   MCSectionData *Parent;
 
   /// Atom - The atom this fragment is in, as represented by it's defining
-  /// symbol. Atom's are only used by backends which set
-  /// \see MCAsmBackend::hasReliableSymbolDifference().
+  /// symbol.
   MCSymbolData *Atom;
 
   /// @name Assembler Backend Data
@@ -85,7 +86,7 @@ private:
   /// @}
 
 protected:
-  MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
+  MCFragment(FragmentType _Kind, MCSectionData *_Parent = nullptr);
 
 public:
   // Only for sentinel.
@@ -136,7 +137,7 @@ class MCEncodedFragment : public MCFragment {
 
   uint8_t BundlePadding;
 public:
-  MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
+  MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = nullptr)
     : MCFragment(FType, SD), BundlePadding(0)
   {
   }
@@ -145,11 +146,11 @@ public:
   virtual SmallVectorImpl<char> &getContents() = 0;
   virtual const SmallVectorImpl<char> &getContents() const = 0;
 
-  virtual uint8_t getBundlePadding() const {
+  uint8_t getBundlePadding() const override {
     return BundlePadding;
   }
 
-  virtual void setBundlePadding(uint8_t N) {
+  void setBundlePadding(uint8_t N) override {
     BundlePadding = N;
   }
 
@@ -170,11 +171,11 @@ public:
 /// data and also have fixups registered.
 ///
 class MCEncodedFragmentWithFixups : public MCEncodedFragment {
-  virtual void anchor();
+  void anchor() override;
 
 public:
   MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
-                              MCSectionData *SD = 0)
+                              MCSectionData *SD = nullptr)
     : MCEncodedFragment(FType, SD)
   {
   }
@@ -201,7 +202,7 @@ public:
 /// Fragment for data and encoded instructions.
 ///
 class MCDataFragment : public MCEncodedFragmentWithFixups {
-  virtual void anchor();
+  void anchor() override;
 
   /// \brief Does this fragment contain encoded instructions anywhere in it?
   bool HasInstructions;
@@ -214,34 +215,36 @@ class MCDataFragment : public MCEncodedFragmentWithFixups {
   /// Fixups - The list of fixups in this fragment.
   SmallVector<MCFixup, 4> Fixups;
 public:
-  MCDataFragment(MCSectionData *SD = 0)
+  MCDataFragment(MCSectionData *SD = nullptr)
     : MCEncodedFragmentWithFixups(FT_Data, SD),
       HasInstructions(false), AlignToBundleEnd(false)
   {
   }
 
-  virtual SmallVectorImpl<char> &getContents() { return Contents; }
-  virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+  SmallVectorImpl<char> &getContents() override { return Contents; }
+  const SmallVectorImpl<char> &getContents() const override {
+    return Contents;
+  }
 
-  SmallVectorImpl<MCFixup> &getFixups() {
+  SmallVectorImpl<MCFixup> &getFixups() override {
     return Fixups;
   }
 
-  const SmallVectorImpl<MCFixup> &getFixups() const {
+  const SmallVectorImpl<MCFixup> &getFixups() const override {
     return Fixups;
   }
 
-  virtual bool hasInstructions() const { return HasInstructions; }
+  bool hasInstructions() const override { return HasInstructions; }
   virtual void setHasInstructions(bool V) { HasInstructions = V; }
 
-  virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
-  virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+  bool alignToBundleEnd() const override { return AlignToBundleEnd; }
+  void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
 
-  fixup_iterator fixup_begin() { return Fixups.begin(); }
-  const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+  fixup_iterator fixup_begin() override { return Fixups.begin(); }
+  const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
 
-  fixup_iterator fixup_end() {return Fixups.end();}
-  const_fixup_iterator fixup_end() const {return Fixups.end();}
+  fixup_iterator fixup_end() override {return Fixups.end();}
+  const_fixup_iterator fixup_end() const override {return Fixups.end();}
 
   static bool classof(const MCFragment *F) {
     return F->getKind() == MCFragment::FT_Data;
@@ -254,27 +257,27 @@ public:
 /// consumption.
 ///
 class MCCompactEncodedInstFragment : public MCEncodedFragment {
-  virtual void anchor();
+  void anchor() override;
 
   /// \brief Should this fragment be aligned to the end of a bundle?
   bool AlignToBundleEnd;
 
   SmallVector<char, 4> Contents;
 public:
-  MCCompactEncodedInstFragment(MCSectionData *SD = 0)
+  MCCompactEncodedInstFragment(MCSectionData *SD = nullptr)
     : MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false)
   {
   }
 
-  virtual bool hasInstructions() const {
+  bool hasInstructions() const override {
     return true;
   }
 
-  virtual SmallVectorImpl<char> &getContents() { return Contents; }
-  virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+  SmallVectorImpl<char> &getContents() override { return Contents; }
+  const SmallVectorImpl<char> &getContents() const override { return Contents; }
 
-  virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
-  virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+  bool alignToBundleEnd() const override { return AlignToBundleEnd; }
+  void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
 
   static bool classof(const MCFragment *F) {
     return F->getKind() == MCFragment::FT_CompactEncodedInst;
@@ -285,7 +288,7 @@ public:
 /// relaxed during the assembler layout and relaxation stage.
 ///
 class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
-  virtual void anchor();
+  void anchor() override;
 
   /// Inst - The instruction this is a fragment for.
   MCInst Inst;
@@ -304,33 +307,33 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
 public:
   MCRelaxableFragment(const MCInst &_Inst,
                       const MCSubtargetInfo &_STI,
-                      MCSectionData *SD = 0)
+                      MCSectionData *SD = nullptr)
     : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) {
   }
 
-  virtual SmallVectorImpl<char> &getContents() { return Contents; }
-  virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+  SmallVectorImpl<char> &getContents() override { return Contents; }
+  const SmallVectorImpl<char> &getContents() const override { return Contents; }
 
   const MCInst &getInst() const { return Inst; }
   void setInst(const MCInst& Value) { Inst = Value; }
 
   const MCSubtargetInfo &getSubtargetInfo() { return STI; }
 
-  SmallVectorImpl<MCFixup> &getFixups() {
+  SmallVectorImpl<MCFixup> &getFixups() override {
     return Fixups;
   }
 
-  const SmallVectorImpl<MCFixup> &getFixups() const {
+  const SmallVectorImpl<MCFixup> &getFixups() const override {
     return Fixups;
   }
 
-  virtual bool hasInstructions() const { return true; }
+  bool hasInstructions() const override { return true; }
 
-  fixup_iterator fixup_begin() { return Fixups.begin(); }
-  const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+  fixup_iterator fixup_begin() override { return Fixups.begin(); }
+  const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
 
-  fixup_iterator fixup_end() {return Fixups.end();}
-  const_fixup_iterator fixup_end() const {return Fixups.end();}
+  fixup_iterator fixup_end() override {return Fixups.end();}
+  const_fixup_iterator fixup_end() const override {return Fixups.end();}
 
   static bool classof(const MCFragment *F) {
     return F->getKind() == MCFragment::FT_Relaxable;
@@ -360,7 +363,7 @@ class MCAlignFragment : public MCFragment {
 
 public:
   MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
-                  unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
+                  unsigned _MaxBytesToEmit, MCSectionData *SD = nullptr)
     : MCFragment(FT_Align, SD), Alignment(_Alignment),
       Value(_Value),ValueSize(_ValueSize),
       MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
@@ -401,7 +404,7 @@ class MCFillFragment : public MCFragment {
 
 public:
   MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
-                 MCSectionData *SD = 0)
+                 MCSectionData *SD = nullptr)
     : MCFragment(FT_Fill, SD),
       Value(_Value), ValueSize(_ValueSize), Size(_Size) {
     assert((!ValueSize || (Size % ValueSize) == 0) &&
@@ -434,7 +437,8 @@ class MCOrgFragment : public MCFragment {
   int8_t Value;
 
 public:
-  MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
+  MCOrgFragment(const MCExpr &_Offset, int8_t _Value,
+                MCSectionData *SD = nullptr)
     : MCFragment(FT_Org, SD),
       Offset(&_Offset), Value(_Value) {}
 
@@ -463,7 +467,8 @@ class MCLEBFragment : public MCFragment {
 
   SmallString<8> Contents;
 public:
-  MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD = 0)
+  MCLEBFragment(const MCExpr &Value_, bool IsSigned_,
+                MCSectionData *SD = nullptr)
     : MCFragment(FT_LEB, SD),
       Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
 
@@ -499,7 +504,7 @@ class MCDwarfLineAddrFragment : public MCFragment {
 
 public:
   MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
-                      MCSectionData *SD = 0)
+                      MCSectionData *SD = nullptr)
     : MCFragment(FT_Dwarf, SD),
       LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
 
@@ -530,7 +535,8 @@ class MCDwarfCallFrameFragment : public MCFragment {
   SmallString<8> Contents;
 
 public:
-  MCDwarfCallFrameFragment(const MCExpr &_AddrDelta,  MCSectionData *SD = 0)
+  MCDwarfCallFrameFragment(const MCExpr &_AddrDelta,
+                           MCSectionData *SD = nullptr)
     : MCFragment(FT_DwarfFrame, SD),
       AddrDelta(&_AddrDelta) { Contents.push_back(0); }
 
@@ -611,7 +617,7 @@ private:
 public:
   // Only for use as sentinel.
   MCSectionData();
-  MCSectionData(const MCSection &Section, MCAssembler *A = 0);
+  MCSectionData(const MCSection &Section, MCAssembler *A = nullptr);
 
   const MCSection &getSection() const { return *Section; }
 
@@ -721,7 +727,7 @@ public:
   // Only for use as sentinel.
   MCSymbolData();
   MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
-               MCAssembler *A = 0);
+               MCAssembler *A = nullptr);
 
   /// @name Accessors
   /// @{
@@ -796,7 +802,7 @@ public:
 
   /// @}
 
-  void dump();
+  void dump() const;
 };
 
 // FIXME: This really doesn't belong here. See comments below.
@@ -828,6 +834,9 @@ public:
   typedef SymbolDataListType::const_iterator const_symbol_iterator;
   typedef SymbolDataListType::iterator symbol_iterator;
 
+  typedef iterator_range<symbol_iterator> symbol_range;
+  typedef iterator_range<const_symbol_iterator> const_symbol_range;
+
   typedef std::vector<std::string> FileNameVectorType;
   typedef FileNameVectorType::const_iterator const_file_name_iterator;
 
@@ -839,6 +848,15 @@ public:
     const_data_region_iterator;
   typedef std::vector<DataRegionData>::iterator data_region_iterator;
 
+  /// MachO specific deployment target version info.
+  // A Major version of 0 indicates that no version information was supplied
+  // and so the corresponding load command should not be emitted.
+  typedef struct {
+    MCVersionMinType Kind;
+    unsigned Major;
+    unsigned Minor;
+    unsigned Update;
+  } VersionMinInfoType;
 private:
   MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
   void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
@@ -884,7 +902,7 @@ private:
   // here. Maybe when the relocation stuff moves to target specific,
   // this can go with it? The streamer would need some target specific
   // refactoring too.
-  SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
+  mutable SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
 
   /// \brief The bundle alignment size currently set in the assembler.
   ///
@@ -901,6 +919,12 @@ private:
   // Access to the flags is necessary in cases where assembler directives affect
   // which flags to be set.
   unsigned ELFHeaderEFlags;
+
+  /// Used to communicate Linker Optimization Hint information between
+  /// the Streamer and the .o writer
+  MCLOHContainer LOHContainer;
+
+  VersionMinInfoType VersionMinInfo;
 private:
   /// Evaluate a fixup to a relocatable expression and the value which should be
   /// placed into the fixup.
@@ -947,8 +971,8 @@ private:
   /// finishLayout - Finalize a layout, including fragment lowering.
   void finishLayout(MCAsmLayout &Layout);
 
-  uint64_t handleFixup(const MCAsmLayout &Layout,
-                       MCFragment &F, const MCFixup &Fixup);
+  std::pair<uint64_t, bool> handleFixup(const MCAsmLayout &Layout,
+                                        MCFragment &F, const MCFixup &Fixup);
 
 public:
   /// Compute the effective fragment size assuming it is laid out at the given
@@ -971,9 +995,7 @@ public:
                         const MCAsmLayout &Layout) const;
 
   /// Check whether a given symbol has been flagged with .thumb_func.
-  bool isThumbFunc(const MCSymbol *Func) const {
-    return ThumbFuncs.count(Func);
-  }
+  bool isThumbFunc(const MCSymbol *Func) const;
 
   /// Flag a function symbol as the target of a .thumb_func directive.
   void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
@@ -982,6 +1004,16 @@ public:
   unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;}
   void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;}
 
+  /// MachO deployment target version information.
+  const VersionMinInfoType &getVersionMinInfo() const { return VersionMinInfo; }
+  void setVersionMinInfo(MCVersionMinType Kind, unsigned Major, unsigned Minor,
+                         unsigned Update) {
+    VersionMinInfo.Kind = Kind;
+    VersionMinInfo.Major = Major;
+    VersionMinInfo.Minor = Minor;
+    VersionMinInfo.Update = Update;
+  }
+
 public:
   /// Construct a new assembler instance.
   ///
@@ -1068,6 +1100,9 @@ public:
   symbol_iterator symbol_end() { return Symbols.end(); }
   const_symbol_iterator symbol_end() const { return Symbols.end(); }
 
+  symbol_range symbols() { return make_range(symbol_begin(), symbol_end()); }
+  const_symbol_range symbols() const { return make_range(symbol_begin(), symbol_end()); }
+
   size_t symbol_size() const { return Symbols.size(); }
 
   /// @}
@@ -1132,6 +1167,19 @@ public:
 
   size_t data_region_size() const { return DataRegions.size(); }
 
+  /// @}
+  /// @name Data Region List Access
+  /// @{
+
+  // FIXME: This is a total hack, this should not be here. Once things are
+  // factored so that the streamer has direct access to the .o writer, it can
+  // disappear.
+  MCLOHContainer & getLOHContainer() {
+    return LOHContainer;
+  }
+  const MCLOHContainer & getLOHContainer() const {
+    return const_cast<MCAssembler *>(this)->getLOHContainer();
+  }
   /// @}
   /// @name Backend Data Access
   /// @{
@@ -1143,7 +1191,7 @@ public:
   }
 
   MCSectionData &getOrCreateSectionData(const MCSection &Section,
-                                        bool *Created = 0) {
+                                        bool *Created = nullptr) {
     MCSectionData *&Entry = SectionMap[&Section];
 
     if (Created) *Created = !Entry;
@@ -1154,22 +1202,27 @@ public:
   }
 
   bool hasSymbolData(const MCSymbol &Symbol) const {
-    return SymbolMap.lookup(&Symbol) != 0;
+    return SymbolMap.lookup(&Symbol) != nullptr;
+  }
+
+  MCSymbolData &getSymbolData(const MCSymbol &Symbol) {
+    return const_cast<MCSymbolData &>(
+        static_cast<const MCAssembler &>(*this).getSymbolData(Symbol));
   }
 
-  MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
+  const MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
     MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
     assert(Entry && "Missing symbol data!");
     return *Entry;
   }
 
   MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
-                                      bool *Created = 0) {
+                                      bool *Created = nullptr) {
     MCSymbolData *&Entry = SymbolMap[&Symbol];
 
     if (Created) *Created = !Entry;
     if (!Entry)
-      Entry = new MCSymbolData(Symbol, 0, 0, this);
+      Entry = new MCSymbolData(Symbol, nullptr, 0, this);
 
     return *Entry;
   }