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