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 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 
getKind()97   FragmentType getKind() const { return Kind; }
98 
getParent()99   MCSection *getParent() const { return Parent; }
setParent(MCSection * Value)100   void setParent(MCSection *Value) { Parent = Value; }
101 
getAtom()102   const MCSymbol *getAtom() const { return Atom; }
setAtom(const MCSymbol * Value)103   void setAtom(const MCSymbol *Value) { Atom = Value; }
104 
getLayoutOrder()105   unsigned getLayoutOrder() const { return LayoutOrder; }
setLayoutOrder(unsigned Value)106   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.
hasInstructions()110   bool hasInstructions() const { return HasInstructions; }
111 
112   /// Return true if given frgment has FT_Dummy type.
isDummy()113   bool isDummy() const { return Kind == FT_Dummy; }
114 
115   void dump() const;
116 };
117 
118 class MCDummyFragment : public MCFragment {
119 public:
MCDummyFragment(MCSection * Sec)120   explicit MCDummyFragment(MCSection *Sec) : MCFragment(FT_Dummy, false, Sec) {}
121 
classof(const MCFragment * F)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:
MCEncodedFragment(MCFragment::FragmentType FType,bool HasInstructions,MCSection * Sec)135   MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
136                     MCSection *Sec)
137       : 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:
classof(const MCFragment * F)144   static bool classof(const MCFragment *F) {
145     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?
alignToBundleEnd()158   bool alignToBundleEnd() const { return AlignToBundleEnd; }
setAlignToBundleEnd(bool V)159   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.
getBundlePadding()166   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.
setBundlePadding(uint8_t N)170   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
getSubtargetInfo()174   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.
setHasInstructions(const MCSubtargetInfo & STI)178   void setHasInstructions(const MCSubtargetInfo &STI) {
179     HasInstructions = true;
180     this->STI = &STI;
181   }
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:
MCEncodedFragmentWithContents(MCFragment::FragmentType FType,bool HasInstructions,MCSection * Sec)192   MCEncodedFragmentWithContents(MCFragment::FragmentType FType,
193                                 bool HasInstructions,
194                                 MCSection *Sec)
195       : MCEncodedFragment(FType, HasInstructions, Sec) {}
196 
197 public:
getContents()198   SmallVectorImpl<char> &getContents() { return Contents; }
getContents()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:
MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,bool HasInstructions,MCSection * Sec)213   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 
getFixups()224   SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
getFixups()225   const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
226 
fixup_begin()227   fixup_iterator fixup_begin() { return Fixups.begin(); }
fixup_begin()228   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
229 
fixup_end()230   fixup_iterator fixup_end() { return Fixups.end(); }
fixup_end()231   const_fixup_iterator fixup_end() const { return Fixups.end(); }
232 
classof(const MCFragment * F)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 class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
243 public:
244   MCDataFragment(MCSection *Sec = nullptr)
245       : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
246 
classof(const MCFragment * F)247   static bool classof(const MCFragment *F) {
248     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 class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> {
258 public:
259   MCCompactEncodedInstFragment(MCSection *Sec = nullptr)
MCEncodedFragmentWithContents(FT_CompactEncodedInst,true,Sec)260       : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) {
261   }
262 
classof(const MCFragment * F)263   static bool classof(const MCFragment *F) {
264     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   MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
278                       MCSection *Sec = nullptr)
MCEncodedFragmentWithFixups(FT_Relaxable,true,Sec)279       : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec),
280         Inst(Inst) { this->STI = &STI; }
281 
getInst()282   const MCInst &getInst() const { return Inst; }
setInst(const MCInst & Value)283   void setInst(const MCInst &Value) { Inst = Value; }
284 
classof(const MCFragment * F)285   static bool classof(const MCFragment *F) {
286     return F->getKind() == MCFragment::FT_Relaxable;
287   }
288 };
289 
290 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)
MCFragment(FT_Align,false,Sec)312       : MCFragment(FT_Align, false, Sec), Alignment(Alignment), EmitNops(false),
313         Value(Value), ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
314 
315   /// \name Accessors
316   /// @{
317 
getAlignment()318   unsigned getAlignment() const { return Alignment; }
319 
getValue()320   int64_t getValue() const { return Value; }
321 
getValueSize()322   unsigned getValueSize() const { return ValueSize; }
323 
getMaxBytesToEmit()324   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
325 
hasEmitNops()326   bool hasEmitNops() const { return EmitNops; }
setEmitNops(bool Value)327   void setEmitNops(bool Value) { EmitNops = Value; }
328 
329   /// @}
330 
classof(const MCFragment * F)331   static bool classof(const MCFragment *F) {
332     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   MCPaddingFragment(MCSection *Sec = nullptr)
MCFragment(FT_Padding,false,Sec)381       : MCFragment(FT_Padding, false, Sec), PaddingPoliciesMask(PFK_None),
382         IsInsertionPoint(false), Size(UINT64_C(0)),
383         InstInfo({false, MCInst(), false, {0}}) {}
384 
isInsertionPoint()385   bool isInsertionPoint() const { return IsInsertionPoint; }
setAsInsertionPoint()386   void setAsInsertionPoint() { IsInsertionPoint = true; }
getPaddingPoliciesMask()387   uint64_t getPaddingPoliciesMask() const { return PaddingPoliciesMask; }
setPaddingPoliciesMask(uint64_t Value)388   void setPaddingPoliciesMask(uint64_t Value) { PaddingPoliciesMask = Value; }
hasPaddingPolicy(uint64_t PolicyMask)389   bool hasPaddingPolicy(uint64_t PolicyMask) const {
390     assert(isPowerOf2_64(PolicyMask) &&
391            "Policy mask must contain exactly one policy");
392     return (getPaddingPoliciesMask() & PolicyMask) != PFK_None;
393   }
getInst()394   const MCInst &getInst() const {
395     assert(isInstructionInitialized() && "Fragment has no instruction!");
396     return InstInfo.Inst;
397   }
getInstSize()398   size_t getInstSize() const {
399     assert(isInstructionInitialized() && "Fragment has no instruction!");
400     if (InstInfo.IsImmutableSizedInst)
401       return InstInfo.InstSize;
402     assert(InstInfo.InstFragment != nullptr &&
403            "Must have a valid InstFragment to retrieve InstSize from");
404     return InstInfo.InstFragment->getContents().size();
405   }
setInstAndInstSize(const MCInst & Inst,size_t InstSize)406   void setInstAndInstSize(const MCInst &Inst, size_t InstSize) {
407 	InstInfo.IsInitialized = true;
408     InstInfo.IsImmutableSizedInst = true;
409     InstInfo.Inst = Inst;
410     InstInfo.InstSize = InstSize;
411   }
setInstAndInstFragment(const MCInst & Inst,MCRelaxableFragment * InstFragment)412   void setInstAndInstFragment(const MCInst &Inst,
413                               MCRelaxableFragment *InstFragment) {
414     InstInfo.IsInitialized = true;
415     InstInfo.IsImmutableSizedInst = false;
416     InstInfo.Inst = Inst;
417     InstInfo.InstFragment = InstFragment;
418   }
getSize()419   uint64_t getSize() const { return Size; }
setSize(uint64_t Value)420   void setSize(uint64_t Value) { Size = Value; }
isInstructionInitialized()421   bool isInstructionInitialized() const { return InstInfo.IsInitialized; }
422 
classof(const MCFragment * F)423   static bool classof(const MCFragment *F) {
424     return F->getKind() == MCFragment::FT_Padding;
425   }
426 };
427 
428 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)
MCFragment(FT_Fill,false,Sec)441       : MCFragment(FT_Fill, false, Sec), Value(Value), ValueSize(VSize),
442         NumValues(NumValues), Loc(Loc) {}
443 
getValue()444   uint64_t getValue() const { return Value; }
getValueSize()445   uint8_t getValueSize() const { return ValueSize; }
getNumValues()446   const MCExpr &getNumValues() const { return NumValues; }
447 
getLoc()448   SMLoc getLoc() const { return Loc; }
449 
classof(const MCFragment * F)450   static bool classof(const MCFragment *F) {
451     return F->getKind() == MCFragment::FT_Fill;
452   }
453 };
454 
455 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)
MCFragment(FT_Org,false,Sec)468       : MCFragment(FT_Org, false, Sec), Offset(&Offset), Value(Value), Loc(Loc) {}
469 
470   /// \name Accessors
471   /// @{
472 
getOffset()473   const MCExpr &getOffset() const { return *Offset; }
474 
getValue()475   uint8_t getValue() const { return Value; }
476 
getLoc()477   SMLoc getLoc() const { return Loc; }
478 
479   /// @}
480 
classof(const MCFragment * F)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   MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
MCFragment(FT_LEB,false,Sec)497       : MCFragment(FT_LEB, false, Sec), Value(&Value_), IsSigned(IsSigned_) {
498     Contents.push_back(0);
499   }
500 
501   /// \name Accessors
502   /// @{
503 
getValue()504   const MCExpr &getValue() const { return *Value; }
505 
isSigned()506   bool isSigned() const { return IsSigned; }
507 
getContents()508   SmallString<8> &getContents() { return Contents; }
getContents()509   const SmallString<8> &getContents() const { return Contents; }
510 
511   /// @}
512 
classof(const MCFragment * F)513   static bool classof(const MCFragment *F) {
514     return F->getKind() == MCFragment::FT_LEB;
515   }
516 };
517 
518 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       : MCEncodedFragmentWithFixups<8, 1>(FT_Dwarf, false, Sec),
531         LineDelta(LineDelta), AddrDelta(&AddrDelta) {}
532 
533   /// \name Accessors
534   /// @{
535 
getLineDelta()536   int64_t getLineDelta() const { return LineDelta; }
537 
getAddrDelta()538   const MCExpr &getAddrDelta() const { return *AddrDelta; }
539 
540   /// @}
541 
classof(const MCFragment * F)542   static bool classof(const MCFragment *F) {
543     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   MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
MCFragment(FT_DwarfFrame,false,Sec)556       : MCFragment(FT_DwarfFrame, false, Sec), AddrDelta(&AddrDelta) {
557     Contents.push_back(0);
558   }
559 
560   /// \name Accessors
561   /// @{
562 
getAddrDelta()563   const MCExpr &getAddrDelta() const { return *AddrDelta; }
564 
getContents()565   SmallString<8> &getContents() { return Contents; }
getContents()566   const SmallString<8> &getContents() const { return Contents; }
567 
568   /// @}
569 
classof(const MCFragment * F)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 class MCSymbolIdFragment : public MCFragment {
577   const MCSymbol *Sym;
578 
579 public:
580   MCSymbolIdFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
MCFragment(FT_SymbolId,false,Sec)581       : MCFragment(FT_SymbolId, false, Sec), Sym(Sym) {}
582 
583   /// \name Accessors
584   /// @{
585 
getSymbol()586   const MCSymbol *getSymbol() { return Sym; }
getSymbol()587   const MCSymbol *getSymbol() const { return Sym; }
588 
589   /// @}
590 
classof(const MCFragment * F)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)
MCFragment(FT_CVInlineLines,false,Sec)615       : MCFragment(FT_CVInlineLines, false, Sec), SiteFuncId(SiteFuncId),
616         StartFileId(StartFileId), StartLineNum(StartLineNum),
617         FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}
618 
619   /// \name Accessors
620   /// @{
621 
getFnStartSym()622   const MCSymbol *getFnStartSym() const { return FnStartSym; }
getFnEndSym()623   const MCSymbol *getFnEndSym() const { return FnEndSym; }
624 
getContents()625   SmallString<8> &getContents() { return Contents; }
getContents()626   const SmallString<8> &getContents() const { return Contents; }
627 
628   /// @}
629 
classof(const MCFragment * F)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   MCCVDefRangeFragment(
646       ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
647       StringRef FixedSizePortion, MCSection *Sec = nullptr)
648       : MCEncodedFragmentWithFixups<32, 4>(FT_CVDefRange, false, Sec),
649         Ranges(Ranges.begin(), Ranges.end()),
650         FixedSizePortion(FixedSizePortion) {}
651 
652   /// \name Accessors
653   /// @{
getRanges()654   ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges() const {
655     return Ranges;
656   }
657 
getFixedSizePortion()658   StringRef getFixedSizePortion() const { return FixedSizePortion; }
659   /// @}
660 
classof(const MCFragment * F)661   static bool classof(const MCFragment *F) {
662     return F->getKind() == MCFragment::FT_CVDefRange;
663   }
664 };
665 
666 } // end namespace llvm
667 
668 #endif // LLVM_MC_MCFRAGMENT_H
669