MCFragment.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- MCFragment.h - Fragment type hierarchy -------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_MC_MCFRAGMENT_H
  14. #define LLVM_MC_MCFRAGMENT_H
  15. #include "llvm/ADT/ArrayRef.h"
  16. #include "llvm/ADT/SmallString.h"
  17. #include "llvm/ADT/SmallVector.h"
  18. #include "llvm/ADT/StringRef.h"
  19. #include "llvm/ADT/ilist_node.h"
  20. #include "llvm/MC/MCFixup.h"
  21. #include "llvm/MC/MCInst.h"
  22. #include "llvm/Support/Alignment.h"
  23. #include "llvm/Support/SMLoc.h"
  24. #include <cstdint>
  25. #include <utility>
  26. namespace llvm {
  27. class MCSection;
  28. class MCSubtargetInfo;
  29. class MCSymbol;
  30. class MCFragment : public ilist_node_with_parent<MCFragment, MCSection> {
  31. friend class MCAsmLayout;
  32. public:
  33. enum FragmentType : uint8_t {
  34. FT_Align,
  35. FT_Data,
  36. FT_CompactEncodedInst,
  37. FT_Fill,
  38. FT_Nops,
  39. FT_Relaxable,
  40. FT_Org,
  41. FT_Dwarf,
  42. FT_DwarfFrame,
  43. FT_LEB,
  44. FT_BoundaryAlign,
  45. FT_SymbolId,
  46. FT_CVInlineLines,
  47. FT_CVDefRange,
  48. FT_PseudoProbe,
  49. FT_Dummy
  50. };
  51. private:
  52. /// The data for the section this fragment is in.
  53. MCSection *Parent;
  54. /// The atom this fragment is in, as represented by its defining symbol.
  55. const MCSymbol *Atom;
  56. /// The offset of this fragment in its section. This is ~0 until
  57. /// initialized.
  58. uint64_t Offset;
  59. /// The layout order of this fragment.
  60. unsigned LayoutOrder;
  61. /// The subsection this fragment belongs to. This is 0 if the fragment is not
  62. // in any subsection.
  63. unsigned SubsectionNumber = 0;
  64. FragmentType Kind;
  65. /// Whether fragment is being laid out.
  66. bool IsBeingLaidOut;
  67. protected:
  68. bool HasInstructions;
  69. MCFragment(FragmentType Kind, bool HasInstructions,
  70. MCSection *Parent = nullptr);
  71. public:
  72. MCFragment() = delete;
  73. MCFragment(const MCFragment &) = delete;
  74. MCFragment &operator=(const MCFragment &) = delete;
  75. /// Destroys the current fragment.
  76. ///
  77. /// This must be used instead of delete as MCFragment is non-virtual.
  78. /// This method will dispatch to the appropriate subclass.
  79. void destroy();
  80. FragmentType getKind() const { return Kind; }
  81. MCSection *getParent() const { return Parent; }
  82. void setParent(MCSection *Value) { Parent = Value; }
  83. const MCSymbol *getAtom() const { return Atom; }
  84. void setAtom(const MCSymbol *Value) { Atom = Value; }
  85. unsigned getLayoutOrder() const { return LayoutOrder; }
  86. void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
  87. /// Does this fragment have instructions emitted into it? By default
  88. /// this is false, but specific fragment types may set it to true.
  89. bool hasInstructions() const { return HasInstructions; }
  90. void dump() const;
  91. void setSubsectionNumber(unsigned Value) { SubsectionNumber = Value; }
  92. unsigned getSubsectionNumber() const { return SubsectionNumber; }
  93. };
  94. class MCDummyFragment : public MCFragment {
  95. public:
  96. explicit MCDummyFragment(MCSection *Sec) : MCFragment(FT_Dummy, false, Sec) {}
  97. static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; }
  98. };
  99. /// Interface implemented by fragments that contain encoded instructions and/or
  100. /// data.
  101. ///
  102. class MCEncodedFragment : public MCFragment {
  103. /// Should this fragment be aligned to the end of a bundle?
  104. bool AlignToBundleEnd = false;
  105. uint8_t BundlePadding = 0;
  106. protected:
  107. MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
  108. MCSection *Sec)
  109. : MCFragment(FType, HasInstructions, Sec) {}
  110. /// The MCSubtargetInfo in effect when the instruction was encoded.
  111. /// It must be non-null for instructions.
  112. const MCSubtargetInfo *STI = nullptr;
  113. public:
  114. static bool classof(const MCFragment *F) {
  115. MCFragment::FragmentType Kind = F->getKind();
  116. switch (Kind) {
  117. default:
  118. return false;
  119. case MCFragment::FT_Relaxable:
  120. case MCFragment::FT_CompactEncodedInst:
  121. case MCFragment::FT_Data:
  122. case MCFragment::FT_Dwarf:
  123. case MCFragment::FT_DwarfFrame:
  124. case MCFragment::FT_PseudoProbe:
  125. return true;
  126. }
  127. }
  128. /// Should this fragment be placed at the end of an aligned bundle?
  129. bool alignToBundleEnd() const { return AlignToBundleEnd; }
  130. void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
  131. /// Get the padding size that must be inserted before this fragment.
  132. /// Used for bundling. By default, no padding is inserted.
  133. /// Note that padding size is restricted to 8 bits. This is an optimization
  134. /// to reduce the amount of space used for each fragment. In practice, larger
  135. /// padding should never be required.
  136. uint8_t getBundlePadding() const { return BundlePadding; }
  137. /// Set the padding size for this fragment. By default it's a no-op,
  138. /// and only some fragments have a meaningful implementation.
  139. void setBundlePadding(uint8_t N) { BundlePadding = N; }
  140. /// Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
  141. /// Guaranteed to be non-null if hasInstructions() == true
  142. const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
  143. /// Record that the fragment contains instructions with the MCSubtargetInfo in
  144. /// effect when the instruction was encoded.
  145. void setHasInstructions(const MCSubtargetInfo &STI) {
  146. HasInstructions = true;
  147. this->STI = &STI;
  148. }
  149. };
  150. /// Interface implemented by fragments that contain encoded instructions and/or
  151. /// data.
  152. ///
  153. template<unsigned ContentsSize>
  154. class MCEncodedFragmentWithContents : public MCEncodedFragment {
  155. SmallVector<char, ContentsSize> Contents;
  156. protected:
  157. MCEncodedFragmentWithContents(MCFragment::FragmentType FType,
  158. bool HasInstructions,
  159. MCSection *Sec)
  160. : MCEncodedFragment(FType, HasInstructions, Sec) {}
  161. public:
  162. SmallVectorImpl<char> &getContents() { return Contents; }
  163. const SmallVectorImpl<char> &getContents() const { return Contents; }
  164. };
  165. /// Interface implemented by fragments that contain encoded instructions and/or
  166. /// data and also have fixups registered.
  167. ///
  168. template<unsigned ContentsSize, unsigned FixupsSize>
  169. class MCEncodedFragmentWithFixups :
  170. public MCEncodedFragmentWithContents<ContentsSize> {
  171. /// The list of fixups in this fragment.
  172. SmallVector<MCFixup, FixupsSize> Fixups;
  173. protected:
  174. MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
  175. bool HasInstructions,
  176. MCSection *Sec)
  177. : MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions,
  178. Sec) {}
  179. public:
  180. using const_fixup_iterator = SmallVectorImpl<MCFixup>::const_iterator;
  181. using fixup_iterator = SmallVectorImpl<MCFixup>::iterator;
  182. SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
  183. const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
  184. fixup_iterator fixup_begin() { return Fixups.begin(); }
  185. const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
  186. fixup_iterator fixup_end() { return Fixups.end(); }
  187. const_fixup_iterator fixup_end() const { return Fixups.end(); }
  188. static bool classof(const MCFragment *F) {
  189. MCFragment::FragmentType Kind = F->getKind();
  190. return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||
  191. Kind == MCFragment::FT_CVDefRange || Kind == MCFragment::FT_Dwarf ||
  192. Kind == MCFragment::FT_DwarfFrame;
  193. }
  194. };
  195. /// Fragment for data and encoded instructions.
  196. ///
  197. class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
  198. public:
  199. MCDataFragment(MCSection *Sec = nullptr)
  200. : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
  201. static bool classof(const MCFragment *F) {
  202. return F->getKind() == MCFragment::FT_Data;
  203. }
  204. };
  205. /// This is a compact (memory-size-wise) fragment for holding an encoded
  206. /// instruction (non-relaxable) that has no fixups registered. When applicable,
  207. /// it can be used instead of MCDataFragment and lead to lower memory
  208. /// consumption.
  209. ///
  210. class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> {
  211. public:
  212. MCCompactEncodedInstFragment(MCSection *Sec = nullptr)
  213. : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) {
  214. }
  215. static bool classof(const MCFragment *F) {
  216. return F->getKind() == MCFragment::FT_CompactEncodedInst;
  217. }
  218. };
  219. /// A relaxable fragment holds on to its MCInst, since it may need to be
  220. /// relaxed during the assembler layout and relaxation stage.
  221. ///
  222. class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> {
  223. /// The instruction this is a fragment for.
  224. MCInst Inst;
  225. /// Can we auto pad the instruction?
  226. bool AllowAutoPadding = false;
  227. public:
  228. MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
  229. MCSection *Sec = nullptr)
  230. : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec),
  231. Inst(Inst) { this->STI = &STI; }
  232. const MCInst &getInst() const { return Inst; }
  233. void setInst(const MCInst &Value) { Inst = Value; }
  234. bool getAllowAutoPadding() const { return AllowAutoPadding; }
  235. void setAllowAutoPadding(bool V) { AllowAutoPadding = V; }
  236. static bool classof(const MCFragment *F) {
  237. return F->getKind() == MCFragment::FT_Relaxable;
  238. }
  239. };
  240. class MCAlignFragment : public MCFragment {
  241. /// The alignment to ensure, in bytes.
  242. Align Alignment;
  243. /// Flag to indicate that (optimal) NOPs should be emitted instead
  244. /// of using the provided value. The exact interpretation of this flag is
  245. /// target dependent.
  246. bool EmitNops : 1;
  247. /// Value to use for filling padding bytes.
  248. int64_t Value;
  249. /// The size of the integer (in bytes) of \p Value.
  250. unsigned ValueSize;
  251. /// The maximum number of bytes to emit; if the alignment
  252. /// cannot be satisfied in this width then this fragment is ignored.
  253. unsigned MaxBytesToEmit;
  254. /// When emitting Nops some subtargets have specific nop encodings.
  255. const MCSubtargetInfo *STI;
  256. public:
  257. MCAlignFragment(Align Alignment, int64_t Value, unsigned ValueSize,
  258. unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
  259. : MCFragment(FT_Align, false, Sec), Alignment(Alignment), EmitNops(false),
  260. Value(Value), ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
  261. Align getAlignment() const { return Alignment; }
  262. int64_t getValue() const { return Value; }
  263. unsigned getValueSize() const { return ValueSize; }
  264. unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
  265. bool hasEmitNops() const { return EmitNops; }
  266. void setEmitNops(bool Value, const MCSubtargetInfo *STI) {
  267. EmitNops = Value;
  268. this->STI = STI;
  269. }
  270. const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
  271. static bool classof(const MCFragment *F) {
  272. return F->getKind() == MCFragment::FT_Align;
  273. }
  274. };
  275. class MCFillFragment : public MCFragment {
  276. uint8_t ValueSize;
  277. /// Value to use for filling bytes.
  278. uint64_t Value;
  279. /// The number of bytes to insert.
  280. const MCExpr &NumValues;
  281. /// Source location of the directive that this fragment was created for.
  282. SMLoc Loc;
  283. public:
  284. MCFillFragment(uint64_t Value, uint8_t VSize, const MCExpr &NumValues,
  285. SMLoc Loc, MCSection *Sec = nullptr)
  286. : MCFragment(FT_Fill, false, Sec), ValueSize(VSize), Value(Value),
  287. NumValues(NumValues), Loc(Loc) {}
  288. uint64_t getValue() const { return Value; }
  289. uint8_t getValueSize() const { return ValueSize; }
  290. const MCExpr &getNumValues() const { return NumValues; }
  291. SMLoc getLoc() const { return Loc; }
  292. static bool classof(const MCFragment *F) {
  293. return F->getKind() == MCFragment::FT_Fill;
  294. }
  295. };
  296. class MCNopsFragment : public MCFragment {
  297. /// The number of bytes to insert.
  298. int64_t Size;
  299. /// Maximum number of bytes allowed in each NOP instruction.
  300. int64_t ControlledNopLength;
  301. /// Source location of the directive that this fragment was created for.
  302. SMLoc Loc;
  303. /// When emitting Nops some subtargets have specific nop encodings.
  304. const MCSubtargetInfo &STI;
  305. public:
  306. MCNopsFragment(int64_t NumBytes, int64_t ControlledNopLength, SMLoc L,
  307. const MCSubtargetInfo &STI, MCSection *Sec = nullptr)
  308. : MCFragment(FT_Nops, false, Sec), Size(NumBytes),
  309. ControlledNopLength(ControlledNopLength), Loc(L), STI(STI) {}
  310. int64_t getNumBytes() const { return Size; }
  311. int64_t getControlledNopLength() const { return ControlledNopLength; }
  312. SMLoc getLoc() const { return Loc; }
  313. const MCSubtargetInfo *getSubtargetInfo() const { return &STI; }
  314. static bool classof(const MCFragment *F) {
  315. return F->getKind() == MCFragment::FT_Nops;
  316. }
  317. };
  318. class MCOrgFragment : public MCFragment {
  319. /// Value to use for filling bytes.
  320. int8_t Value;
  321. /// The offset this fragment should start at.
  322. const MCExpr *Offset;
  323. /// Source location of the directive that this fragment was created for.
  324. SMLoc Loc;
  325. public:
  326. MCOrgFragment(const MCExpr &Offset, int8_t Value, SMLoc Loc,
  327. MCSection *Sec = nullptr)
  328. : MCFragment(FT_Org, false, Sec), Value(Value), Offset(&Offset),
  329. Loc(Loc) {}
  330. const MCExpr &getOffset() const { return *Offset; }
  331. uint8_t getValue() const { return Value; }
  332. SMLoc getLoc() const { return Loc; }
  333. static bool classof(const MCFragment *F) {
  334. return F->getKind() == MCFragment::FT_Org;
  335. }
  336. };
  337. class MCLEBFragment : public MCFragment {
  338. /// True if this is a sleb128, false if uleb128.
  339. bool IsSigned;
  340. /// The value this fragment should contain.
  341. const MCExpr *Value;
  342. SmallString<8> Contents;
  343. public:
  344. MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
  345. : MCFragment(FT_LEB, false, Sec), IsSigned(IsSigned_), Value(&Value_) {
  346. Contents.push_back(0);
  347. }
  348. const MCExpr &getValue() const { return *Value; }
  349. bool isSigned() const { return IsSigned; }
  350. SmallString<8> &getContents() { return Contents; }
  351. const SmallString<8> &getContents() const { return Contents; }
  352. /// @}
  353. static bool classof(const MCFragment *F) {
  354. return F->getKind() == MCFragment::FT_LEB;
  355. }
  356. };
  357. class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
  358. /// The value of the difference between the two line numbers
  359. /// between two .loc dwarf directives.
  360. int64_t LineDelta;
  361. /// The expression for the difference of the two symbols that
  362. /// make up the address delta between two .loc dwarf directives.
  363. const MCExpr *AddrDelta;
  364. public:
  365. MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
  366. MCSection *Sec = nullptr)
  367. : MCEncodedFragmentWithFixups<8, 1>(FT_Dwarf, false, Sec),
  368. LineDelta(LineDelta), AddrDelta(&AddrDelta) {}
  369. int64_t getLineDelta() const { return LineDelta; }
  370. const MCExpr &getAddrDelta() const { return *AddrDelta; }
  371. static bool classof(const MCFragment *F) {
  372. return F->getKind() == MCFragment::FT_Dwarf;
  373. }
  374. };
  375. class MCDwarfCallFrameFragment : public MCEncodedFragmentWithFixups<8, 1> {
  376. /// The expression for the difference of the two symbols that
  377. /// make up the address delta between two .cfi_* dwarf directives.
  378. const MCExpr *AddrDelta;
  379. public:
  380. MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
  381. : MCEncodedFragmentWithFixups<8, 1>(FT_DwarfFrame, false, Sec),
  382. AddrDelta(&AddrDelta) {}
  383. const MCExpr &getAddrDelta() const { return *AddrDelta; }
  384. static bool classof(const MCFragment *F) {
  385. return F->getKind() == MCFragment::FT_DwarfFrame;
  386. }
  387. };
  388. /// Represents a symbol table index fragment.
  389. class MCSymbolIdFragment : public MCFragment {
  390. const MCSymbol *Sym;
  391. public:
  392. MCSymbolIdFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
  393. : MCFragment(FT_SymbolId, false, Sec), Sym(Sym) {}
  394. const MCSymbol *getSymbol() { return Sym; }
  395. const MCSymbol *getSymbol() const { return Sym; }
  396. static bool classof(const MCFragment *F) {
  397. return F->getKind() == MCFragment::FT_SymbolId;
  398. }
  399. };
  400. /// Fragment representing the binary annotations produced by the
  401. /// .cv_inline_linetable directive.
  402. class MCCVInlineLineTableFragment : public MCFragment {
  403. unsigned SiteFuncId;
  404. unsigned StartFileId;
  405. unsigned StartLineNum;
  406. const MCSymbol *FnStartSym;
  407. const MCSymbol *FnEndSym;
  408. SmallString<8> Contents;
  409. /// CodeViewContext has the real knowledge about this format, so let it access
  410. /// our members.
  411. friend class CodeViewContext;
  412. public:
  413. MCCVInlineLineTableFragment(unsigned SiteFuncId, unsigned StartFileId,
  414. unsigned StartLineNum, const MCSymbol *FnStartSym,
  415. const MCSymbol *FnEndSym,
  416. MCSection *Sec = nullptr)
  417. : MCFragment(FT_CVInlineLines, false, Sec), SiteFuncId(SiteFuncId),
  418. StartFileId(StartFileId), StartLineNum(StartLineNum),
  419. FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}
  420. const MCSymbol *getFnStartSym() const { return FnStartSym; }
  421. const MCSymbol *getFnEndSym() const { return FnEndSym; }
  422. SmallString<8> &getContents() { return Contents; }
  423. const SmallString<8> &getContents() const { return Contents; }
  424. static bool classof(const MCFragment *F) {
  425. return F->getKind() == MCFragment::FT_CVInlineLines;
  426. }
  427. };
  428. /// Fragment representing the .cv_def_range directive.
  429. class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> {
  430. SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 2> Ranges;
  431. SmallString<32> FixedSizePortion;
  432. /// CodeViewContext has the real knowledge about this format, so let it access
  433. /// our members.
  434. friend class CodeViewContext;
  435. public:
  436. MCCVDefRangeFragment(
  437. ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
  438. StringRef FixedSizePortion, MCSection *Sec = nullptr)
  439. : MCEncodedFragmentWithFixups<32, 4>(FT_CVDefRange, false, Sec),
  440. Ranges(Ranges.begin(), Ranges.end()),
  441. FixedSizePortion(FixedSizePortion) {}
  442. ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges() const {
  443. return Ranges;
  444. }
  445. StringRef getFixedSizePortion() const { return FixedSizePortion.str(); }
  446. static bool classof(const MCFragment *F) {
  447. return F->getKind() == MCFragment::FT_CVDefRange;
  448. }
  449. };
  450. /// Represents required padding such that a particular other set of fragments
  451. /// does not cross a particular power-of-two boundary. The other fragments must
  452. /// follow this one within the same section.
  453. class MCBoundaryAlignFragment : public MCFragment {
  454. /// The alignment requirement of the branch to be aligned.
  455. Align AlignBoundary;
  456. /// The last fragment in the set of fragments to be aligned.
  457. const MCFragment *LastFragment = nullptr;
  458. /// The size of the fragment. The size is lazily set during relaxation, and
  459. /// is not meaningful before that.
  460. uint64_t Size = 0;
  461. /// When emitting Nops some subtargets have specific nop encodings.
  462. const MCSubtargetInfo &STI;
  463. public:
  464. MCBoundaryAlignFragment(Align AlignBoundary, const MCSubtargetInfo &STI,
  465. MCSection *Sec = nullptr)
  466. : MCFragment(FT_BoundaryAlign, false, Sec), AlignBoundary(AlignBoundary),
  467. STI(STI) {}
  468. uint64_t getSize() const { return Size; }
  469. void setSize(uint64_t Value) { Size = Value; }
  470. Align getAlignment() const { return AlignBoundary; }
  471. void setAlignment(Align Value) { AlignBoundary = Value; }
  472. const MCFragment *getLastFragment() const { return LastFragment; }
  473. void setLastFragment(const MCFragment *F) {
  474. assert(!F || getParent() == F->getParent());
  475. LastFragment = F;
  476. }
  477. const MCSubtargetInfo *getSubtargetInfo() const { return &STI; }
  478. static bool classof(const MCFragment *F) {
  479. return F->getKind() == MCFragment::FT_BoundaryAlign;
  480. }
  481. };
  482. class MCPseudoProbeAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
  483. /// The expression for the difference of the two symbols that
  484. /// make up the address delta between two .pseudoprobe directives.
  485. const MCExpr *AddrDelta;
  486. public:
  487. MCPseudoProbeAddrFragment(const MCExpr *AddrDelta, MCSection *Sec = nullptr)
  488. : MCEncodedFragmentWithFixups<8, 1>(FT_PseudoProbe, false, Sec),
  489. AddrDelta(AddrDelta) {}
  490. const MCExpr &getAddrDelta() const { return *AddrDelta; }
  491. static bool classof(const MCFragment *F) {
  492. return F->getKind() == MCFragment::FT_PseudoProbe;
  493. }
  494. };
  495. } // end namespace llvm
  496. #endif // LLVM_MC_MCFRAGMENT_H
  497. #ifdef __GNUC__
  498. #pragma GCC diagnostic pop
  499. #endif