blob: c999c9fc4f17cfdc2b018188d080963884b99864 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- 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
25namespace llvm {
26
27class MCSection;
28class MCSubtargetInfo;
29class MCSymbol;
30
31class MCFragment : public ilist_node_with_parent<MCFragment, MCSection> {
32 friend class MCAsmLayout;
33
34public:
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
52private:
53 FragmentType Kind;
54
55protected:
56 bool HasInstructions;
57
58private:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010059 /// 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
Andrew Scullcdfcccc2018-10-05 20:58:37 +010065 /// Atom - The atom this fragment is in, as represented by its defining
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010066 /// 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
80protected:
81 MCFragment(FragmentType Kind, bool HasInstructions,
Andrew Scullcdfcccc2018-10-05 20:58:37 +010082 MCSection *Parent = nullptr);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010083
84 ~MCFragment();
85
86public:
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 void setParent(MCSection *Value) { Parent = Value; }
101
102 const MCSymbol *getAtom() const { return Atom; }
103 void setAtom(const MCSymbol *Value) { Atom = Value; }
104
105 unsigned getLayoutOrder() const { return LayoutOrder; }
106 void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
107
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100108 /// Does this fragment have instructions emitted into it? By default
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100109 /// this is false, but specific fragment types may set it to true.
110 bool hasInstructions() const { return HasInstructions; }
111
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100112 /// Return true if given frgment has FT_Dummy type.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100113 bool isDummy() const { return Kind == FT_Dummy; }
114
115 void dump() const;
116};
117
118class MCDummyFragment : public MCFragment {
119public:
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100120 explicit MCDummyFragment(MCSection *Sec) : MCFragment(FT_Dummy, false, Sec) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100121
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///
128class MCEncodedFragment : public MCFragment {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100129 /// Should this fragment be aligned to the end of a bundle?
130 bool AlignToBundleEnd = false;
131
132 uint8_t BundlePadding = 0;
133
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100134protected:
135 MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
136 MCSection *Sec)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100137 : 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;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100142
143public:
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:
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100152 case MCFragment::FT_Dwarf:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100153 return true;
154 }
155 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100156
157 /// Should this fragment be placed at the end of an aligned bundle?
158 bool alignToBundleEnd() const { return AlignToBundleEnd; }
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.
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.
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
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.
178 void setHasInstructions(const MCSubtargetInfo &STI) {
179 HasInstructions = true;
180 this->STI = &STI;
181 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100182};
183
184/// Interface implemented by fragments that contain encoded instructions and/or
185/// data.
186///
187template<unsigned ContentsSize>
188class MCEncodedFragmentWithContents : public MCEncodedFragment {
189 SmallVector<char, ContentsSize> Contents;
190
191protected:
192 MCEncodedFragmentWithContents(MCFragment::FragmentType FType,
193 bool HasInstructions,
194 MCSection *Sec)
195 : MCEncodedFragment(FType, HasInstructions, Sec) {}
196
197public:
198 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///
205template<unsigned ContentsSize, unsigned FixupsSize>
206class MCEncodedFragmentWithFixups :
207 public MCEncodedFragmentWithContents<ContentsSize> {
208
209 /// Fixups - The list of fixups in this fragment.
210 SmallVector<MCFixup, FixupsSize> Fixups;
211
212protected:
213 MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
214 bool HasInstructions,
215 MCSection *Sec)
216 : MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions,
217 Sec) {}
218
219public:
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100220
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100221 using const_fixup_iterator = SmallVectorImpl<MCFixup>::const_iterator;
222 using fixup_iterator = SmallVectorImpl<MCFixup>::iterator;
223
224 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 ||
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100236 Kind == MCFragment::FT_CVDefRange || Kind == MCFragment::FT_Dwarf;;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100237 }
238};
239
240/// Fragment for data and encoded instructions.
241///
242class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
243public:
244 MCDataFragment(MCSection *Sec = nullptr)
245 : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
246
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100247 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///
257class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> {
258public:
259 MCCompactEncodedInstFragment(MCSection *Sec = nullptr)
260 : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) {
261 }
262
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///
271class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> {
272
273 /// Inst - The instruction this is a fragment for.
274 MCInst Inst;
275
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100276public:
277 MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
278 MCSection *Sec = nullptr)
279 : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec),
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100280 Inst(Inst) { this->STI = &STI; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100281
282 const MCInst &getInst() const { return Inst; }
283 void setInst(const MCInst &Value) { Inst = Value; }
284
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100285 static bool classof(const MCFragment *F) {
286 return F->getKind() == MCFragment::FT_Relaxable;
287 }
288};
289
290class 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
309public:
310 MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
311 unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100312 : MCFragment(FT_Align, false, Sec), Alignment(Alignment), EmitNops(false),
313 Value(Value), ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100314
315 /// \name Accessors
316 /// @{
317
318 unsigned getAlignment() const { return Alignment; }
319
320 int64_t getValue() const { return Value; }
321
322 unsigned getValueSize() const { return ValueSize; }
323
324 unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
325
326 bool hasEmitNops() const { return EmitNops; }
327 void setEmitNops(bool Value) { EmitNops = Value; }
328
329 /// @}
330
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///
341class 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
368public:
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)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100381 : MCFragment(FT_Padding, false, Sec), PaddingPoliciesMask(PFK_None),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100382 IsInsertionPoint(false), Size(UINT64_C(0)),
383 InstInfo({false, MCInst(), false, {0}}) {}
384
385 bool isInsertionPoint() const { return IsInsertionPoint; }
386 void setAsInsertionPoint() { IsInsertionPoint = true; }
387 uint64_t getPaddingPoliciesMask() const { return PaddingPoliciesMask; }
388 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 return (getPaddingPoliciesMask() & PolicyMask) != PFK_None;
393 }
394 const MCInst &getInst() const {
395 assert(isInstructionInitialized() && "Fragment has no instruction!");
396 return InstInfo.Inst;
397 }
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 }
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 }
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 }
419 uint64_t getSize() const { return Size; }
420 void setSize(uint64_t Value) { Size = Value; }
421 bool isInstructionInitialized() const { return InstInfo.IsInitialized; }
422
423 static bool classof(const MCFragment *F) {
424 return F->getKind() == MCFragment::FT_Padding;
425 }
426};
427
428class MCFillFragment : public MCFragment {
429 /// Value to use for filling bytes.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100430 uint64_t Value;
431 uint8_t ValueSize;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100432 /// The number of bytes to insert.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100433 const MCExpr &NumValues;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100434
435 /// Source location of the directive that this fragment was created for.
436 SMLoc Loc;
437
438public:
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100439 MCFillFragment(uint64_t Value, uint8_t VSize, const MCExpr &NumValues,
440 SMLoc Loc, MCSection *Sec = nullptr)
441 : MCFragment(FT_Fill, false, Sec), Value(Value), ValueSize(VSize),
442 NumValues(NumValues), Loc(Loc) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100443
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100444 uint64_t getValue() const { return Value; }
445 uint8_t getValueSize() const { return ValueSize; }
446 const MCExpr &getNumValues() const { return NumValues; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100447
448 SMLoc getLoc() const { return Loc; }
449
450 static bool classof(const MCFragment *F) {
451 return F->getKind() == MCFragment::FT_Fill;
452 }
453};
454
455class 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
465public:
466 MCOrgFragment(const MCExpr &Offset, int8_t Value, SMLoc Loc,
467 MCSection *Sec = nullptr)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100468 : MCFragment(FT_Org, false, Sec), Offset(&Offset), Value(Value), Loc(Loc) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100469
470 /// \name Accessors
471 /// @{
472
473 const MCExpr &getOffset() const { return *Offset; }
474
475 uint8_t getValue() const { return Value; }
476
477 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
486class 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
495public:
496 MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100497 : MCFragment(FT_LEB, false, Sec), Value(&Value_), IsSigned(IsSigned_) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100498 Contents.push_back(0);
499 }
500
501 /// \name Accessors
502 /// @{
503
504 const MCExpr &getValue() const { return *Value; }
505
506 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
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100518class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100519 /// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100527public:
528 MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
529 MCSection *Sec = nullptr)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100530 : MCEncodedFragmentWithFixups<8, 1>(FT_Dwarf, false, Sec),
531 LineDelta(LineDelta), AddrDelta(&AddrDelta) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100532
533 /// \name Accessors
534 /// @{
535
536 int64_t getLineDelta() const { return LineDelta; }
537
538 const MCExpr &getAddrDelta() const { return *AddrDelta; }
539
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100540 /// @}
541
542 static bool classof(const MCFragment *F) {
543 return F->getKind() == MCFragment::FT_Dwarf;
544 }
545};
546
547class 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
554public:
555 MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100556 : MCFragment(FT_DwarfFrame, false, Sec), AddrDelta(&AddrDelta) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100557 Contents.push_back(0);
558 }
559
560 /// \name Accessors
561 /// @{
562
563 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.
576class MCSymbolIdFragment : public MCFragment {
577 const MCSymbol *Sym;
578
579public:
580 MCSymbolIdFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100581 : MCFragment(FT_SymbolId, false, Sec), Sym(Sym) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100582
583 /// \name Accessors
584 /// @{
585
586 const MCSymbol *getSymbol() { return Sym; }
587 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.
598class 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
610public:
611 MCCVInlineLineTableFragment(unsigned SiteFuncId, unsigned StartFileId,
612 unsigned StartLineNum, const MCSymbol *FnStartSym,
613 const MCSymbol *FnEndSym,
614 MCSection *Sec = nullptr)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100615 : MCFragment(FT_CVInlineLines, false, Sec), SiteFuncId(SiteFuncId),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100616 StartFileId(StartFileId), StartLineNum(StartLineNum),
617 FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}
618
619 /// \name Accessors
620 /// @{
621
622 const MCSymbol *getFnStartSym() const { return FnStartSym; }
623 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.
636class 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
644public:
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 /// @{
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 return F->getKind() == MCFragment::FT_CVDefRange;
663 }
664};
665
666} // end namespace llvm
667
668#endif // LLVM_MC_MCFRAGMENT_H