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

Generated by: LCOV version 1.13