LCOV - code coverage report
Current view: top level - include/llvm/MC - MCFragment.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 64 83 77.1 %
Date: 2018-06-17 00:07:59 Functions: 18 20 90.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- MCFragment.h - Fragment type hierarchy -------------------*- 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             : #ifndef LLVM_MC_MCFRAGMENT_H
      11             : #define LLVM_MC_MCFRAGMENT_H
      12             : 
      13             : #include "llvm/ADT/ArrayRef.h"
      14             : #include "llvm/ADT/SmallString.h"
      15             : #include "llvm/ADT/SmallVector.h"
      16             : #include "llvm/ADT/StringRef.h"
      17             : #include "llvm/ADT/ilist_node.h"
      18             : #include "llvm/MC/MCFixup.h"
      19             : #include "llvm/MC/MCInst.h"
      20             : #include "llvm/Support/Casting.h"
      21             : #include "llvm/Support/SMLoc.h"
      22             : #include <cstdint>
      23             : #include <utility>
      24             : 
      25             : namespace llvm {
      26             : 
      27             : class MCSection;
      28             : class MCSubtargetInfo;
      29             : class MCSymbol;
      30             : 
      31     6717917 : class MCFragment : public ilist_node_with_parent<MCFragment, MCSection> {
      32             :   friend class MCAsmLayout;
      33             : 
      34             : public:
      35             :   enum FragmentType : uint8_t {
      36             :     FT_Align,
      37             :     FT_Data,
      38             :     FT_CompactEncodedInst,
      39             :     FT_Fill,
      40             :     FT_Relaxable,
      41             :     FT_Org,
      42             :     FT_Dwarf,
      43             :     FT_DwarfFrame,
      44             :     FT_LEB,
      45             :     FT_Padding,
      46             :     FT_SymbolId,
      47             :     FT_CVInlineLines,
      48             :     FT_CVDefRange,
      49             :     FT_Dummy
      50             :   };
      51             : 
      52             : private:
      53             :   FragmentType Kind;
      54             : 
      55             : protected:
      56             :   bool HasInstructions;
      57             : 
      58             : private:
      59             :   /// LayoutOrder - The layout order of this fragment.
      60             :   unsigned LayoutOrder;
      61             : 
      62             :   /// The data for the section this fragment is in.
      63             :   MCSection *Parent;
      64             : 
      65             :   /// Atom - The atom this fragment is in, as represented by its defining
      66             :   /// symbol.
      67             :   const MCSymbol *Atom;
      68             : 
      69             :   /// \name Assembler Backend Data
      70             :   /// @{
      71             :   //
      72             :   // FIXME: This could all be kept private to the assembler implementation.
      73             : 
      74             :   /// Offset - The offset of this fragment in its section. This is ~0 until
      75             :   /// initialized.
      76             :   uint64_t Offset;
      77             : 
      78             :   /// @}
      79             : 
      80             : protected:
      81             :   MCFragment(FragmentType Kind, bool HasInstructions,
      82             :              MCSection *Parent = nullptr);
      83             : 
      84             :   ~MCFragment();
      85             : 
      86             : public:
      87             :   MCFragment() = delete;
      88             :   MCFragment(const MCFragment &) = delete;
      89             :   MCFragment &operator=(const MCFragment &) = delete;
      90             : 
      91             :   /// Destroys the current fragment.
      92             :   ///
      93             :   /// This must be used instead of delete as MCFragment is non-virtual.
      94             :   /// This method will dispatch to the appropriate subclass.
      95             :   void destroy();
      96             : 
      97             :   FragmentType getKind() const { return Kind; }
      98             : 
      99             :   MCSection *getParent() const { return Parent; }
     100     4639417 :   void setParent(MCSection *Value) { Parent = Value; }
     101             : 
     102             :   const MCSymbol *getAtom() const { return Atom; }
     103        8194 :   void setAtom(const MCSymbol *Value) { Atom = Value; }
     104             : 
     105             :   unsigned getLayoutOrder() const { return LayoutOrder; }
     106     3307072 :   void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
     107             : 
     108             :   /// Does this fragment have instructions emitted into it? By default
     109             :   /// this is false, but specific fragment types may set it to true.
     110             :   bool hasInstructions() const { return HasInstructions; }
     111             : 
     112             :   /// Return true if given frgment has FT_Dummy type.
     113             :   bool isDummy() const { return Kind == FT_Dummy; }
     114             : 
     115             :   void dump() const;
     116             : };
     117             : 
     118     2083437 : class MCDummyFragment : public MCFragment {
     119             : public:
     120     2090144 :   explicit MCDummyFragment(MCSection *Sec) : MCFragment(FT_Dummy, false, Sec) {}
     121             : 
     122             :   static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; }
     123             : };
     124             : 
     125             : /// Interface implemented by fragments that contain encoded instructions and/or
     126             : /// data.
     127             : ///
     128     3204574 : class MCEncodedFragment : public MCFragment {
     129             :   /// Should this fragment be aligned to the end of a bundle?
     130             :   bool AlignToBundleEnd = false;
     131             : 
     132             :   uint8_t BundlePadding = 0;
     133             : 
     134             : protected:
     135             :   MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
     136             :                     MCSection *Sec)
     137     3210058 :       : MCFragment(FType, HasInstructions, Sec) {}
     138             : 
     139             :   /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
     140             :   /// must be non-null for instructions.
     141             :   const MCSubtargetInfo *STI = nullptr;
     142             : 
     143             : public:
     144             :   static bool classof(const MCFragment *F) {
     145     6510760 :     MCFragment::FragmentType Kind = F->getKind();
     146             :     switch (Kind) {
     147             :     default:
     148             :       return false;
     149             :     case MCFragment::FT_Relaxable:
     150             :     case MCFragment::FT_CompactEncodedInst:
     151             :     case MCFragment::FT_Data:
     152             :       return true;
     153             :     }
     154             :   }
     155             : 
     156             :   /// Should this fragment be placed at the end of an aligned bundle?
     157             :   bool alignToBundleEnd() const { return AlignToBundleEnd; }
     158        2242 :   void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
     159             : 
     160             :   /// Get the padding size that must be inserted before this fragment.
     161             :   /// Used for bundling. By default, no padding is inserted.
     162             :   /// Note that padding size is restricted to 8 bits. This is an optimization
     163             :   /// to reduce the amount of space used for each fragment. In practice, larger
     164             :   /// padding should never be required.
     165             :   uint8_t getBundlePadding() const { return BundlePadding; }
     166             : 
     167             :   /// Set the padding size for this fragment. By default it's a no-op,
     168             :   /// and only some fragments have a meaningful implementation.
     169         780 :   void setBundlePadding(uint8_t N) { BundlePadding = N; }
     170             : 
     171             :   /// Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
     172             :   /// Guaranteed to be non-null if hasInstructions() == true
     173             :   const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
     174             : 
     175             :   /// Record that the fragment contains instructions with the MCSubtargetInfo in
     176             :   /// effect when the instruction was encoded.
     177             :   void setHasInstructions(const MCSubtargetInfo &STI) {
     178     2031890 :     HasInstructions = true;
     179     2031890 :     this->STI = &STI;
     180             :   }
     181             : };
     182             : 
     183             : /// Interface implemented by fragments that contain encoded instructions and/or
     184             : /// data.
     185             : ///
     186             : template<unsigned ContentsSize>
     187     6409148 : class MCEncodedFragmentWithContents : public MCEncodedFragment {
     188             :   SmallVector<char, ContentsSize> Contents;
     189             : 
     190             : protected:
     191     3210058 :   MCEncodedFragmentWithContents(MCFragment::FragmentType FType,
     192             :                                 bool HasInstructions,
     193             :                                 MCSection *Sec)
     194             :       : MCEncodedFragment(FType, HasInstructions, Sec) {}
     195             : 
     196             : public:
     197    19007261 :   SmallVectorImpl<char> &getContents() { return Contents; }
     198             :   const SmallVectorImpl<char> &getContents() const { return Contents; }
     199             : };
     200             : 
     201             : /// Interface implemented by fragments that contain encoded instructions and/or
     202             : /// data and also have fixups registered.
     203             : ///
     204             : template<unsigned ContentsSize, unsigned FixupsSize>
     205     6408878 : class MCEncodedFragmentWithFixups :
     206             :   public MCEncodedFragmentWithContents<ContentsSize> {
     207             : 
     208             :   /// Fixups - The list of fixups in this fragment.
     209             :   SmallVector<MCFixup, FixupsSize> Fixups;
     210             : 
     211             : protected:
     212     3209917 :   MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
     213             :                               bool HasInstructions,
     214             :                               MCSection *Sec)
     215             :       : MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions,
     216             :                                                     Sec) {}
     217             : 
     218             : public:
     219             : 
     220             :   using const_fixup_iterator = SmallVectorImpl<MCFixup>::const_iterator;
     221             :   using fixup_iterator = SmallVectorImpl<MCFixup>::iterator;
     222             : 
     223       86543 :   SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
     224             :   const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
     225             : 
     226             :   fixup_iterator fixup_begin() { return Fixups.begin(); }
     227             :   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
     228             : 
     229             :   fixup_iterator fixup_end() { return Fixups.end(); }
     230             :   const_fixup_iterator fixup_end() const { return Fixups.end(); }
     231             : 
     232             :   static bool classof(const MCFragment *F) {
     233             :     MCFragment::FragmentType Kind = F->getKind();
     234             :     return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||
     235             :            Kind == MCFragment::FT_CVDefRange;
     236             :   }
     237             : };
     238             : 
     239             : /// Fragment for data and encoded instructions.
     240             : ///
     241     3141792 : class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
     242             : public:
     243             :   MCDataFragment(MCSection *Sec = nullptr)
     244             :       : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
     245             : 
     246             :   static bool classof(const MCFragment *F) {
     247    21919214 :     return F->getKind() == MCFragment::FT_Data;
     248             :   }
     249             : };
     250             : 
     251             : /// This is a compact (memory-size-wise) fragment for holding an encoded
     252             : /// instruction (non-relaxable) that has no fixups registered. When applicable,
     253             : /// it can be used instead of MCDataFragment and lead to lower memory
     254             : /// consumption.
     255             : ///
     256         135 : class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> {
     257             : public:
     258             :   MCCompactEncodedInstFragment(MCSection *Sec = nullptr)
     259             :       : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) {
     260             :   }
     261             : 
     262             :   static bool classof(const MCFragment *F) {
     263             :     return F->getKind() == MCFragment::FT_CompactEncodedInst;
     264             :   }
     265             : };
     266             : 
     267             : /// A relaxable fragment holds on to its MCInst, since it may need to be
     268             : /// relaxed during the assembler layout and relaxation stage.
     269             : ///
     270      124932 : class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> {
     271             : 
     272             :   /// Inst - The instruction this is a fragment for.
     273             :   MCInst Inst;
     274             : 
     275             : public:
     276       62468 :   MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
     277             :                       MCSection *Sec = nullptr)
     278       62468 :       : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec),
     279       62468 :         Inst(Inst) { this->STI = &STI; }
     280             : 
     281      239710 :   const MCInst &getInst() const { return Inst; }
     282             :   void setInst(const MCInst &Value) { Inst = Value; }
     283             : 
     284             :   static bool classof(const MCFragment *F) {
     285           0 :     return F->getKind() == MCFragment::FT_Relaxable;
     286             :   }
     287             : };
     288             : 
     289      190016 : class MCAlignFragment : public MCFragment {
     290             :   /// Alignment - The alignment to ensure, in bytes.
     291             :   unsigned Alignment;
     292             : 
     293             :   /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
     294             :   /// of using the provided value. The exact interpretation of this flag is
     295             :   /// target dependent.
     296             :   bool EmitNops : 1;
     297             : 
     298             :   /// Value - Value to use for filling padding bytes.
     299             :   int64_t Value;
     300             : 
     301             :   /// ValueSize - The size of the integer (in bytes) of \p Value.
     302             :   unsigned ValueSize;
     303             : 
     304             :   /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
     305             :   /// cannot be satisfied in this width then this fragment is ignored.
     306             :   unsigned MaxBytesToEmit;
     307             : 
     308             : public:
     309             :   MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
     310             :                   unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
     311      190063 :       : MCFragment(FT_Align, false, Sec), Alignment(Alignment), EmitNops(false),
     312      190063 :         Value(Value), ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
     313             : 
     314             :   /// \name Accessors
     315             :   /// @{
     316             : 
     317             :   unsigned getAlignment() const { return Alignment; }
     318             : 
     319             :   int64_t getValue() const { return Value; }
     320             : 
     321             :   unsigned getValueSize() const { return ValueSize; }
     322             : 
     323             :   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
     324             : 
     325      339384 :   bool hasEmitNops() const { return EmitNops; }
     326       61362 :   void setEmitNops(bool Value) { EmitNops = Value; }
     327             : 
     328             :   /// @}
     329             : 
     330             :   static bool classof(const MCFragment *F) {
     331         217 :     return F->getKind() == MCFragment::FT_Align;
     332             :   }
     333             : };
     334             : 
     335             : /// Fragment for adding required padding.
     336             : /// This fragment is always inserted before an instruction, and holds that
     337             : /// instruction as context information (as well as a mask of kinds) for
     338             : /// determining the padding size.
     339             : ///
     340           0 : class MCPaddingFragment : public MCFragment {
     341             :   /// A mask containing all the kinds relevant to this fragment. i.e. the i'th
     342             :   /// bit will be set iff kind i is relevant to this fragment.
     343             :   uint64_t PaddingPoliciesMask;
     344             :   /// A boolean indicating if this fragment will actually hold padding. If its
     345             :   /// value is false, then this fragment serves only as a placeholder,
     346             :   /// containing data to assist other insertion point in their decision making.
     347             :   bool IsInsertionPoint;
     348             : 
     349             :   uint64_t Size;
     350             : 
     351           0 :   struct MCInstInfo {
     352             :     bool IsInitialized;
     353             :     MCInst Inst;
     354             :     /// A boolean indicating whether the instruction pointed by this fragment is
     355             :     /// a fixed size instruction or a relaxable instruction held by a
     356             :     /// MCRelaxableFragment.
     357             :     bool IsImmutableSizedInst;
     358             :     union {
     359             :       /// If the instruction is a fixed size instruction, hold its size.
     360             :       size_t InstSize;
     361             :       /// Otherwise, hold a pointer to the MCRelaxableFragment holding it.
     362             :       MCRelaxableFragment *InstFragment;
     363             :     };
     364             :   };
     365             :   MCInstInfo InstInfo;
     366             : 
     367             : public:
     368             :   static const uint64_t PFK_None = UINT64_C(0);
     369             : 
     370             :   enum MCPaddingFragmentKind {
     371             :     // values 0-7 are reserved for future target independet values.
     372             : 
     373             :     FirstTargetPerfNopFragmentKind = 8,
     374             : 
     375             :     /// Limit range of target MCPerfNopFragment kinds to fit in uint64_t
     376             :     MaxTargetPerfNopFragmentKind = 63
     377             :   };
     378             : 
     379           0 :   MCPaddingFragment(MCSection *Sec = nullptr)
     380           0 :       : MCFragment(FT_Padding, false, Sec), PaddingPoliciesMask(PFK_None),
     381             :         IsInsertionPoint(false), Size(UINT64_C(0)),
     382           0 :         InstInfo({false, MCInst(), false, {0}}) {}
     383             : 
     384             :   bool isInsertionPoint() const { return IsInsertionPoint; }
     385           0 :   void setAsInsertionPoint() { IsInsertionPoint = true; }
     386             :   uint64_t getPaddingPoliciesMask() const { return PaddingPoliciesMask; }
     387           0 :   void setPaddingPoliciesMask(uint64_t Value) { PaddingPoliciesMask = Value; }
     388             :   bool hasPaddingPolicy(uint64_t PolicyMask) const {
     389             :     assert(isPowerOf2_64(PolicyMask) &&
     390             :            "Policy mask must contain exactly one policy");
     391           0 :     return (getPaddingPoliciesMask() & PolicyMask) != PFK_None;
     392             :   }
     393             :   const MCInst &getInst() const {
     394             :     assert(isInstructionInitialized() && "Fragment has no instruction!");
     395             :     return InstInfo.Inst;
     396             :   }
     397             :   size_t getInstSize() const {
     398             :     assert(isInstructionInitialized() && "Fragment has no instruction!");
     399           0 :     if (InstInfo.IsImmutableSizedInst)
     400             :       return InstInfo.InstSize;
     401             :     assert(InstInfo.InstFragment != nullptr &&
     402             :            "Must have a valid InstFragment to retrieve InstSize from");
     403           0 :     return InstInfo.InstFragment->getContents().size();
     404             :   }
     405             :   void setInstAndInstSize(const MCInst &Inst, size_t InstSize) {
     406           0 :         InstInfo.IsInitialized = true;
     407           0 :     InstInfo.IsImmutableSizedInst = true;
     408             :     InstInfo.Inst = Inst;
     409           0 :     InstInfo.InstSize = InstSize;
     410             :   }
     411             :   void setInstAndInstFragment(const MCInst &Inst,
     412             :                               MCRelaxableFragment *InstFragment) {
     413           0 :     InstInfo.IsInitialized = true;
     414           0 :     InstInfo.IsImmutableSizedInst = false;
     415             :     InstInfo.Inst = Inst;
     416           0 :     InstInfo.InstFragment = InstFragment;
     417             :   }
     418             :   uint64_t getSize() const { return Size; }
     419           0 :   void setSize(uint64_t Value) { Size = Value; }
     420             :   bool isInstructionInitialized() const { return InstInfo.IsInitialized; }
     421             : 
     422             :   static bool classof(const MCFragment *F) {
     423           0 :     return F->getKind() == MCFragment::FT_Padding;
     424             :   }
     425             : };
     426             : 
     427      200134 : class MCFillFragment : public MCFragment {
     428             :   /// Value to use for filling bytes.
     429             :   uint64_t Value;
     430             :   uint8_t ValueSize;
     431             :   /// The number of bytes to insert.
     432             :   const MCExpr &NumValues;
     433             : 
     434             :   /// Source location of the directive that this fragment was created for.
     435             :   SMLoc Loc;
     436             : 
     437             : public:
     438             :   MCFillFragment(uint64_t Value, uint8_t VSize, const MCExpr &NumValues,
     439             :                  SMLoc Loc, MCSection *Sec = nullptr)
     440      200134 :       : MCFragment(FT_Fill, false, Sec), Value(Value), ValueSize(VSize),
     441      200134 :         NumValues(NumValues), Loc(Loc) {}
     442             : 
     443             :   uint64_t getValue() const { return Value; }
     444             :   uint8_t getValueSize() const { return ValueSize; }
     445             :   const MCExpr &getNumValues() const { return NumValues; }
     446             : 
     447             :   SMLoc getLoc() const { return Loc; }
     448             : 
     449             :   static bool classof(const MCFragment *F) {
     450             :     return F->getKind() == MCFragment::FT_Fill;
     451             :   }
     452             : };
     453             : 
     454          19 : class MCOrgFragment : public MCFragment {
     455             :   /// The offset this fragment should start at.
     456             :   const MCExpr *Offset;
     457             : 
     458             :   /// Value to use for filling bytes.
     459             :   int8_t Value;
     460             : 
     461             :   /// Source location of the directive that this fragment was created for.
     462             :   SMLoc Loc;
     463             : 
     464             : public:
     465             :   MCOrgFragment(const MCExpr &Offset, int8_t Value, SMLoc Loc,
     466             :                 MCSection *Sec = nullptr)
     467          19 :       : MCFragment(FT_Org, false, Sec), Offset(&Offset), Value(Value), Loc(Loc) {}
     468             : 
     469             :   /// \name Accessors
     470             :   /// @{
     471             : 
     472             :   const MCExpr &getOffset() const { return *Offset; }
     473             : 
     474        2463 :   uint8_t getValue() const { return Value; }
     475             : 
     476             :   SMLoc getLoc() const { return Loc; }
     477             : 
     478             :   /// @}
     479             : 
     480             :   static bool classof(const MCFragment *F) {
     481             :     return F->getKind() == MCFragment::FT_Org;
     482             :   }
     483             : };
     484             : 
     485      118082 : class MCLEBFragment : public MCFragment {
     486             :   /// Value - The value this fragment should contain.
     487             :   const MCExpr *Value;
     488             : 
     489             :   /// IsSigned - True if this is a sleb128, false if uleb128.
     490             :   bool IsSigned;
     491             : 
     492             :   SmallString<8> Contents;
     493             : 
     494             : public:
     495       59042 :   MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
     496       59042 :       : MCFragment(FT_LEB, false, Sec), Value(&Value_), IsSigned(IsSigned_) {
     497       59042 :     Contents.push_back(0);
     498       59042 :   }
     499             : 
     500             :   /// \name Accessors
     501             :   /// @{
     502             : 
     503             :   const MCExpr &getValue() const { return *Value; }
     504             : 
     505             :   bool isSigned() const { return IsSigned; }
     506             : 
     507             :   SmallString<8> &getContents() { return Contents; }
     508             :   const SmallString<8> &getContents() const { return Contents; }
     509             : 
     510             :   /// @}
     511             : 
     512             :   static bool classof(const MCFragment *F) {
     513             :     return F->getKind() == MCFragment::FT_LEB;
     514             :   }
     515             : };
     516             : 
     517     1442224 : class MCDwarfLineAddrFragment : public MCFragment {
     518             :   /// LineDelta - the value of the difference between the two line numbers
     519             :   /// between two .loc dwarf directives.
     520             :   int64_t LineDelta;
     521             : 
     522             :   /// AddrDelta - The expression for the difference of the two symbols that
     523             :   /// make up the address delta between two .loc dwarf directives.
     524             :   const MCExpr *AddrDelta;
     525             : 
     526             :   SmallString<8> Contents;
     527             : 
     528             : public:
     529      721112 :   MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
     530             :                           MCSection *Sec = nullptr)
     531      721112 :       : MCFragment(FT_Dwarf, false, Sec), LineDelta(LineDelta),
     532      721112 :         AddrDelta(&AddrDelta) {
     533      721112 :     Contents.push_back(0);
     534      721112 :   }
     535             : 
     536             :   /// \name Accessors
     537             :   /// @{
     538             : 
     539             :   int64_t getLineDelta() const { return LineDelta; }
     540             : 
     541             :   const MCExpr &getAddrDelta() const { return *AddrDelta; }
     542             : 
     543             :   SmallString<8> &getContents() { return Contents; }
     544             :   const SmallString<8> &getContents() const { return Contents; }
     545             : 
     546             :   /// @}
     547             : 
     548             :   static bool classof(const MCFragment *F) {
     549             :     return F->getKind() == MCFragment::FT_Dwarf;
     550             :   }
     551             : };
     552             : 
     553      519098 : class MCDwarfCallFrameFragment : public MCFragment {
     554             :   /// AddrDelta - The expression for the difference of the two symbols that
     555             :   /// make up the address delta between two .cfi_* dwarf directives.
     556             :   const MCExpr *AddrDelta;
     557             : 
     558             :   SmallString<8> Contents;
     559             : 
     560             : public:
     561      259549 :   MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
     562      259549 :       : MCFragment(FT_DwarfFrame, false, Sec), AddrDelta(&AddrDelta) {
     563      259549 :     Contents.push_back(0);
     564      259549 :   }
     565             : 
     566             :   /// \name Accessors
     567             :   /// @{
     568             : 
     569             :   const MCExpr &getAddrDelta() const { return *AddrDelta; }
     570             : 
     571             :   SmallString<8> &getContents() { return Contents; }
     572             :   const SmallString<8> &getContents() const { return Contents; }
     573             : 
     574             :   /// @}
     575             : 
     576             :   static bool classof(const MCFragment *F) {
     577             :     return F->getKind() == MCFragment::FT_DwarfFrame;
     578             :   }
     579             : };
     580             : 
     581             : /// Represents a symbol table index fragment.
     582          12 : class MCSymbolIdFragment : public MCFragment {
     583             :   const MCSymbol *Sym;
     584             : 
     585             : public:
     586             :   MCSymbolIdFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
     587          12 :       : MCFragment(FT_SymbolId, false, Sec), Sym(Sym) {}
     588             : 
     589             :   /// \name Accessors
     590             :   /// @{
     591             : 
     592             :   const MCSymbol *getSymbol() { return Sym; }
     593             :   const MCSymbol *getSymbol() const { return Sym; }
     594             : 
     595             :   /// @}
     596             : 
     597             :   static bool classof(const MCFragment *F) {
     598             :     return F->getKind() == MCFragment::FT_SymbolId;
     599             :   }
     600             : };
     601             : 
     602             : /// Fragment representing the binary annotations produced by the
     603             : /// .cv_inline_linetable directive.
     604          46 : class MCCVInlineLineTableFragment : public MCFragment {
     605             :   unsigned SiteFuncId;
     606             :   unsigned StartFileId;
     607             :   unsigned StartLineNum;
     608             :   const MCSymbol *FnStartSym;
     609             :   const MCSymbol *FnEndSym;
     610             :   SmallString<8> Contents;
     611             : 
     612             :   /// CodeViewContext has the real knowledge about this format, so let it access
     613             :   /// our members.
     614             :   friend class CodeViewContext;
     615             : 
     616             : public:
     617             :   MCCVInlineLineTableFragment(unsigned SiteFuncId, unsigned StartFileId,
     618             :                               unsigned StartLineNum, const MCSymbol *FnStartSym,
     619             :                               const MCSymbol *FnEndSym,
     620             :                               MCSection *Sec = nullptr)
     621          23 :       : MCFragment(FT_CVInlineLines, false, Sec), SiteFuncId(SiteFuncId),
     622             :         StartFileId(StartFileId), StartLineNum(StartLineNum),
     623          23 :         FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}
     624             : 
     625             :   /// \name Accessors
     626             :   /// @{
     627             : 
     628             :   const MCSymbol *getFnStartSym() const { return FnStartSym; }
     629             :   const MCSymbol *getFnEndSym() const { return FnEndSym; }
     630             : 
     631             :   SmallString<8> &getContents() { return Contents; }
     632             :   const SmallString<8> &getContents() const { return Contents; }
     633             : 
     634             :   /// @}
     635             : 
     636             :   static bool classof(const MCFragment *F) {
     637             :     return F->getKind() == MCFragment::FT_CVInlineLines;
     638             :   }
     639             : };
     640             : 
     641             : /// Fragment representing the .cv_def_range directive.
     642         362 : class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> {
     643             :   SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 2> Ranges;
     644             :   SmallString<32> FixedSizePortion;
     645             : 
     646             :   /// CodeViewContext has the real knowledge about this format, so let it access
     647             :   /// our members.
     648             :   friend class CodeViewContext;
     649             : 
     650             : public:
     651         181 :   MCCVDefRangeFragment(
     652             :       ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
     653             :       StringRef FixedSizePortion, MCSection *Sec = nullptr)
     654         181 :       : MCEncodedFragmentWithFixups<32, 4>(FT_CVDefRange, false, Sec),
     655             :         Ranges(Ranges.begin(), Ranges.end()),
     656         181 :         FixedSizePortion(FixedSizePortion) {}
     657             : 
     658             :   /// \name Accessors
     659             :   /// @{
     660             :   ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges() const {
     661             :     return Ranges;
     662             :   }
     663             : 
     664             :   StringRef getFixedSizePortion() const { return FixedSizePortion; }
     665             :   /// @}
     666             : 
     667             :   static bool classof(const MCFragment *F) {
     668             :     return F->getKind() == MCFragment::FT_CVDefRange;
     669             :   }
     670             : };
     671             : 
     672             : } // end namespace llvm
     673             : 
     674             : #endif // LLVM_MC_MCFRAGMENT_H

Generated by: LCOV version 1.13