LLVM 19.0.0git
MCAsmStreamer.cpp
Go to the documentation of this file.
1//===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output ----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "llvm/ADT/Twine.h"
14#include "llvm/MC/MCAsmInfo.h"
15#include "llvm/MC/MCAssembler.h"
17#include "llvm/MC/MCCodeView.h"
18#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCExpr.h"
21#include "llvm/MC/MCInst.h"
26#include "llvm/MC/MCRegister.h"
29#include "llvm/MC/MCStreamer.h"
34#include "llvm/Support/Format.h"
36#include "llvm/Support/LEB128.h"
38#include "llvm/Support/Path.h"
39#include <algorithm>
40#include <optional>
41
42using namespace llvm;
43
44namespace {
45
46class MCAsmStreamer final : public MCStreamer {
47 std::unique_ptr<formatted_raw_ostream> OSOwner;
49 const MCAsmInfo *MAI;
50 std::unique_ptr<MCInstPrinter> InstPrinter;
51 std::unique_ptr<MCAssembler> Assembler;
52
53 SmallString<128> ExplicitCommentToEmit;
54 SmallString<128> CommentToEmit;
55 raw_svector_ostream CommentStream;
56 raw_null_ostream NullStream;
57
58 unsigned IsVerboseAsm : 1;
59 unsigned ShowInst : 1;
60 unsigned UseDwarfDirectory : 1;
61
62 void EmitRegisterName(int64_t Register);
63 void PrintQuotedString(StringRef Data, raw_ostream &OS) const;
64 void printDwarfFileDirective(unsigned FileNo, StringRef Directory,
65 StringRef Filename,
66 std::optional<MD5::MD5Result> Checksum,
67 std::optional<StringRef> Source,
68 bool UseDwarfDirectory,
69 raw_svector_ostream &OS) const;
70 void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
71 void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
72
73public:
74 MCAsmStreamer(MCContext &Context, std::unique_ptr<formatted_raw_ostream> os,
75 bool isVerboseAsm, bool useDwarfDirectory,
76 MCInstPrinter *printer, std::unique_ptr<MCCodeEmitter> emitter,
77 std::unique_ptr<MCAsmBackend> asmbackend, bool showInst)
78 : MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner),
79 MAI(Context.getAsmInfo()), InstPrinter(printer),
80 Assembler(std::make_unique<MCAssembler>(
81 Context, std::move(asmbackend), std::move(emitter),
82 (asmbackend) ? asmbackend->createObjectWriter(NullStream)
83 : nullptr)),
84 CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
85 ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) {
86 assert(InstPrinter);
87 if (IsVerboseAsm)
88 InstPrinter->setCommentStream(CommentStream);
89 if (Assembler->getBackendPtr())
90 setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
91
92 Context.setUseNamesOnTempLabels(true);
93 }
94
95 MCAssembler &getAssembler() { return *Assembler; }
96 MCAssembler *getAssemblerPtr() override { return nullptr; }
97
98 inline void EmitEOL() {
99 // Dump Explicit Comments here.
101 // If we don't have any comments, just emit a \n.
102 if (!IsVerboseAsm) {
103 OS << '\n';
104 return;
105 }
106 EmitCommentsAndEOL();
107 }
108
109 void emitSyntaxDirective() override;
110
111 void EmitCommentsAndEOL();
112
113 /// Return true if this streamer supports verbose assembly at all.
114 bool isVerboseAsm() const override { return IsVerboseAsm; }
115
116 /// Do we support EmitRawText?
117 bool hasRawTextSupport() const override { return true; }
118
119 /// Add a comment that can be emitted to the generated .s file to make the
120 /// output of the compiler more readable. This only affects the MCAsmStreamer
121 /// and only when verbose assembly output is enabled.
122 void AddComment(const Twine &T, bool EOL = true) override;
123
124 /// Add a comment showing the encoding of an instruction.
125 void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &);
126
127 /// Return a raw_ostream that comments can be written to.
128 /// Unlike AddComment, you are required to terminate comments with \n if you
129 /// use this method.
130 raw_ostream &getCommentOS() override {
131 if (!IsVerboseAsm)
132 return nulls(); // Discard comments unless in verbose asm mode.
133 return CommentStream;
134 }
135
136 void emitRawComment(const Twine &T, bool TabPrefix = true) override;
137
138 void addExplicitComment(const Twine &T) override;
139 void emitExplicitComments() override;
140
141 /// Emit a blank line to a .s file to pretty it up.
142 void addBlankLine() override { EmitEOL(); }
143
144 /// @name MCStreamer Interface
145 /// @{
146
147 void changeSection(MCSection *Section, uint32_t Subsection) override;
148
149 void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name,
150 bool KeepOriginalSym) override;
151
152 void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
153
154 void emitGNUAttribute(unsigned Tag, unsigned Value) override;
155
156 StringRef getMnemonic(MCInst &MI) override {
157 auto [Ptr, Bits] = InstPrinter->getMnemonic(&MI);
158 assert((Bits != 0 || Ptr == nullptr) &&
159 "Invalid char pointer for instruction with no mnemonic");
160 return Ptr;
161 }
162
163 void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
164
165 void emitAssemblerFlag(MCAssemblerFlag Flag) override;
167 void emitDataRegion(MCDataRegionType Kind) override;
168 void emitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
169 unsigned Update, VersionTuple SDKVersion) override;
170 void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor,
171 unsigned Update, VersionTuple SDKVersion) override;
172 void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major,
173 unsigned Minor, unsigned Update,
174 VersionTuple SDKVersion) override;
175 void emitThumbFunc(MCSymbol *Func) override;
176
177 void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
179 const MCExpr *Value) override;
180 void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
181 bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
182
183 void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
184 void beginCOFFSymbolDef(const MCSymbol *Symbol) override;
185 void emitCOFFSymbolStorageClass(int StorageClass) override;
186 void emitCOFFSymbolType(int Type) override;
187 void endCOFFSymbolDef() override;
188 void emitCOFFSafeSEH(MCSymbol const *Symbol) override;
189 void emitCOFFSymbolIndex(MCSymbol const *Symbol) override;
190 void emitCOFFSectionIndex(MCSymbol const *Symbol) override;
191 void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
192 void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override;
194 MCSymbol *CsectSym, Align Alignment) override;
196 MCSymbolAttr Linkage,
197 MCSymbolAttr Visibility) override;
199 StringRef Rename) override;
200
201 void emitXCOFFRefDirective(const MCSymbol *Symbol) override;
202
203 void emitXCOFFExceptDirective(const MCSymbol *Symbol,
204 const MCSymbol *Trap,
205 unsigned Lang, unsigned Reason,
206 unsigned FunctionSize, bool hasDebug) override;
208
209 void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
211 Align ByteAlignment) override;
212
213 /// Emit a local common (.lcomm) symbol.
214 ///
215 /// @param Symbol - The common symbol to emit.
216 /// @param Size - The size of the common symbol.
217 /// @param ByteAlignment - The alignment of the common symbol in bytes.
219 Align ByteAlignment) override;
220
221 void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
222 uint64_t Size = 0, Align ByteAlignment = Align(1),
223 SMLoc Loc = SMLoc()) override;
224
225 void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
226 Align ByteAlignment = Align(1)) override;
227
228 void emitBinaryData(StringRef Data) override;
229
230 void emitBytes(StringRef Data) override;
231
232 void emitValueImpl(const MCExpr *Value, unsigned Size,
233 SMLoc Loc = SMLoc()) override;
234 void emitIntValue(uint64_t Value, unsigned Size) override;
235 void emitIntValueInHex(uint64_t Value, unsigned Size) override;
236 void emitIntValueInHexWithPadding(uint64_t Value, unsigned Size) override;
237
238 void emitULEB128Value(const MCExpr *Value) override;
239
240 void emitSLEB128Value(const MCExpr *Value) override;
241
242 void emitDTPRel32Value(const MCExpr *Value) override;
243 void emitDTPRel64Value(const MCExpr *Value) override;
244 void emitTPRel32Value(const MCExpr *Value) override;
245 void emitTPRel64Value(const MCExpr *Value) override;
246
247 void emitGPRel64Value(const MCExpr *Value) override;
248
249 void emitGPRel32Value(const MCExpr *Value) override;
250
251 void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
252 SMLoc Loc = SMLoc()) override;
253
254 void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
255 SMLoc Loc = SMLoc()) override;
256
257 void emitAlignmentDirective(unsigned ByteAlignment,
258 std::optional<int64_t> Value, unsigned ValueSize,
259 unsigned MaxBytesToEmit);
260
261 void emitValueToAlignment(Align Alignment, int64_t Value = 0,
262 unsigned ValueSize = 1,
263 unsigned MaxBytesToEmit = 0) override;
264
265 void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
266 unsigned MaxBytesToEmit = 0) override;
267
268 void emitValueToOffset(const MCExpr *Offset,
269 unsigned char Value,
270 SMLoc Loc) override;
271
272 void emitFileDirective(StringRef Filename) override;
273 void emitFileDirective(StringRef Filename, StringRef CompilerVersion,
274 StringRef TimeStamp, StringRef Description) override;
276 unsigned FileNo, StringRef Directory, StringRef Filename,
277 std::optional<MD5::MD5Result> Checksum = std::nullopt,
278 std::optional<StringRef> Source = std::nullopt,
279 unsigned CUID = 0) override;
280 void emitDwarfFile0Directive(StringRef Directory, StringRef Filename,
281 std::optional<MD5::MD5Result> Checksum,
282 std::optional<StringRef> Source,
283 unsigned CUID = 0) override;
284 void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
285 unsigned Flags, unsigned Isa,
286 unsigned Discriminator,
287 StringRef FileName) override;
288 MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
289
290 bool emitCVFileDirective(unsigned FileNo, StringRef Filename,
291 ArrayRef<uint8_t> Checksum,
292 unsigned ChecksumKind) override;
293 bool emitCVFuncIdDirective(unsigned FuncId) override;
294 bool emitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc,
295 unsigned IAFile, unsigned IALine,
296 unsigned IACol, SMLoc Loc) override;
297 void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
298 unsigned Column, bool PrologueEnd, bool IsStmt,
299 StringRef FileName, SMLoc Loc) override;
300 void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart,
301 const MCSymbol *FnEnd) override;
302 void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
303 unsigned SourceFileId,
304 unsigned SourceLineNum,
305 const MCSymbol *FnStartSym,
306 const MCSymbol *FnEndSym) override;
307
308 void PrintCVDefRangePrefix(
309 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges);
310
312 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
314
316 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
318
320 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
321 codeview::DefRangeRegisterHeader DRHdr) override;
322
324 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
326
327 void emitCVStringTableDirective() override;
328 void emitCVFileChecksumsDirective() override;
329 void emitCVFileChecksumOffsetDirective(unsigned FileNo) override;
330 void emitCVFPOData(const MCSymbol *ProcSym, SMLoc L) override;
331
332 void emitIdent(StringRef IdentString) override;
333 void emitCFIBKeyFrame() override;
334 void emitCFIMTETaggedFrame() override;
335 void emitCFISections(bool EH, bool Debug) override;
336 void emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) override;
337 void emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) override;
338 void emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) override;
339 void emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
340 int64_t AddressSpace, SMLoc Loc) override;
341 void emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;
342 void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) override;
343 void emitCFILsda(const MCSymbol *Sym, unsigned Encoding) override;
344 void emitCFIRememberState(SMLoc Loc) override;
345 void emitCFIRestoreState(SMLoc Loc) override;
346 void emitCFIRestore(int64_t Register, SMLoc Loc) override;
347 void emitCFISameValue(int64_t Register, SMLoc Loc) override;
348 void emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;
349 void emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) override;
350 void emitCFIEscape(StringRef Values, SMLoc Loc) override;
351 void emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) override;
352 void emitCFISignalFrame() override;
353 void emitCFIUndefined(int64_t Register, SMLoc Loc) override;
354 void emitCFIRegister(int64_t Register1, int64_t Register2,
355 SMLoc Loc) override;
356 void emitCFIWindowSave(SMLoc Loc) override;
357 void emitCFINegateRAState(SMLoc Loc) override;
358 void emitCFIReturnColumn(int64_t Register) override;
359
360 void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
361 void emitWinCFIEndProc(SMLoc Loc) override;
362 void emitWinCFIFuncletOrFuncEnd(SMLoc Loc) override;
363 void emitWinCFIStartChained(SMLoc Loc) override;
364 void emitWinCFIEndChained(SMLoc Loc) override;
365 void emitWinCFIPushReg(MCRegister Register, SMLoc Loc) override;
367 SMLoc Loc) override;
368 void emitWinCFIAllocStack(unsigned Size, SMLoc Loc) override;
370 SMLoc Loc) override;
372 SMLoc Loc) override;
373 void emitWinCFIPushFrame(bool Code, SMLoc Loc) override;
374 void emitWinCFIEndProlog(SMLoc Loc) override;
375
376 void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
377 SMLoc Loc) override;
378 void emitWinEHHandlerData(SMLoc Loc) override;
379
381 const MCSymbolRefExpr *To, uint64_t Count) override;
382
383 void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
384
386 uint64_t Attr, uint64_t Discriminator,
387 const MCPseudoProbeInlineStack &InlineStack,
388 MCSymbol *FnSym) override;
389
390 void emitBundleAlignMode(Align Alignment) override;
391 void emitBundleLock(bool AlignToEnd) override;
392 void emitBundleUnlock() override;
393
394 std::optional<std::pair<bool, std::string>>
396 SMLoc Loc, const MCSubtargetInfo &STI) override;
397
398 void emitAddrsig() override;
399 void emitAddrsigSym(const MCSymbol *Sym) override;
400
401 /// If this file is backed by an assembly streamer, this dumps the specified
402 /// string in the output .s file. This capability is indicated by the
403 /// hasRawTextSupport() predicate.
404 void emitRawTextImpl(StringRef String) override;
405
406 void finishImpl() override;
407
408 void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) override;
409
410 MCSymbol *emitDwarfUnitLength(const Twine &Prefix,
411 const Twine &Comment) override;
412
413 void emitDwarfLineStartLabel(MCSymbol *StartSym) override;
414
415 void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override;
416
417 void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
418 const MCSymbol *Label,
419 unsigned PointerSize) override;
420
421 void doFinalizationAtSectionEnd(MCSection *Section) override;
422};
423
424} // end anonymous namespace.
425
426void MCAsmStreamer::AddComment(const Twine &T, bool EOL) {
427 if (!IsVerboseAsm) return;
428
429 T.toVector(CommentToEmit);
430
431 if (EOL)
432 CommentToEmit.push_back('\n'); // Place comment in a new line.
433}
434
435void MCAsmStreamer::EmitCommentsAndEOL() {
436 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
437 OS << '\n';
438 return;
439 }
440
441 StringRef Comments = CommentToEmit;
442
443 assert(Comments.back() == '\n' &&
444 "Comment array not newline terminated");
445 do {
446 // Emit a line of comments.
447 OS.PadToColumn(MAI->getCommentColumn());
448 size_t Position = Comments.find('\n');
449 OS << MAI->getCommentString() << ' ' << Comments.substr(0, Position) <<'\n';
450
451 Comments = Comments.substr(Position+1);
452 } while (!Comments.empty());
453
454 CommentToEmit.clear();
455}
456
457static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
458 assert(Bytes > 0 && Bytes <= 8 && "Invalid size!");
459 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
460}
461
462void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) {
463 if (TabPrefix)
464 OS << '\t';
465 OS << MAI->getCommentString() << T;
466 EmitEOL();
467}
468
469void MCAsmStreamer::addExplicitComment(const Twine &T) {
470 StringRef c = T.getSingleStringRef();
471 if (c == MAI->getSeparatorString())
472 return;
473 if (c.starts_with(StringRef("//"))) {
474 ExplicitCommentToEmit.append("\t");
475 ExplicitCommentToEmit.append(MAI->getCommentString());
476 // drop //
477 ExplicitCommentToEmit.append(c.slice(2, c.size()).str());
478 } else if (c.starts_with(StringRef("/*"))) {
479 size_t p = 2, len = c.size() - 2;
480 // emit each line in comment as separate newline.
481 do {
482 size_t newp = std::min(len, c.find_first_of("\r\n", p));
483 ExplicitCommentToEmit.append("\t");
484 ExplicitCommentToEmit.append(MAI->getCommentString());
485 ExplicitCommentToEmit.append(c.slice(p, newp).str());
486 // If we have another line in this comment add line
487 if (newp < len)
488 ExplicitCommentToEmit.append("\n");
489 p = newp + 1;
490 } while (p < len);
491 } else if (c.starts_with(StringRef(MAI->getCommentString()))) {
492 ExplicitCommentToEmit.append("\t");
493 ExplicitCommentToEmit.append(c.str());
494 } else if (c.front() == '#') {
495
496 ExplicitCommentToEmit.append("\t");
497 ExplicitCommentToEmit.append(MAI->getCommentString());
498 ExplicitCommentToEmit.append(c.slice(1, c.size()).str());
499 } else
500 assert(false && "Unexpected Assembly Comment");
501 // full line comments immediately output
502 if (c.back() == '\n')
503 emitExplicitComments();
504}
505
506void MCAsmStreamer::emitExplicitComments() {
507 StringRef Comments = ExplicitCommentToEmit;
508 if (!Comments.empty())
509 OS << Comments;
510 ExplicitCommentToEmit.clear();
511}
512
513void MCAsmStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
514 if (MCTargetStreamer *TS = getTargetStreamer()) {
515 TS->changeSection(getCurrentSection().first, Section, Subsection, OS);
516 } else {
517 Section->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS,
518 Subsection);
519 }
520 MCStreamer::changeSection(Section, Subsection);
521}
522
523void MCAsmStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
525 bool KeepOriginalSym) {
526 OS << ".symver ";
527 OriginalSym->print(OS, MAI);
528 OS << ", " << Name;
529 if (!KeepOriginalSym && !Name.contains("@@@"))
530 OS << ", remove";
531 EmitEOL();
532}
533
534void MCAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
535 MCStreamer::emitLabel(Symbol, Loc);
536
537 Symbol->print(OS, MAI);
538 OS << MAI->getLabelSuffix();
539
540 EmitEOL();
541}
542
543void MCAsmStreamer::emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {
544 StringRef str = MCLOHIdToName(Kind);
545
546#ifndef NDEBUG
547 int NbArgs = MCLOHIdToNbArgs(Kind);
548 assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");
549 assert(str != "" && "Invalid LOH name");
550#endif
551
552 OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";
553 bool IsFirst = true;
554 for (const MCSymbol *Arg : Args) {
555 if (!IsFirst)
556 OS << ", ";
557 IsFirst = false;
558 Arg->print(OS, MAI);
559 }
560 EmitEOL();
561}
562
563void MCAsmStreamer::emitGNUAttribute(unsigned Tag, unsigned Value) {
564 OS << "\t.gnu_attribute " << Tag << ", " << Value << "\n";
565}
566
567void MCAsmStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {
568 switch (Flag) {
569 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
570 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
571 case MCAF_Code16: OS << '\t'<< MAI->getCode16Directive();break;
572 case MCAF_Code32: OS << '\t'<< MAI->getCode32Directive();break;
573 case MCAF_Code64: OS << '\t'<< MAI->getCode64Directive();break;
574 }
575 EmitEOL();
576}
577
578void MCAsmStreamer::emitLinkerOptions(ArrayRef<std::string> Options) {
579 assert(!Options.empty() && "At least one option is required!");
580 OS << "\t.linker_option \"" << Options[0] << '"';
581 for (const std::string &Opt : llvm::drop_begin(Options))
582 OS << ", " << '"' << Opt << '"';
583 EmitEOL();
584}
585
586void MCAsmStreamer::emitDataRegion(MCDataRegionType Kind) {
588 return;
589 switch (Kind) {
590 case MCDR_DataRegion: OS << "\t.data_region"; break;
591 case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
592 case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
593 case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
594 case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
595 }
596 EmitEOL();
597}
598
600 switch (Type) {
601 case MCVM_WatchOSVersionMin: return ".watchos_version_min";
602 case MCVM_TvOSVersionMin: return ".tvos_version_min";
603 case MCVM_IOSVersionMin: return ".ios_version_min";
604 case MCVM_OSXVersionMin: return ".macosx_version_min";
605 }
606 llvm_unreachable("Invalid MC version min type");
607}
608
610 const VersionTuple &SDKVersion) {
611 if (SDKVersion.empty())
612 return;
613 OS << '\t' << "sdk_version " << SDKVersion.getMajor();
614 if (auto Minor = SDKVersion.getMinor()) {
615 OS << ", " << *Minor;
616 if (auto Subminor = SDKVersion.getSubminor()) {
617 OS << ", " << *Subminor;
618 }
619 }
620}
621
622void MCAsmStreamer::emitVersionMin(MCVersionMinType Type, unsigned Major,
623 unsigned Minor, unsigned Update,
624 VersionTuple SDKVersion) {
625 OS << '\t' << getVersionMinDirective(Type) << ' ' << Major << ", " << Minor;
626 if (Update)
627 OS << ", " << Update;
628 EmitSDKVersionSuffix(OS, SDKVersion);
629 EmitEOL();
630}
631
633 switch (Type) {
634#define PLATFORM(platform, id, name, build_name, target, tapi_target, \
635 marketing) \
636 case MachO::PLATFORM_##platform: \
637 return #build_name;
638#include "llvm/BinaryFormat/MachO.def"
639 }
640 llvm_unreachable("Invalid Mach-O platform type");
641}
642
643void MCAsmStreamer::emitBuildVersion(unsigned Platform, unsigned Major,
644 unsigned Minor, unsigned Update,
645 VersionTuple SDKVersion) {
646 const char *PlatformName = getPlatformName((MachO::PlatformType)Platform);
647 OS << "\t.build_version " << PlatformName << ", " << Major << ", " << Minor;
648 if (Update)
649 OS << ", " << Update;
650 EmitSDKVersionSuffix(OS, SDKVersion);
651 EmitEOL();
652}
653
654void MCAsmStreamer::emitDarwinTargetVariantBuildVersion(
655 unsigned Platform, unsigned Major, unsigned Minor, unsigned Update,
656 VersionTuple SDKVersion) {
657 emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
658}
659
660void MCAsmStreamer::emitThumbFunc(MCSymbol *Func) {
661 // This needs to emit to a temporary string to get properly quoted
662 // MCSymbols when they have spaces in them.
663 OS << "\t.thumb_func";
664 // Only Mach-O hasSubsectionsViaSymbols()
665 if (MAI->hasSubsectionsViaSymbols()) {
666 OS << '\t';
667 Func->print(OS, MAI);
668 }
669 EmitEOL();
670}
671
672void MCAsmStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
673 // Do not emit a .set on inlined target assignments.
674 bool EmitSet = true;
675 if (auto *E = dyn_cast<MCTargetExpr>(Value))
676 if (E->inlineAssignedExpr())
677 EmitSet = false;
678 if (EmitSet) {
679 OS << ".set ";
680 Symbol->print(OS, MAI);
681 OS << ", ";
682 Value->print(OS, MAI);
683
684 EmitEOL();
685 }
686
688}
689
690void MCAsmStreamer::emitConditionalAssignment(MCSymbol *Symbol,
691 const MCExpr *Value) {
692 OS << ".lto_set_conditional ";
693 Symbol->print(OS, MAI);
694 OS << ", ";
695 Value->print(OS, MAI);
696 EmitEOL();
697}
698
699void MCAsmStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
700 OS << ".weakref ";
701 Alias->print(OS, MAI);
702 OS << ", ";
703 Symbol->print(OS, MAI);
704 EmitEOL();
705}
706
707bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
709 switch (Attribute) {
710 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
711 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
712 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
713 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
714 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
715 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
716 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
717 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
718 if (!MAI->hasDotTypeDotSizeDirective())
719 return false; // Symbol attribute not supported
720 OS << "\t.type\t";
721 Symbol->print(OS, MAI);
722 OS << ',' << ((MAI->getCommentString()[0] != '@') ? '@' : '%');
723 switch (Attribute) {
724 default: return false;
725 case MCSA_ELF_TypeFunction: OS << "function"; break;
726 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
727 case MCSA_ELF_TypeObject: OS << "object"; break;
728 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
729 case MCSA_ELF_TypeCommon: OS << "common"; break;
730 case MCSA_ELF_TypeNoType: OS << "notype"; break;
731 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
732 }
733 EmitEOL();
734 return true;
735 case MCSA_Global: // .globl/.global
736 OS << MAI->getGlobalDirective();
737 break;
738 case MCSA_LGlobal: OS << "\t.lglobl\t"; break;
739 case MCSA_Hidden: OS << "\t.hidden\t"; break;
740 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
741 case MCSA_Internal: OS << "\t.internal\t"; break;
742 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
743 case MCSA_Local: OS << "\t.local\t"; break;
744 case MCSA_NoDeadStrip:
745 if (!MAI->hasNoDeadStrip())
746 return false;
747 OS << "\t.no_dead_strip\t";
748 break;
749 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
750 case MCSA_AltEntry: OS << "\t.alt_entry\t"; break;
752 OS << "\t.private_extern\t";
753 break;
754 case MCSA_Protected: OS << "\t.protected\t"; break;
755 case MCSA_Reference: OS << "\t.reference\t"; break;
756 case MCSA_Extern:
757 OS << "\t.extern\t";
758 break;
759 case MCSA_Weak: OS << MAI->getWeakDirective(); break;
761 OS << "\t.weak_definition\t";
762 break;
763 // .weak_reference
764 case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break;
765 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
766 case MCSA_Cold:
767 // Assemblers currently do not support a .cold directive.
768 case MCSA_Exported:
769 // Non-AIX assemblers currently do not support exported visibility.
770 return false;
771 case MCSA_Memtag:
772 OS << "\t.memtag\t";
773 break;
774 case MCSA_WeakAntiDep:
775 OS << "\t.weak_anti_dep\t";
776 break;
777 }
778
779 Symbol->print(OS, MAI);
780 EmitEOL();
781
782 return true;
783}
784
785void MCAsmStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
786 OS << ".desc" << ' ';
787 Symbol->print(OS, MAI);
788 OS << ',' << DescValue;
789 EmitEOL();
790}
791
792void MCAsmStreamer::emitSyntaxDirective() {
793 if (MAI->getAssemblerDialect() == 1) {
794 OS << "\t.intel_syntax noprefix";
795 EmitEOL();
796 }
797 // FIXME: Currently emit unprefix'ed registers.
798 // The intel_syntax directive has one optional argument
799 // with may have a value of prefix or noprefix.
800}
801
802void MCAsmStreamer::beginCOFFSymbolDef(const MCSymbol *Symbol) {
803 OS << "\t.def\t";
804 Symbol->print(OS, MAI);
805 OS << ';';
806 EmitEOL();
807}
808
809void MCAsmStreamer::emitCOFFSymbolStorageClass(int StorageClass) {
810 OS << "\t.scl\t" << StorageClass << ';';
811 EmitEOL();
812}
813
814void MCAsmStreamer::emitCOFFSymbolType(int Type) {
815 OS << "\t.type\t" << Type << ';';
816 EmitEOL();
817}
818
819void MCAsmStreamer::endCOFFSymbolDef() {
820 OS << "\t.endef";
821 EmitEOL();
822}
823
824void MCAsmStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {
825 OS << "\t.safeseh\t";
826 Symbol->print(OS, MAI);
827 EmitEOL();
828}
829
830void MCAsmStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {
831 OS << "\t.symidx\t";
832 Symbol->print(OS, MAI);
833 EmitEOL();
834}
835
836void MCAsmStreamer::emitCOFFSectionIndex(MCSymbol const *Symbol) {
837 OS << "\t.secidx\t";
838 Symbol->print(OS, MAI);
839 EmitEOL();
840}
841
842void MCAsmStreamer::emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {
843 OS << "\t.secrel32\t";
844 Symbol->print(OS, MAI);
845 if (Offset != 0)
846 OS << '+' << Offset;
847 EmitEOL();
848}
849
850void MCAsmStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {
851 OS << "\t.rva\t";
852 Symbol->print(OS, MAI);
853 if (Offset > 0)
854 OS << '+' << Offset;
855 else if (Offset < 0)
856 OS << '-' << -Offset;
857 EmitEOL();
858}
859
860// We need an XCOFF-specific version of this directive as the AIX syntax
861// requires a QualName argument identifying the csect name and storage mapping
862// class to appear before the alignment if we are specifying it.
863void MCAsmStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym,
865 MCSymbol *CsectSym,
866 Align Alignment) {
868 "We only support writing log base-2 alignment format with XCOFF.");
869
870 OS << "\t.lcomm\t";
871 LabelSym->print(OS, MAI);
872 OS << ',' << Size << ',';
873 CsectSym->print(OS, MAI);
874 OS << ',' << Log2(Alignment);
875
876 EmitEOL();
877
878 // Print symbol's rename (original name contains invalid character(s)) if
879 // there is one.
880 MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(CsectSym);
881 if (XSym->hasRename())
882 emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
883}
884
885void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility(
886 MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility) {
887
888 switch (Linkage) {
889 case MCSA_Global:
890 OS << MAI->getGlobalDirective();
891 break;
892 case MCSA_Weak:
893 OS << MAI->getWeakDirective();
894 break;
895 case MCSA_Extern:
896 OS << "\t.extern\t";
897 break;
898 case MCSA_LGlobal:
899 OS << "\t.lglobl\t";
900 break;
901 default:
902 report_fatal_error("unhandled linkage type");
903 }
904
905 Symbol->print(OS, MAI);
906
907 switch (Visibility) {
908 case MCSA_Invalid:
909 // Nothing to do.
910 break;
911 case MCSA_Hidden:
912 OS << ",hidden";
913 break;
914 case MCSA_Protected:
915 OS << ",protected";
916 break;
917 case MCSA_Exported:
918 OS << ",exported";
919 break;
920 default:
921 report_fatal_error("unexpected value for Visibility type");
922 }
923 EmitEOL();
924
925 // Print symbol's rename (original name contains invalid character(s)) if
926 // there is one.
927 if (cast<MCSymbolXCOFF>(Symbol)->hasRename())
928 emitXCOFFRenameDirective(Symbol,
929 cast<MCSymbolXCOFF>(Symbol)->getSymbolTableName());
930}
931
932void MCAsmStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
933 StringRef Rename) {
934 OS << "\t.rename\t";
935 Name->print(OS, MAI);
936 const char DQ = '"';
937 OS << ',' << DQ;
938 for (char C : Rename) {
939 // To escape a double quote character, the character should be doubled.
940 if (C == DQ)
941 OS << DQ;
942 OS << C;
943 }
944 OS << DQ;
945 EmitEOL();
946}
947
948void MCAsmStreamer::emitXCOFFRefDirective(const MCSymbol *Symbol) {
949 OS << "\t.ref ";
950 Symbol->print(OS, MAI);
951 EmitEOL();
952}
953
954void MCAsmStreamer::emitXCOFFExceptDirective(const MCSymbol *Symbol,
955 const MCSymbol *Trap,
956 unsigned Lang,
957 unsigned Reason,
958 unsigned FunctionSize,
959 bool hasDebug) {
960 OS << "\t.except\t";
961 Symbol->print(OS, MAI);
962 OS << ", " << Lang << ", " << Reason;
963 EmitEOL();
964}
965
966void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
967 const char InfoDirective[] = "\t.info ";
968 const char *Separator = ", ";
969 constexpr int WordSize = sizeof(uint32_t);
970
971 // Start by emitting the .info pseudo-op and C_INFO symbol name.
972 OS << InfoDirective;
973 PrintQuotedString(Name, OS);
974 OS << Separator;
975
976 size_t MetadataSize = Metadata.size();
977
978 // Emit the 4-byte length of the metadata.
979 OS << format_hex(MetadataSize, 10) << Separator;
980
981 // Nothing left to do if there's no metadata.
982 if (MetadataSize == 0) {
983 EmitEOL();
984 return;
985 }
986
987 // Metadata needs to be padded out to an even word size when generating
988 // assembly because the .info pseudo-op can only generate words of data. We
989 // apply the same restriction to the object case for consistency, however the
990 // linker doesn't require padding, so it will only save bytes specified by the
991 // length and discard any padding.
992 uint32_t PaddedSize = alignTo(MetadataSize, WordSize);
993 uint32_t PaddingSize = PaddedSize - MetadataSize;
994
995 // Write out the payload a word at a time.
996 //
997 // The assembler has a limit on the number of operands in an expression,
998 // so we need multiple .info pseudo-ops. We choose a small number of words
999 // per pseudo-op to keep the assembly readable.
1000 constexpr int WordsPerDirective = 5;
1001 // Force emitting a new directive to keep the first directive purely about the
1002 // name and size of the note.
1003 int WordsBeforeNextDirective = 0;
1004 auto PrintWord = [&](const uint8_t *WordPtr) {
1005 if (WordsBeforeNextDirective-- == 0) {
1006 EmitEOL();
1007 OS << InfoDirective;
1008 WordsBeforeNextDirective = WordsPerDirective;
1009 }
1010 OS << Separator;
1012 OS << format_hex(Word, 10);
1013 };
1014
1015 size_t Index = 0;
1016 for (; Index + WordSize <= MetadataSize; Index += WordSize)
1017 PrintWord(reinterpret_cast<const uint8_t *>(Metadata.data()) + Index);
1018
1019 // If there is padding, then we have at least one byte of payload left
1020 // to emit.
1021 if (PaddingSize) {
1022 assert(PaddedSize - Index == WordSize);
1023 std::array<uint8_t, WordSize> LastWord = {0};
1024 ::memcpy(LastWord.data(), Metadata.data() + Index, MetadataSize - Index);
1025 PrintWord(LastWord.data());
1026 }
1027 EmitEOL();
1028}
1029
1030void MCAsmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
1032 OS << "\t.size\t";
1033 Symbol->print(OS, MAI);
1034 OS << ", ";
1035 Value->print(OS, MAI);
1036 EmitEOL();
1037}
1038
1039void MCAsmStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1040 Align ByteAlignment) {
1041 OS << "\t.comm\t";
1042 Symbol->print(OS, MAI);
1043 OS << ',' << Size;
1044
1046 OS << ',' << ByteAlignment.value();
1047 else
1048 OS << ',' << Log2(ByteAlignment);
1049 EmitEOL();
1050
1051 // Print symbol's rename (original name contains invalid character(s)) if
1052 // there is one.
1053 MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(Symbol);
1054 if (XSym && XSym->hasRename())
1055 emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
1056}
1057
1058void MCAsmStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1059 Align ByteAlign) {
1060 OS << "\t.lcomm\t";
1061 Symbol->print(OS, MAI);
1062 OS << ',' << Size;
1063
1064 if (ByteAlign > 1) {
1065 switch (MAI->getLCOMMDirectiveAlignmentType()) {
1066 case LCOMM::NoAlignment:
1067 llvm_unreachable("alignment not supported on .lcomm!");
1069 OS << ',' << ByteAlign.value();
1070 break;
1072 OS << ',' << Log2(ByteAlign);
1073 break;
1074 }
1075 }
1076 EmitEOL();
1077}
1078
1079void MCAsmStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
1080 uint64_t Size, Align ByteAlignment,
1081 SMLoc Loc) {
1082 if (Symbol)
1083 assignFragment(Symbol, &Section->getDummyFragment());
1084
1085 // Note: a .zerofill directive does not switch sections.
1086 OS << ".zerofill ";
1087
1088 assert(Section->getVariant() == MCSection::SV_MachO &&
1089 ".zerofill is a Mach-O specific directive");
1090 // This is a mach-o specific directive.
1091
1092 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
1093 OS << MOSection->getSegmentName() << "," << MOSection->getName();
1094
1095 if (Symbol) {
1096 OS << ',';
1097 Symbol->print(OS, MAI);
1098 OS << ',' << Size;
1099 OS << ',' << Log2(ByteAlignment);
1100 }
1101 EmitEOL();
1102}
1103
1104// .tbss sym, size, align
1105// This depends that the symbol has already been mangled from the original,
1106// e.g. _a.
1107void MCAsmStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1108 uint64_t Size, Align ByteAlignment) {
1109 assignFragment(Symbol, &Section->getDummyFragment());
1110
1111 assert(Symbol && "Symbol shouldn't be NULL!");
1112 // Instead of using the Section we'll just use the shortcut.
1113
1114 assert(Section->getVariant() == MCSection::SV_MachO &&
1115 ".zerofill is a Mach-O specific directive");
1116 // This is a mach-o specific directive and section.
1117
1118 OS << ".tbss ";
1119 Symbol->print(OS, MAI);
1120 OS << ", " << Size;
1121
1122 // Output align if we have it. We default to 1 so don't bother printing
1123 // that.
1124 if (ByteAlignment > 1)
1125 OS << ", " << Log2(ByteAlignment);
1126
1127 EmitEOL();
1128}
1129
1130static inline bool isPrintableString(StringRef Data) {
1131 const auto BeginPtr = Data.begin(), EndPtr = Data.end();
1132 for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {
1133 if (!isPrint(C))
1134 return false;
1135 }
1136 return isPrint(Data.back()) || Data.back() == 0;
1137}
1138
1139static inline char toOctal(int X) { return (X&7)+'0'; }
1140
1143 assert(!Data.empty() && "Cannot generate an empty list.");
1144 const auto printCharacterInOctal = [&OS](unsigned char C) {
1145 OS << '0';
1146 OS << toOctal(C >> 6);
1147 OS << toOctal(C >> 3);
1148 OS << toOctal(C >> 0);
1149 };
1150 const auto printOneCharacterFor = [printCharacterInOctal](
1151 auto printOnePrintingCharacter) {
1152 return [printCharacterInOctal, printOnePrintingCharacter](unsigned char C) {
1153 if (isPrint(C)) {
1154 printOnePrintingCharacter(static_cast<char>(C));
1155 return;
1156 }
1157 printCharacterInOctal(C);
1158 };
1159 };
1160 const auto printCharacterList = [Data, &OS](const auto &printOneCharacter) {
1161 const auto BeginPtr = Data.begin(), EndPtr = Data.end();
1162 for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {
1163 printOneCharacter(C);
1164 OS << ',';
1165 }
1166 printOneCharacter(*(EndPtr - 1));
1167 };
1168 switch (ACLS) {
1170 printCharacterList(printCharacterInOctal);
1171 return;
1173 printCharacterList(printOneCharacterFor([&OS](char C) {
1174 const char AsmCharLitBuf[2] = {'\'', C};
1175 OS << StringRef(AsmCharLitBuf, sizeof(AsmCharLitBuf));
1176 }));
1177 return;
1178 }
1179 llvm_unreachable("Invalid AsmCharLiteralSyntax value!");
1180}
1181
1182void MCAsmStreamer::PrintQuotedString(StringRef Data, raw_ostream &OS) const {
1183 OS << '"';
1184
1186 for (unsigned char C : Data) {
1187 if (C == '"')
1188 OS << "\"\"";
1189 else
1190 OS << (char)C;
1191 }
1192 } else {
1193 for (unsigned char C : Data) {
1194 if (C == '"' || C == '\\') {
1195 OS << '\\' << (char)C;
1196 continue;
1197 }
1198
1199 if (isPrint((unsigned char)C)) {
1200 OS << (char)C;
1201 continue;
1202 }
1203
1204 switch (C) {
1205 case '\b':
1206 OS << "\\b";
1207 break;
1208 case '\f':
1209 OS << "\\f";
1210 break;
1211 case '\n':
1212 OS << "\\n";
1213 break;
1214 case '\r':
1215 OS << "\\r";
1216 break;
1217 case '\t':
1218 OS << "\\t";
1219 break;
1220 default:
1221 OS << '\\';
1222 OS << toOctal(C >> 6);
1223 OS << toOctal(C >> 3);
1224 OS << toOctal(C >> 0);
1225 break;
1226 }
1227 }
1228 }
1229
1230 OS << '"';
1231}
1232
1233void MCAsmStreamer::emitBytes(StringRef Data) {
1234 assert(getCurrentSectionOnly() &&
1235 "Cannot emit contents before setting section!");
1236 if (Data.empty()) return;
1237
1238 const auto emitAsString = [this](StringRef Data) {
1239 // If the data ends with 0 and the target supports .asciz, use it, otherwise
1240 // use .ascii or a byte-list directive
1241 if (MAI->getAscizDirective() && Data.back() == 0) {
1242 OS << MAI->getAscizDirective();
1243 Data = Data.substr(0, Data.size() - 1);
1244 } else if (LLVM_LIKELY(MAI->getAsciiDirective())) {
1245 OS << MAI->getAsciiDirective();
1246 } else if (MAI->hasPairedDoubleQuoteStringConstants() &&
1247 isPrintableString(Data)) {
1248 // For target with DoubleQuoteString constants, .string and .byte are used
1249 // as replacement of .asciz and .ascii.
1251 "hasPairedDoubleQuoteStringConstants target must support "
1252 "PlainString Directive");
1254 "hasPairedDoubleQuoteStringConstants target must support ByteList "
1255 "Directive");
1256 if (Data.back() == 0) {
1257 OS << MAI->getPlainStringDirective();
1258 Data = Data.substr(0, Data.size() - 1);
1259 } else {
1260 OS << MAI->getByteListDirective();
1261 }
1262 } else if (MAI->getByteListDirective()) {
1263 OS << MAI->getByteListDirective();
1265 EmitEOL();
1266 return true;
1267 } else {
1268 return false;
1269 }
1270
1271 PrintQuotedString(Data, OS);
1272 EmitEOL();
1273 return true;
1274 };
1275
1276 if (Data.size() != 1 && emitAsString(Data))
1277 return;
1278
1279 // Only single byte is provided or no ascii, asciz, or byte-list directives
1280 // are applicable. Emit as vector of individual 8bits data elements.
1281 if (MCTargetStreamer *TS = getTargetStreamer()) {
1282 TS->emitRawBytes(Data);
1283 return;
1284 }
1285 const char *Directive = MAI->getData8bitsDirective();
1286 for (const unsigned char C : Data.bytes()) {
1287 OS << Directive << (unsigned)C;
1288 EmitEOL();
1289 }
1290}
1291
1292void MCAsmStreamer::emitBinaryData(StringRef Data) {
1293 // This is binary data. Print it in a grid of hex bytes for readability.
1294 const size_t Cols = 4;
1295 for (size_t I = 0, EI = alignTo(Data.size(), Cols); I < EI; I += Cols) {
1296 size_t J = I, EJ = std::min(I + Cols, Data.size());
1297 assert(EJ > 0);
1298 OS << MAI->getData8bitsDirective();
1299 for (; J < EJ - 1; ++J)
1300 OS << format("0x%02x", uint8_t(Data[J])) << ", ";
1301 OS << format("0x%02x", uint8_t(Data[J]));
1302 EmitEOL();
1303 }
1304}
1305
1306void MCAsmStreamer::emitIntValue(uint64_t Value, unsigned Size) {
1307 emitValue(MCConstantExpr::create(Value, getContext()), Size);
1308}
1309
1310void MCAsmStreamer::emitIntValueInHex(uint64_t Value, unsigned Size) {
1311 emitValue(MCConstantExpr::create(Value, getContext(), true), Size);
1312}
1313
1314void MCAsmStreamer::emitIntValueInHexWithPadding(uint64_t Value,
1315 unsigned Size) {
1316 emitValue(MCConstantExpr::create(Value, getContext(), true, Size), Size);
1317}
1318
1319void MCAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
1320 SMLoc Loc) {
1321 assert(Size <= 8 && "Invalid size");
1322 assert(getCurrentSectionOnly() &&
1323 "Cannot emit contents before setting section!");
1324 const char *Directive = nullptr;
1325 switch (Size) {
1326 default: break;
1327 case 1: Directive = MAI->getData8bitsDirective(); break;
1328 case 2: Directive = MAI->getData16bitsDirective(); break;
1329 case 4: Directive = MAI->getData32bitsDirective(); break;
1330 case 8: Directive = MAI->getData64bitsDirective(); break;
1331 }
1332
1333 if (!Directive) {
1334 int64_t IntValue;
1335 if (!Value->evaluateAsAbsolute(IntValue))
1336 report_fatal_error("Don't know how to emit this value.");
1337
1338 // We couldn't handle the requested integer size so we fallback by breaking
1339 // the request down into several, smaller, integers.
1340 // Since sizes greater or equal to "Size" are invalid, we use the greatest
1341 // power of 2 that is less than "Size" as our largest piece of granularity.
1342 bool IsLittleEndian = MAI->isLittleEndian();
1343 for (unsigned Emitted = 0; Emitted != Size;) {
1344 unsigned Remaining = Size - Emitted;
1345 // The size of our partial emission must be a power of two less than
1346 // Size.
1347 unsigned EmissionSize = llvm::bit_floor(std::min(Remaining, Size - 1));
1348 // Calculate the byte offset of our partial emission taking into account
1349 // the endianness of the target.
1350 unsigned ByteOffset =
1351 IsLittleEndian ? Emitted : (Remaining - EmissionSize);
1352 uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
1353 // We truncate our partial emission to fit within the bounds of the
1354 // emission domain. This produces nicer output and silences potential
1355 // truncation warnings when round tripping through another assembler.
1356 uint64_t Shift = 64 - EmissionSize * 8;
1357 assert(Shift < static_cast<uint64_t>(
1358 std::numeric_limits<unsigned long long>::digits) &&
1359 "undefined behavior");
1360 ValueToEmit &= ~0ULL >> Shift;
1361 emitIntValue(ValueToEmit, EmissionSize);
1362 Emitted += EmissionSize;
1363 }
1364 return;
1365 }
1366
1367 assert(Directive && "Invalid size for machine code value!");
1368 OS << Directive;
1369 if (MCTargetStreamer *TS = getTargetStreamer()) {
1370 TS->emitValue(Value);
1371 } else {
1372 Value->print(OS, MAI);
1373 EmitEOL();
1374 }
1375}
1376
1377void MCAsmStreamer::emitULEB128Value(const MCExpr *Value) {
1378 int64_t IntValue;
1379 if (Value->evaluateAsAbsolute(IntValue)) {
1380 emitULEB128IntValue(IntValue);
1381 return;
1382 }
1383 OS << "\t.uleb128 ";
1384 Value->print(OS, MAI);
1385 EmitEOL();
1386}
1387
1388void MCAsmStreamer::emitSLEB128Value(const MCExpr *Value) {
1389 int64_t IntValue;
1390 if (Value->evaluateAsAbsolute(IntValue)) {
1391 emitSLEB128IntValue(IntValue);
1392 return;
1393 }
1394 OS << "\t.sleb128 ";
1395 Value->print(OS, MAI);
1396 EmitEOL();
1397}
1398
1399void MCAsmStreamer::emitDTPRel64Value(const MCExpr *Value) {
1400 assert(MAI->getDTPRel64Directive() != nullptr);
1401 OS << MAI->getDTPRel64Directive();
1402 Value->print(OS, MAI);
1403 EmitEOL();
1404}
1405
1406void MCAsmStreamer::emitDTPRel32Value(const MCExpr *Value) {
1407 assert(MAI->getDTPRel32Directive() != nullptr);
1408 OS << MAI->getDTPRel32Directive();
1409 Value->print(OS, MAI);
1410 EmitEOL();
1411}
1412
1413void MCAsmStreamer::emitTPRel64Value(const MCExpr *Value) {
1414 assert(MAI->getTPRel64Directive() != nullptr);
1415 OS << MAI->getTPRel64Directive();
1416 Value->print(OS, MAI);
1417 EmitEOL();
1418}
1419
1420void MCAsmStreamer::emitTPRel32Value(const MCExpr *Value) {
1421 assert(MAI->getTPRel32Directive() != nullptr);
1422 OS << MAI->getTPRel32Directive();
1423 Value->print(OS, MAI);
1424 EmitEOL();
1425}
1426
1427void MCAsmStreamer::emitGPRel64Value(const MCExpr *Value) {
1428 assert(MAI->getGPRel64Directive() != nullptr);
1429 OS << MAI->getGPRel64Directive();
1430 Value->print(OS, MAI);
1431 EmitEOL();
1432}
1433
1434void MCAsmStreamer::emitGPRel32Value(const MCExpr *Value) {
1435 assert(MAI->getGPRel32Directive() != nullptr);
1436 OS << MAI->getGPRel32Directive();
1437 Value->print(OS, MAI);
1438 EmitEOL();
1439}
1440
1441void MCAsmStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
1442 SMLoc Loc) {
1443 int64_t IntNumBytes;
1444 const bool IsAbsolute = NumBytes.evaluateAsAbsolute(IntNumBytes);
1445 if (IsAbsolute && IntNumBytes == 0)
1446 return;
1447
1448 if (const char *ZeroDirective = MAI->getZeroDirective()) {
1449 if (MAI->doesZeroDirectiveSupportNonZeroValue() || FillValue == 0) {
1450 // FIXME: Emit location directives
1451 OS << ZeroDirective;
1452 NumBytes.print(OS, MAI);
1453 if (FillValue != 0)
1454 OS << ',' << (int)FillValue;
1455 EmitEOL();
1456 } else {
1457 if (!IsAbsolute)
1459 "Cannot emit non-absolute expression lengths of fill.");
1460 for (int i = 0; i < IntNumBytes; ++i) {
1461 OS << MAI->getData8bitsDirective() << (int)FillValue;
1462 EmitEOL();
1463 }
1464 }
1465 return;
1466 }
1467
1468 MCStreamer::emitFill(NumBytes, FillValue);
1469}
1470
1471void MCAsmStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
1472 int64_t Expr, SMLoc Loc) {
1473 // FIXME: Emit location directives
1474 OS << "\t.fill\t";
1475 NumValues.print(OS, MAI);
1476 OS << ", " << Size << ", 0x";
1477 OS.write_hex(truncateToSize(Expr, 4));
1478 EmitEOL();
1479}
1480
1481void MCAsmStreamer::emitAlignmentDirective(unsigned ByteAlignment,
1482 std::optional<int64_t> Value,
1483 unsigned ValueSize,
1484 unsigned MaxBytesToEmit) {
1485 if (MAI->useDotAlignForAlignment()) {
1486 if (!isPowerOf2_32(ByteAlignment))
1487 report_fatal_error("Only power-of-two alignments are supported "
1488 "with .align.");
1489 OS << "\t.align\t";
1490 OS << Log2_32(ByteAlignment);
1491 EmitEOL();
1492 return;
1493 }
1494
1495 // Some assemblers don't support non-power of two alignments, so we always
1496 // emit alignments as a power of two if possible.
1497 if (isPowerOf2_32(ByteAlignment)) {
1498 switch (ValueSize) {
1499 default:
1500 llvm_unreachable("Invalid size for machine code value!");
1501 case 1:
1502 OS << "\t.p2align\t";
1503 break;
1504 case 2:
1505 OS << ".p2alignw ";
1506 break;
1507 case 4:
1508 OS << ".p2alignl ";
1509 break;
1510 case 8:
1511 llvm_unreachable("Unsupported alignment size!");
1512 }
1513
1514 OS << Log2_32(ByteAlignment);
1515
1516 if (Value.has_value() || MaxBytesToEmit) {
1517 if (Value.has_value()) {
1518 OS << ", 0x";
1519 OS.write_hex(truncateToSize(*Value, ValueSize));
1520 } else {
1521 OS << ", ";
1522 }
1523
1524 if (MaxBytesToEmit)
1525 OS << ", " << MaxBytesToEmit;
1526 }
1527 EmitEOL();
1528 return;
1529 }
1530
1531 // Non-power of two alignment. This is not widely supported by assemblers.
1532 // FIXME: Parameterize this based on MAI.
1533 switch (ValueSize) {
1534 default: llvm_unreachable("Invalid size for machine code value!");
1535 case 1: OS << ".balign"; break;
1536 case 2: OS << ".balignw"; break;
1537 case 4: OS << ".balignl"; break;
1538 case 8: llvm_unreachable("Unsupported alignment size!");
1539 }
1540
1541 OS << ' ' << ByteAlignment;
1542 if (Value.has_value())
1543 OS << ", " << truncateToSize(*Value, ValueSize);
1544 else if (MaxBytesToEmit)
1545 OS << ", ";
1546 if (MaxBytesToEmit)
1547 OS << ", " << MaxBytesToEmit;
1548 EmitEOL();
1549}
1550
1551void MCAsmStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
1552 unsigned ValueSize,
1553 unsigned MaxBytesToEmit) {
1554 emitAlignmentDirective(Alignment.value(), Value, ValueSize, MaxBytesToEmit);
1555}
1556
1557void MCAsmStreamer::emitCodeAlignment(Align Alignment,
1558 const MCSubtargetInfo *STI,
1559 unsigned MaxBytesToEmit) {
1560 // Emit with a text fill value.
1561 if (MAI->getTextAlignFillValue())
1562 emitAlignmentDirective(Alignment.value(), MAI->getTextAlignFillValue(), 1,
1563 MaxBytesToEmit);
1564 else
1565 emitAlignmentDirective(Alignment.value(), std::nullopt, 1, MaxBytesToEmit);
1566}
1567
1568void MCAsmStreamer::emitValueToOffset(const MCExpr *Offset,
1569 unsigned char Value,
1570 SMLoc Loc) {
1571 // FIXME: Verify that Offset is associated with the current section.
1572 OS << ".org ";
1573 Offset->print(OS, MAI);
1574 OS << ", " << (unsigned)Value;
1575 EmitEOL();
1576}
1577
1578void MCAsmStreamer::emitFileDirective(StringRef Filename) {
1580 OS << "\t.file\t";
1581 PrintQuotedString(Filename, OS);
1582 EmitEOL();
1583}
1584
1585void MCAsmStreamer::emitFileDirective(StringRef Filename,
1586 StringRef CompilerVersion,
1587 StringRef TimeStamp,
1588 StringRef Description) {
1590 OS << "\t.file\t";
1591 PrintQuotedString(Filename, OS);
1592 bool useTimeStamp = !TimeStamp.empty();
1593 bool useCompilerVersion = !CompilerVersion.empty();
1594 bool useDescription = !Description.empty();
1595 if (useTimeStamp || useCompilerVersion || useDescription) {
1596 OS << ",";
1597 if (useTimeStamp)
1598 PrintQuotedString(TimeStamp, OS);
1599 if (useCompilerVersion || useDescription) {
1600 OS << ",";
1601 if (useCompilerVersion)
1602 PrintQuotedString(CompilerVersion, OS);
1603 if (useDescription) {
1604 OS << ",";
1605 PrintQuotedString(Description, OS);
1606 }
1607 }
1608 }
1609 EmitEOL();
1610}
1611
1612void MCAsmStreamer::printDwarfFileDirective(
1613 unsigned FileNo, StringRef Directory, StringRef Filename,
1614 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1615 bool UseDwarfDirectory, raw_svector_ostream &OS) const {
1616 SmallString<128> FullPathName;
1617
1618 if (!UseDwarfDirectory && !Directory.empty()) {
1619 if (sys::path::is_absolute(Filename))
1620 Directory = "";
1621 else {
1622 FullPathName = Directory;
1623 sys::path::append(FullPathName, Filename);
1624 Directory = "";
1625 Filename = FullPathName;
1626 }
1627 }
1628
1629 OS << "\t.file\t" << FileNo << ' ';
1630 if (!Directory.empty()) {
1631 PrintQuotedString(Directory, OS);
1632 OS << ' ';
1633 }
1634 PrintQuotedString(Filename, OS);
1635 if (Checksum)
1636 OS << " md5 0x" << Checksum->digest();
1637 if (Source) {
1638 OS << " source ";
1639 PrintQuotedString(*Source, OS);
1640 }
1641}
1642
1643Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective(
1644 unsigned FileNo, StringRef Directory, StringRef Filename,
1645 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1646 unsigned CUID) {
1647 assert(CUID == 0 && "multiple CUs not supported by MCAsmStreamer");
1648
1649 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
1650 unsigned NumFiles = Table.getMCDwarfFiles().size();
1651 Expected<unsigned> FileNoOrErr =
1652 Table.tryGetFile(Directory, Filename, Checksum, Source,
1653 getContext().getDwarfVersion(), FileNo);
1654 if (!FileNoOrErr)
1655 return FileNoOrErr.takeError();
1656 FileNo = FileNoOrErr.get();
1657
1658 // Return early if this file is already emitted before or if target doesn't
1659 // support .file directive.
1660 if (NumFiles == Table.getMCDwarfFiles().size() ||
1662 return FileNo;
1663
1664 SmallString<128> Str;
1665 raw_svector_ostream OS1(Str);
1666 printDwarfFileDirective(FileNo, Directory, Filename, Checksum, Source,
1667 UseDwarfDirectory, OS1);
1668
1669 if (MCTargetStreamer *TS = getTargetStreamer())
1670 TS->emitDwarfFileDirective(OS1.str());
1671 else
1672 emitRawText(OS1.str());
1673
1674 return FileNo;
1675}
1676
1677void MCAsmStreamer::emitDwarfFile0Directive(
1678 StringRef Directory, StringRef Filename,
1679 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1680 unsigned CUID) {
1681 assert(CUID == 0);
1682 // .file 0 is new for DWARF v5.
1683 if (getContext().getDwarfVersion() < 5)
1684 return;
1685 // Inform MCDwarf about the root file.
1686 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
1687 Source);
1688
1689 // Target doesn't support .loc/.file directives, return early.
1691 return;
1692
1693 SmallString<128> Str;
1694 raw_svector_ostream OS1(Str);
1695 printDwarfFileDirective(0, Directory, Filename, Checksum, Source,
1696 UseDwarfDirectory, OS1);
1697
1698 if (MCTargetStreamer *TS = getTargetStreamer())
1699 TS->emitDwarfFileDirective(OS1.str());
1700 else
1701 emitRawText(OS1.str());
1702}
1703
1704void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
1705 unsigned Column, unsigned Flags,
1706 unsigned Isa, unsigned Discriminator,
1707 StringRef FileName) {
1708 // If target doesn't support .loc/.file directive, we need to record the lines
1709 // same way like we do in object mode.
1710 if (!MAI->usesDwarfFileAndLocDirectives()) {
1711 // In case we see two .loc directives in a row, make sure the
1712 // first one gets a line entry.
1713 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
1714 this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
1715 Discriminator, FileName);
1716 return;
1717 }
1718
1719 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
1721 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
1722 OS << " basic_block";
1723 if (Flags & DWARF2_FLAG_PROLOGUE_END)
1724 OS << " prologue_end";
1725 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
1726 OS << " epilogue_begin";
1727
1728 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
1729 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
1730 OS << " is_stmt ";
1731
1732 if (Flags & DWARF2_FLAG_IS_STMT)
1733 OS << "1";
1734 else
1735 OS << "0";
1736 }
1737
1738 if (Isa)
1739 OS << " isa " << Isa;
1740 if (Discriminator)
1741 OS << " discriminator " << Discriminator;
1742 }
1743
1744 if (IsVerboseAsm) {
1745 OS.PadToColumn(MAI->getCommentColumn());
1746 OS << MAI->getCommentString() << ' ' << FileName << ':'
1747 << Line << ':' << Column;
1748 }
1749 EmitEOL();
1750 this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
1751 Discriminator, FileName);
1752}
1753
1754MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
1755 // Always use the zeroth line table, since asm syntax only supports one line
1756 // table for now.
1758}
1759
1760bool MCAsmStreamer::emitCVFileDirective(unsigned FileNo, StringRef Filename,
1761 ArrayRef<uint8_t> Checksum,
1762 unsigned ChecksumKind) {
1763 if (!getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
1764 ChecksumKind))
1765 return false;
1766
1767 OS << "\t.cv_file\t" << FileNo << ' ';
1768 PrintQuotedString(Filename, OS);
1769
1770 if (!ChecksumKind) {
1771 EmitEOL();
1772 return true;
1773 }
1774
1775 OS << ' ';
1776 PrintQuotedString(toHex(Checksum), OS);
1777 OS << ' ' << ChecksumKind;
1778
1779 EmitEOL();
1780 return true;
1781}
1782
1783bool MCAsmStreamer::emitCVFuncIdDirective(unsigned FuncId) {
1784 OS << "\t.cv_func_id " << FuncId << '\n';
1786}
1787
1788bool MCAsmStreamer::emitCVInlineSiteIdDirective(unsigned FunctionId,
1789 unsigned IAFunc,
1790 unsigned IAFile,
1791 unsigned IALine, unsigned IACol,
1792 SMLoc Loc) {
1793 OS << "\t.cv_inline_site_id " << FunctionId << " within " << IAFunc
1794 << " inlined_at " << IAFile << ' ' << IALine << ' ' << IACol << '\n';
1796 IALine, IACol, Loc);
1797}
1798
1799void MCAsmStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
1800 unsigned Line, unsigned Column,
1801 bool PrologueEnd, bool IsStmt,
1802 StringRef FileName, SMLoc Loc) {
1803 // Validate the directive.
1804 if (!checkCVLocSection(FunctionId, FileNo, Loc))
1805 return;
1806
1807 OS << "\t.cv_loc\t" << FunctionId << " " << FileNo << " " << Line << " "
1808 << Column;
1809 if (PrologueEnd)
1810 OS << " prologue_end";
1811
1812 if (IsStmt)
1813 OS << " is_stmt 1";
1814
1815 if (IsVerboseAsm) {
1816 OS.PadToColumn(MAI->getCommentColumn());
1817 OS << MAI->getCommentString() << ' ' << FileName << ':' << Line << ':'
1818 << Column;
1819 }
1820 EmitEOL();
1821}
1822
1823void MCAsmStreamer::emitCVLinetableDirective(unsigned FunctionId,
1824 const MCSymbol *FnStart,
1825 const MCSymbol *FnEnd) {
1826 OS << "\t.cv_linetable\t" << FunctionId << ", ";
1827 FnStart->print(OS, MAI);
1828 OS << ", ";
1829 FnEnd->print(OS, MAI);
1830 EmitEOL();
1831 this->MCStreamer::emitCVLinetableDirective(FunctionId, FnStart, FnEnd);
1832}
1833
1834void MCAsmStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
1835 unsigned SourceFileId,
1836 unsigned SourceLineNum,
1837 const MCSymbol *FnStartSym,
1838 const MCSymbol *FnEndSym) {
1839 OS << "\t.cv_inline_linetable\t" << PrimaryFunctionId << ' ' << SourceFileId
1840 << ' ' << SourceLineNum << ' ';
1841 FnStartSym->print(OS, MAI);
1842 OS << ' ';
1843 FnEndSym->print(OS, MAI);
1844 EmitEOL();
1846 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
1847}
1848
1849void MCAsmStreamer::PrintCVDefRangePrefix(
1850 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges) {
1851 OS << "\t.cv_def_range\t";
1852 for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {
1853 OS << ' ';
1854 Range.first->print(OS, MAI);
1855 OS << ' ';
1856 Range.second->print(OS, MAI);
1857 }
1858}
1859
1860void MCAsmStreamer::emitCVDefRangeDirective(
1861 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1863 PrintCVDefRangePrefix(Ranges);
1864 OS << ", reg_rel, ";
1865 OS << DRHdr.Register << ", " << DRHdr.Flags << ", "
1866 << DRHdr.BasePointerOffset;
1867 EmitEOL();
1868}
1869
1870void MCAsmStreamer::emitCVDefRangeDirective(
1871 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1873 PrintCVDefRangePrefix(Ranges);
1874 OS << ", subfield_reg, ";
1875 OS << DRHdr.Register << ", " << DRHdr.OffsetInParent;
1876 EmitEOL();
1877}
1878
1879void MCAsmStreamer::emitCVDefRangeDirective(
1880 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1882 PrintCVDefRangePrefix(Ranges);
1883 OS << ", reg, ";
1884 OS << DRHdr.Register;
1885 EmitEOL();
1886}
1887
1888void MCAsmStreamer::emitCVDefRangeDirective(
1889 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1891 PrintCVDefRangePrefix(Ranges);
1892 OS << ", frame_ptr_rel, ";
1893 OS << DRHdr.Offset;
1894 EmitEOL();
1895}
1896
1897void MCAsmStreamer::emitCVStringTableDirective() {
1898 OS << "\t.cv_stringtable";
1899 EmitEOL();
1900}
1901
1902void MCAsmStreamer::emitCVFileChecksumsDirective() {
1903 OS << "\t.cv_filechecksums";
1904 EmitEOL();
1905}
1906
1907void MCAsmStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {
1908 OS << "\t.cv_filechecksumoffset\t" << FileNo;
1909 EmitEOL();
1910}
1911
1912void MCAsmStreamer::emitCVFPOData(const MCSymbol *ProcSym, SMLoc L) {
1913 OS << "\t.cv_fpo_data\t";
1914 ProcSym->print(OS, MAI);
1915 EmitEOL();
1916}
1917
1918void MCAsmStreamer::emitIdent(StringRef IdentString) {
1919 assert(MAI->hasIdentDirective() && ".ident directive not supported");
1920 OS << "\t.ident\t";
1921 PrintQuotedString(IdentString, OS);
1922 EmitEOL();
1923}
1924
1925void MCAsmStreamer::emitCFISections(bool EH, bool Debug) {
1927 OS << "\t.cfi_sections ";
1928 if (EH) {
1929 OS << ".eh_frame";
1930 if (Debug)
1931 OS << ", .debug_frame";
1932 } else if (Debug) {
1933 OS << ".debug_frame";
1934 }
1935
1936 EmitEOL();
1937}
1938
1939void MCAsmStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
1940 OS << "\t.cfi_startproc";
1941 if (Frame.IsSimple)
1942 OS << " simple";
1943 EmitEOL();
1944}
1945
1946void MCAsmStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
1948 OS << "\t.cfi_endproc";
1949 EmitEOL();
1950}
1951
1952void MCAsmStreamer::EmitRegisterName(int64_t Register) {
1953 if (!MAI->useDwarfRegNumForCFI()) {
1954 // User .cfi_* directives can use arbitrary DWARF register numbers, not
1955 // just ones that map to LLVM register numbers and have known names.
1956 // Fall back to using the original number directly if no name is known.
1957 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1958 if (std::optional<unsigned> LLVMRegister =
1959 MRI->getLLVMRegNum(Register, true)) {
1960 InstPrinter->printRegName(OS, *LLVMRegister);
1961 return;
1962 }
1963 }
1964 OS << Register;
1965}
1966
1967void MCAsmStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) {
1969 OS << "\t.cfi_def_cfa ";
1970 EmitRegisterName(Register);
1971 OS << ", " << Offset;
1972 EmitEOL();
1973}
1974
1975void MCAsmStreamer::emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) {
1977 OS << "\t.cfi_def_cfa_offset " << Offset;
1978 EmitEOL();
1979}
1980
1981void MCAsmStreamer::emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
1982 int64_t AddressSpace, SMLoc Loc) {
1984 OS << "\t.cfi_llvm_def_aspace_cfa ";
1985 EmitRegisterName(Register);
1986 OS << ", " << Offset;
1987 OS << ", " << AddressSpace;
1988 EmitEOL();
1989}
1990
1992 OS << "\t.cfi_escape ";
1993 if (!Values.empty()) {
1994 size_t e = Values.size() - 1;
1995 for (size_t i = 0; i < e; ++i)
1996 OS << format("0x%02x", uint8_t(Values[i])) << ", ";
1997 OS << format("0x%02x", uint8_t(Values[e]));
1998 }
1999}
2000
2001void MCAsmStreamer::emitCFIEscape(StringRef Values, SMLoc Loc) {
2002 MCStreamer::emitCFIEscape(Values, Loc);
2003 PrintCFIEscape(OS, Values);
2004 EmitEOL();
2005}
2006
2007void MCAsmStreamer::emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) {
2009
2010 uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
2011 unsigned Len = encodeULEB128(Size, Buffer + 1) + 1;
2012
2013 PrintCFIEscape(OS, StringRef((const char *)&Buffer[0], Len));
2014 EmitEOL();
2015}
2016
2017void MCAsmStreamer::emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) {
2019 OS << "\t.cfi_def_cfa_register ";
2020 EmitRegisterName(Register);
2021 EmitEOL();
2022}
2023
2024void MCAsmStreamer::emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
2026 OS << "\t.cfi_offset ";
2027 EmitRegisterName(Register);
2028 OS << ", " << Offset;
2029 EmitEOL();
2030}
2031
2032void MCAsmStreamer::emitCFIPersonality(const MCSymbol *Sym,
2033 unsigned Encoding) {
2035 OS << "\t.cfi_personality " << Encoding << ", ";
2036 Sym->print(OS, MAI);
2037 EmitEOL();
2038}
2039
2040void MCAsmStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
2041 MCStreamer::emitCFILsda(Sym, Encoding);
2042 OS << "\t.cfi_lsda " << Encoding << ", ";
2043 Sym->print(OS, MAI);
2044 EmitEOL();
2045}
2046
2047void MCAsmStreamer::emitCFIRememberState(SMLoc Loc) {
2049 OS << "\t.cfi_remember_state";
2050 EmitEOL();
2051}
2052
2053void MCAsmStreamer::emitCFIRestoreState(SMLoc Loc) {
2055 OS << "\t.cfi_restore_state";
2056 EmitEOL();
2057}
2058
2059void MCAsmStreamer::emitCFIRestore(int64_t Register, SMLoc Loc) {
2061 OS << "\t.cfi_restore ";
2062 EmitRegisterName(Register);
2063 EmitEOL();
2064}
2065
2066void MCAsmStreamer::emitCFISameValue(int64_t Register, SMLoc Loc) {
2068 OS << "\t.cfi_same_value ";
2069 EmitRegisterName(Register);
2070 EmitEOL();
2071}
2072
2073void MCAsmStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset,
2074 SMLoc Loc) {
2076 OS << "\t.cfi_rel_offset ";
2077 EmitRegisterName(Register);
2078 OS << ", " << Offset;
2079 EmitEOL();
2080}
2081
2082void MCAsmStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) {
2083 MCStreamer::emitCFIAdjustCfaOffset(Adjustment, Loc);
2084 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
2085 EmitEOL();
2086}
2087
2088void MCAsmStreamer::emitCFISignalFrame() {
2090 OS << "\t.cfi_signal_frame";
2091 EmitEOL();
2092}
2093
2094void MCAsmStreamer::emitCFIUndefined(int64_t Register, SMLoc Loc) {
2096 OS << "\t.cfi_undefined ";
2097 EmitRegisterName(Register);
2098 EmitEOL();
2099}
2100
2101void MCAsmStreamer::emitCFIRegister(int64_t Register1, int64_t Register2,
2102 SMLoc Loc) {
2103 MCStreamer::emitCFIRegister(Register1, Register2, Loc);
2104 OS << "\t.cfi_register ";
2105 EmitRegisterName(Register1);
2106 OS << ", ";
2107 EmitRegisterName(Register2);
2108 EmitEOL();
2109}
2110
2111void MCAsmStreamer::emitCFIWindowSave(SMLoc Loc) {
2113 OS << "\t.cfi_window_save";
2114 EmitEOL();
2115}
2116
2117void MCAsmStreamer::emitCFINegateRAState(SMLoc Loc) {
2119 OS << "\t.cfi_negate_ra_state";
2120 EmitEOL();
2121}
2122
2123void MCAsmStreamer::emitCFIReturnColumn(int64_t Register) {
2125 OS << "\t.cfi_return_column ";
2126 EmitRegisterName(Register);
2127 EmitEOL();
2128}
2129
2130void MCAsmStreamer::emitCFIBKeyFrame() {
2132 OS << "\t.cfi_b_key_frame";
2133 EmitEOL();
2134}
2135
2136void MCAsmStreamer::emitCFIMTETaggedFrame() {
2138 OS << "\t.cfi_mte_tagged_frame";
2139 EmitEOL();
2140}
2141
2142void MCAsmStreamer::emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
2144
2145 OS << ".seh_proc ";
2146 Symbol->print(OS, MAI);
2147 EmitEOL();
2148}
2149
2150void MCAsmStreamer::emitWinCFIEndProc(SMLoc Loc) {
2152
2153 OS << "\t.seh_endproc";
2154 EmitEOL();
2155}
2156
2157void MCAsmStreamer::emitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
2159
2160 OS << "\t.seh_endfunclet";
2161 EmitEOL();
2162}
2163
2164void MCAsmStreamer::emitWinCFIStartChained(SMLoc Loc) {
2166
2167 OS << "\t.seh_startchained";
2168 EmitEOL();
2169}
2170
2171void MCAsmStreamer::emitWinCFIEndChained(SMLoc Loc) {
2173
2174 OS << "\t.seh_endchained";
2175 EmitEOL();
2176}
2177
2178void MCAsmStreamer::emitWinEHHandler(const MCSymbol *Sym, bool Unwind,
2179 bool Except, SMLoc Loc) {
2180 MCStreamer::emitWinEHHandler(Sym, Unwind, Except, Loc);
2181
2182 OS << "\t.seh_handler ";
2183 Sym->print(OS, MAI);
2184 char Marker = '@';
2185 const Triple &T = getContext().getTargetTriple();
2186 if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
2187 Marker = '%';
2188 if (Unwind)
2189 OS << ", " << Marker << "unwind";
2190 if (Except)
2191 OS << ", " << Marker << "except";
2192 EmitEOL();
2193}
2194
2195void MCAsmStreamer::emitWinEHHandlerData(SMLoc Loc) {
2197
2198 // Switch sections. Don't call switchSection directly, because that will
2199 // cause the section switch to be visible in the emitted assembly.
2200 // We only do this so the section switch that terminates the handler
2201 // data block is visible.
2202 WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
2203
2204 // Do nothing if no frame is open. MCStreamer should've already reported an
2205 // error.
2206 if (!CurFrame)
2207 return;
2208
2209 MCSection *TextSec = &CurFrame->Function->getSection();
2210 MCSection *XData = getAssociatedXDataSection(TextSec);
2211 switchSectionNoPrint(XData);
2212
2213 OS << "\t.seh_handlerdata";
2214 EmitEOL();
2215}
2216
2217void MCAsmStreamer::emitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
2219
2220 OS << "\t.seh_pushreg ";
2221 InstPrinter->printRegName(OS, Register);
2222 EmitEOL();
2223}
2224
2225void MCAsmStreamer::emitWinCFISetFrame(MCRegister Register, unsigned Offset,
2226 SMLoc Loc) {
2228
2229 OS << "\t.seh_setframe ";
2230 InstPrinter->printRegName(OS, Register);
2231 OS << ", " << Offset;
2232 EmitEOL();
2233}
2234
2235void MCAsmStreamer::emitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
2237
2238 OS << "\t.seh_stackalloc " << Size;
2239 EmitEOL();
2240}
2241
2242void MCAsmStreamer::emitWinCFISaveReg(MCRegister Register, unsigned Offset,
2243 SMLoc Loc) {
2245
2246 OS << "\t.seh_savereg ";
2247 InstPrinter->printRegName(OS, Register);
2248 OS << ", " << Offset;
2249 EmitEOL();
2250}
2251
2252void MCAsmStreamer::emitWinCFISaveXMM(MCRegister Register, unsigned Offset,
2253 SMLoc Loc) {
2255
2256 OS << "\t.seh_savexmm ";
2257 InstPrinter->printRegName(OS, Register);
2258 OS << ", " << Offset;
2259 EmitEOL();
2260}
2261
2262void MCAsmStreamer::emitWinCFIPushFrame(bool Code, SMLoc Loc) {
2264
2265 OS << "\t.seh_pushframe";
2266 if (Code)
2267 OS << " @code";
2268 EmitEOL();
2269}
2270
2271void MCAsmStreamer::emitWinCFIEndProlog(SMLoc Loc) {
2273
2274 OS << "\t.seh_endprologue";
2275 EmitEOL();
2276}
2277
2278void MCAsmStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
2279 const MCSymbolRefExpr *To,
2280 uint64_t Count) {
2281 OS << "\t.cg_profile ";
2282 From->getSymbol().print(OS, MAI);
2283 OS << ", ";
2284 To->getSymbol().print(OS, MAI);
2285 OS << ", " << Count;
2286 EmitEOL();
2287}
2288
2289void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
2290 const MCSubtargetInfo &STI) {
2291 raw_ostream &OS = getCommentOS();
2294
2295 // If we have no code emitter, don't emit code.
2296 if (!getAssembler().getEmitterPtr())
2297 return;
2298
2299 getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
2300
2301 // If we are showing fixups, create symbolic markers in the encoded
2302 // representation. We do this by making a per-bit map to the fixup item index,
2303 // then trying to display it as nicely as possible.
2304 SmallVector<uint8_t, 64> FixupMap;
2305 FixupMap.resize(Code.size() * 8);
2306 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
2307 FixupMap[i] = 0;
2308
2309 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
2310 MCFixup &F = Fixups[i];
2311 const MCFixupKindInfo &Info =
2312 getAssembler().getBackend().getFixupKindInfo(F.getKind());
2313 for (unsigned j = 0; j != Info.TargetSize; ++j) {
2314 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
2315 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
2316 FixupMap[Index] = 1 + i;
2317 }
2318 }
2319
2320 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
2321 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
2322 OS << "encoding: [";
2323 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
2324 if (i)
2325 OS << ',';
2326
2327 // See if all bits are the same map entry.
2328 uint8_t MapEntry = FixupMap[i * 8 + 0];
2329 for (unsigned j = 1; j != 8; ++j) {
2330 if (FixupMap[i * 8 + j] == MapEntry)
2331 continue;
2332
2333 MapEntry = uint8_t(~0U);
2334 break;
2335 }
2336
2337 if (MapEntry != uint8_t(~0U)) {
2338 if (MapEntry == 0) {
2339 OS << format("0x%02x", uint8_t(Code[i]));
2340 } else {
2341 if (Code[i]) {
2342 // FIXME: Some of the 8 bits require fix up.
2343 OS << format("0x%02x", uint8_t(Code[i])) << '\''
2344 << char('A' + MapEntry - 1) << '\'';
2345 } else
2346 OS << char('A' + MapEntry - 1);
2347 }
2348 } else {
2349 // Otherwise, write out in binary.
2350 OS << "0b";
2351 for (unsigned j = 8; j--;) {
2352 unsigned Bit = (Code[i] >> j) & 1;
2353
2354 unsigned FixupBit;
2355 if (MAI->isLittleEndian())
2356 FixupBit = i * 8 + j;
2357 else
2358 FixupBit = i * 8 + (7-j);
2359
2360 if (uint8_t MapEntry = FixupMap[FixupBit]) {
2361 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
2362 OS << char('A' + MapEntry - 1);
2363 } else
2364 OS << Bit;
2365 }
2366 }
2367 }
2368 OS << "]\n";
2369
2370 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
2371 MCFixup &F = Fixups[i];
2372 const MCFixupKindInfo &Info =
2373 getAssembler().getBackend().getFixupKindInfo(F.getKind());
2374 OS << " fixup " << char('A' + i) << " - "
2375 << "offset: " << F.getOffset() << ", value: ";
2376 F.getValue()->print(OS, MAI);
2377 OS << ", kind: " << Info.Name << "\n";
2378 }
2379}
2380
2381void MCAsmStreamer::emitInstruction(const MCInst &Inst,
2382 const MCSubtargetInfo &STI) {
2383 assert(getCurrentSectionOnly() &&
2384 "Cannot emit contents before setting section!");
2385
2387 // Now that a machine instruction has been assembled into this section, make
2388 // a line entry for any .loc directive that has been seen.
2389 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
2390
2391 // Show the encoding in a comment if we have a code emitter.
2392 AddEncodingComment(Inst, STI);
2393
2394 // Show the MCInst if enabled.
2395 if (ShowInst) {
2396 Inst.dump_pretty(getCommentOS(), InstPrinter.get(), "\n ");
2397 getCommentOS() << "\n";
2398 }
2399
2400 if(getTargetStreamer())
2401 getTargetStreamer()->prettyPrintAsm(*InstPrinter, 0, Inst, STI, OS);
2402 else
2403 InstPrinter->printInst(&Inst, 0, "", STI, OS);
2404
2405 StringRef Comments = CommentToEmit;
2406 if (Comments.size() && Comments.back() != '\n')
2407 getCommentOS() << "\n";
2408
2409 EmitEOL();
2410}
2411
2412void MCAsmStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index,
2413 uint64_t Type, uint64_t Attr,
2414 uint64_t Discriminator,
2415 const MCPseudoProbeInlineStack &InlineStack,
2416 MCSymbol *FnSym) {
2417 OS << "\t.pseudoprobe\t" << Guid << " " << Index << " " << Type << " " << Attr;
2418 if (Discriminator)
2419 OS << " " << Discriminator;
2420 // Emit inline stack like
2421 // @ GUIDmain:3 @ GUIDCaller:1 @ GUIDDirectCaller:11
2422 for (const auto &Site : InlineStack)
2423 OS << " @ " << std::get<0>(Site) << ":" << std::get<1>(Site);
2424
2425 OS << " " << FnSym->getName();
2426
2427 EmitEOL();
2428}
2429
2430void MCAsmStreamer::emitBundleAlignMode(Align Alignment) {
2431 OS << "\t.bundle_align_mode " << Log2(Alignment);
2432 EmitEOL();
2433}
2434
2435void MCAsmStreamer::emitBundleLock(bool AlignToEnd) {
2436 OS << "\t.bundle_lock";
2437 if (AlignToEnd)
2438 OS << " align_to_end";
2439 EmitEOL();
2440}
2441
2442void MCAsmStreamer::emitBundleUnlock() {
2443 OS << "\t.bundle_unlock";
2444 EmitEOL();
2445}
2446
2447std::optional<std::pair<bool, std::string>>
2448MCAsmStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
2449 const MCExpr *Expr, SMLoc,
2450 const MCSubtargetInfo &STI) {
2451 OS << "\t.reloc ";
2452 Offset.print(OS, MAI);
2453 OS << ", " << Name;
2454 if (Expr) {
2455 OS << ", ";
2456 Expr->print(OS, MAI);
2457 }
2458 EmitEOL();
2459 return std::nullopt;
2460}
2461
2462void MCAsmStreamer::emitAddrsig() {
2463 OS << "\t.addrsig";
2464 EmitEOL();
2465}
2466
2467void MCAsmStreamer::emitAddrsigSym(const MCSymbol *Sym) {
2468 OS << "\t.addrsig_sym ";
2469 Sym->print(OS, MAI);
2470 EmitEOL();
2471}
2472
2473/// EmitRawText - If this file is backed by an assembly streamer, this dumps
2474/// the specified string in the output .s file. This capability is
2475/// indicated by the hasRawTextSupport() predicate.
2476void MCAsmStreamer::emitRawTextImpl(StringRef String) {
2477 String.consume_back("\n");
2478 OS << String;
2479 EmitEOL();
2480}
2481
2482void MCAsmStreamer::finishImpl() {
2483 // If we are generating dwarf for assembly source files dump out the sections.
2484 if (getContext().getGenDwarfForAssembly())
2486
2487 // Now it is time to emit debug line sections if target doesn't support .loc
2488 // and .line directives.
2489 if (!MAI->usesDwarfFileAndLocDirectives()) {
2490 MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
2491 return;
2492 }
2493
2494 // Emit the label for the line table, if requested - since the rest of the
2495 // line table will be defined by .loc/.file directives, and not emitted
2496 // directly, the label is the only work required here.
2497 const auto &Tables = getContext().getMCDwarfLineTables();
2498 if (!Tables.empty()) {
2499 assert(Tables.size() == 1 && "asm output only supports one line table");
2500 if (auto *Label = Tables.begin()->second.getLabel()) {
2501 switchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
2502 emitLabel(Label);
2503 }
2504 }
2505}
2506
2507void MCAsmStreamer::emitDwarfUnitLength(uint64_t Length, const Twine &Comment) {
2508 // If the assembler on some target fills in the DWARF unit length, we
2509 // don't want to emit the length in the compiler. For example, the AIX
2510 // assembler requires the assembly file with the unit length omitted from
2511 // the debug section headers. In such cases, any label we placed occurs
2512 // after the implied length field. We need to adjust the reference here
2513 // to account for the offset introduced by the inserted length field.
2515 return;
2517}
2518
2519MCSymbol *MCAsmStreamer::emitDwarfUnitLength(const Twine &Prefix,
2520 const Twine &Comment) {
2521 // If the assembler on some target fills in the DWARF unit length, we
2522 // don't want to emit the length in the compiler. For example, the AIX
2523 // assembler requires the assembly file with the unit length omitted from
2524 // the debug section headers. In such cases, any label we placed occurs
2525 // after the implied length field. We need to adjust the reference here
2526 // to account for the offset introduced by the inserted length field.
2528 return getContext().createTempSymbol(Prefix + "_end");
2529 return MCStreamer::emitDwarfUnitLength(Prefix, Comment);
2530}
2531
2532void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
2533 // If the assembler on some target fills in the DWARF unit length, we
2534 // don't want to emit the length in the compiler. For example, the AIX
2535 // assembler requires the assembly file with the unit length omitted from
2536 // the debug section headers. In such cases, any label we placed occurs
2537 // after the implied length field. We need to adjust the reference here
2538 // to account for the offset introduced by the inserted length field.
2539 MCContext &Ctx = getContext();
2540 if (!MAI->needsDwarfSectionSizeInHeader()) {
2541 MCSymbol *DebugLineSymTmp = Ctx.createTempSymbol("debug_line_");
2542 // Emit the symbol which does not contain the unit length field.
2543 emitLabel(DebugLineSymTmp);
2544
2545 // Adjust the outer reference to account for the offset introduced by the
2546 // inserted length field.
2547 unsigned LengthFieldSize =
2549 const MCExpr *EntrySize = MCConstantExpr::create(LengthFieldSize, Ctx);
2550 const MCExpr *OuterSym = MCBinaryExpr::createSub(
2551 MCSymbolRefExpr::create(DebugLineSymTmp, Ctx), EntrySize, Ctx);
2552
2553 emitAssignment(StartSym, OuterSym);
2554 return;
2555 }
2557}
2558
2559void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section,
2560 MCSymbol *LastLabel) {
2561 // If the targets write the raw debug line data for assembly output (We can
2562 // not switch to Section and add the end symbol there for assembly output)
2563 // we currently use the .text end label as any section end. This will not
2564 // impact the debugability as we will jump to the caller of the last function
2565 // in the section before we come into the .text end address.
2567 ".loc should not be generated together with raw data!");
2568
2569 MCContext &Ctx = getContext();
2570
2571 // FIXME: use section end symbol as end of the Section. We need to consider
2572 // the explicit sections and -ffunction-sections when we try to generate or
2573 // find section end symbol for the Section.
2574 MCSection *TextSection = Ctx.getObjectFileInfo()->getTextSection();
2575 assert(TextSection->hasEnded() && ".text section is not end!");
2576
2577 MCSymbol *SectionEnd = TextSection->getEndSymbol(Ctx);
2578 const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
2579 emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
2580 AsmInfo->getCodePointerSize());
2581}
2582
2583// Generate DWARF line sections for assembly mode without .loc/.file
2584void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
2585 const MCSymbol *LastLabel,
2586 const MCSymbol *Label,
2587 unsigned PointerSize) {
2589 ".loc/.file don't need raw data in debug line section!");
2590
2591 // Set to new address.
2592 AddComment("Set address to " + Label->getName());
2593 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2594 emitULEB128IntValue(PointerSize + 1);
2595 emitIntValue(dwarf::DW_LNE_set_address, 1);
2596 emitSymbolValue(Label, PointerSize);
2597
2598 if (!LastLabel) {
2599 // Emit the sequence for the LineDelta (from 1) and a zero address delta.
2600 AddComment("Start sequence");
2601 MCDwarfLineAddr::Emit(this, MCDwarfLineTableParams(), LineDelta, 0);
2602 return;
2603 }
2604
2605 // INT64_MAX is a signal of the end of the section. Emit DW_LNE_end_sequence
2606 // for the end of the section.
2607 if (LineDelta == INT64_MAX) {
2608 AddComment("End sequence");
2609 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2610 emitULEB128IntValue(1);
2611 emitIntValue(dwarf::DW_LNE_end_sequence, 1);
2612 return;
2613 }
2614
2615 // Advance line.
2616 AddComment("Advance line " + Twine(LineDelta));
2617 emitIntValue(dwarf::DW_LNS_advance_line, 1);
2618 emitSLEB128IntValue(LineDelta);
2619 emitIntValue(dwarf::DW_LNS_copy, 1);
2620}
2621
2622void MCAsmStreamer::doFinalizationAtSectionEnd(MCSection *Section) {
2623 // Emit section end. This is used to tell the debug line section where the end
2624 // is for a text section if we don't use .loc to represent the debug line.
2626 return;
2627
2628 switchSectionNoPrint(Section);
2629
2630 MCSymbol *Sym = getCurrentSectionOnly()->getEndSymbol(getContext());
2631
2632 if (!Sym->isInSection())
2633 emitLabel(Sym);
2634}
2635
2637 std::unique_ptr<formatted_raw_ostream> OS,
2638 bool isVerboseAsm, bool useDwarfDirectory,
2639 MCInstPrinter *IP,
2640 std::unique_ptr<MCCodeEmitter> &&CE,
2641 std::unique_ptr<MCAsmBackend> &&MAB,
2642 bool ShowInst) {
2643 return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm,
2644 useDwarfDirectory, IP, std::move(CE), std::move(MAB),
2645 ShowInst);
2646}
unsigned const MachineRegisterInfo * MRI
BlockVerifier::State From
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define LLVM_LIKELY(EXPR)
Definition: Compiler.h:240
dxil pretty printer
std::string Name
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
IRTranslator LLVM IR MI
static LVOptions Options
Definition: LVOptions.cpp:25
static void PrintCFIEscape(llvm::formatted_raw_ostream &OS, StringRef Values)
static const char * getVersionMinDirective(MCVersionMinType Type)
static bool isPrintableString(StringRef Data)
static void PrintByteList(StringRef Data, raw_ostream &OS, MCAsmInfo::AsmCharLiteralSyntax ACLS)
static char toOctal(int X)
static void EmitSDKVersionSuffix(raw_ostream &OS, const VersionTuple &SDKVersion)
static int64_t truncateToSize(int64_t Value, unsigned Bytes)
static const char * getPlatformName(MachO::PlatformType Type)
#define DWARF2_FLAG_IS_STMT
Definition: MCDwarf.h:117
#define DWARF2_FLAG_BASIC_BLOCK
Definition: MCDwarf.h:118
#define DWARF2_FLAG_PROLOGUE_END
Definition: MCDwarf.h:119
#define DWARF2_FLAG_EPILOGUE_BEGIN
Definition: MCDwarf.h:120
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
bool Debug
Profile::FuncID FuncId
Definition: Profile.cpp:321
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallString class.
This file contains some functions that are useful when dealing with strings.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
void print(raw_ostream &OS) const
Print out the bounds to a stream.
Tagged union holding either a T or a Error.
Definition: Error.h:481
Error takeError()
Take ownership of the stored error.
Definition: Error.h:608
reference get()
Returns a reference to the stored T value.
Definition: Error.h:578
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
const char * getPlainStringDirective() const
Definition: MCAsmInfo.h:719
const char * getLabelSuffix() const
Definition: MCAsmInfo.h:659
bool hasDotTypeDotSizeDirective() const
Definition: MCAsmInfo.h:748
bool isLittleEndian() const
True if the target is little endian.
Definition: MCAsmInfo.h:555
bool doesSupportDataRegionDirectives() const
Definition: MCAsmInfo.h:699
const char * getTPRel64Directive() const
Definition: MCAsmInfo.h:573
const char * getData32bitsDirective() const
Definition: MCAsmInfo.h:566
bool hasFourStringsDotFile() const
Definition: MCAsmInfo.h:750
unsigned getAssemblerDialect() const
Definition: MCAsmInfo.h:682
unsigned getTextAlignFillValue() const
Definition: MCAsmInfo.h:724
bool useDwarfRegNumForCFI() const
Definition: MCAsmInfo.h:810
bool supportsExtendedDwarfLocDirective() const
Definition: MCAsmInfo.h:815
const char * getData8bitsDirective() const
Definition: MCAsmInfo.h:564
const char * getTPRel32Directive() const
Definition: MCAsmInfo.h:574
const char * getData64bitsDirective() const
Definition: MCAsmInfo.h:567
AsmCharLiteralSyntax characterLiteralSyntax() const
Definition: MCAsmInfo.h:720
const char * getByteListDirective() const
Definition: MCAsmInfo.h:718
const char * getCode16Directive() const
Definition: MCAsmInfo.h:679
const char * getGPRel64Directive() const
Definition: MCAsmInfo.h:569
LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const
Definition: MCAsmInfo.h:737
StringRef getCommentString() const
Definition: MCAsmInfo.h:651
const char * getAscizDirective() const
Definition: MCAsmInfo.h:717
const char * getDTPRel64Directive() const
Definition: MCAsmInfo.h:571
const char * getZeroDirective() const
Definition: MCAsmInfo.h:712
const char * getWeakDirective() const
Definition: MCAsmInfo.h:754
bool hasSubsectionsViaSymbols() const
Definition: MCAsmInfo.h:560
const char * getData16bitsDirective() const
Definition: MCAsmInfo.h:565
const char * getSeparatorString() const
Definition: MCAsmInfo.h:645
bool getCOMMDirectiveAlignmentIsInBytes() const
Definition: MCAsmInfo.h:733
bool hasPairedDoubleQuoteStringConstants() const
Definition: MCAsmInfo.h:744
bool needsDwarfSectionSizeInHeader() const
Definition: MCAsmInfo.h:823
const char * getGlobalDirective() const
Definition: MCAsmInfo.h:725
const char * getCode32Directive() const
Definition: MCAsmInfo.h:680
unsigned getCommentColumn() const
This indicates the column (zero-based) at which asm comments should be printed.
Definition: MCAsmInfo.h:649
const char * getCode64Directive() const
Definition: MCAsmInfo.h:681
bool hasSingleParameterDotFile() const
Definition: MCAsmInfo.h:749
bool doesZeroDirectiveSupportNonZeroValue() const
Definition: MCAsmInfo.h:713
const char * getAsciiDirective() const
Definition: MCAsmInfo.h:716
AsmCharLiteralSyntax
Assembly character literal syntax types.
Definition: MCAsmInfo.h:59
@ ACLS_SingleQuotePrefix
Unknown; character literals not used by LLVM for this target.
Definition: MCAsmInfo.h:62
bool useDotAlignForAlignment() const
Definition: MCAsmInfo.h:703
const char * getGPRel32Directive() const
Definition: MCAsmInfo.h:570
const char * getWeakRefDirective() const
Definition: MCAsmInfo.h:755
const char * getDTPRel32Directive() const
Definition: MCAsmInfo.h:572
bool hasNoDeadStrip() const
Definition: MCAsmInfo.h:752
bool usesDwarfFileAndLocDirectives() const
Definition: MCAsmInfo.h:819
bool hasIdentDirective() const
Definition: MCAsmInfo.h:751
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
Definition: MCAsmInfo.h:546
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:621
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
Context object for machine code objects.
Definition: MCContext.h:83
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:416
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:345
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:412
void setUseNamesOnTempLabels(bool Value)
Definition: MCContext.h:424
dwarf::DwarfFormat getDwarfFormat() const
Definition: MCContext.h:806
static void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta)
Utility function to emit the encoding to a streamer.
Definition: MCDwarf.cpp:674
static void make(MCStreamer *MCOS, MCSection *Section)
Definition: MCDwarf.cpp:95
static void emit(MCStreamer *MCOS, MCDwarfLineTableParams Params)
Definition: MCDwarf.cpp:260
Expected< unsigned > tryGetFile(StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, uint16_t DwarfVersion, unsigned FileNumber=0)
Definition: MCDwarf.cpp:575
const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles() const
Definition: MCDwarf.h:418
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:41
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
static void Emit(MCStreamer *MCOS)
Definition: MCDwarf.cpp:1143
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:45
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCRegisterInfo *RegInfo=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
Definition: MCInst.cpp:84
MCSection * getTextSection() const
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
This represents a section on a Mach-O system (used by Mac OS X).
StringRef getSegmentName() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:36
MCSymbol * getEndSymbol(MCContext &Ctx)
Definition: MCSection.cpp:33
StringRef getName() const
Definition: MCSection.h:142
bool hasEnded() const
Definition: MCSection.cpp:39
Streaming machine code generation interface.
Definition: MCStreamer.h:213
virtual void emitCFIGnuArgsSize(int64_t Size, SMLoc Loc={})
Definition: MCStreamer.cpp:638
virtual void emitAddrsig()
Definition: MCStreamer.h:1083
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
virtual void emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc={})
Definition: MCStreamer.cpp:496
virtual void addBlankLine()
Emit a blank line to a .s file to pretty it up.
Definition: MCStreamer.h:389
virtual void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel)
Emit the debug line end entry.
Definition: MCStreamer.h:1137
virtual bool emitCVFuncIdDirective(unsigned FunctionId)
Introduces a function id for use with .cv_loc.
Definition: MCStreamer.cpp:302
virtual void finishImpl()
Streamer specific finalization.
virtual void emitDTPRel64Value(const MCExpr *Value)
Emit the expression Value into the output as a dtprel (64-bit DTP relative) value.
Definition: MCStreamer.cpp:195
virtual void emitCFIBKeyFrame()
Definition: MCStreamer.cpp:249
virtual void beginCOFFSymbolDef(const MCSymbol *Symbol)
Start emitting COFF symbol definition.
virtual void emitSyntaxDirective()
Definition: MCStreamer.cpp:866
virtual void emitWinCFIPushReg(MCRegister Register, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:872
virtual void emitBinaryData(StringRef Data)
Functionally identical to EmitBytes.
virtual StringRef getMnemonic(MCInst &MI)
Returns the mnemonic for MI, if the streamer has access to a instruction printer and returns an empty...
Definition: MCStreamer.h:460
virtual void emitGNUAttribute(unsigned Tag, unsigned Value)
Emit a .gnu_attribute directive.
Definition: MCStreamer.h:655
virtual raw_ostream & getCommentOS()
Return a raw_ostream that comments can be written to.
Definition: MCStreamer.cpp:111
virtual void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:791
virtual void emitBundleLock(bool AlignToEnd)
The following instructions are a bundle-locked group.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitGPRel64Value(const MCExpr *Value)
Emit the expression Value into the output as a gprel64 (64-bit GP relative) value.
Definition: MCStreamer.cpp:211
virtual void emitCFISameValue(int64_t Register, SMLoc Loc={})
Definition: MCStreamer.cpp:608
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
virtual bool emitCVFileDirective(unsigned FileNo, StringRef Filename, ArrayRef< uint8_t > Checksum, unsigned ChecksumKind)
Associate a filename with a specified logical file number, and also specify that file's checksum info...
Definition: MCStreamer.cpp:295
virtual void emitCFIReturnColumn(int64_t Register)
Definition: MCStreamer.cpp:695
virtual void emitCOFFSymbolType(int Type)
Emit the type of the symbol.
virtual void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding)
Definition: MCStreamer.cpp:570
virtual void emitDwarfUnitLength(uint64_t Length, const Twine &Comment)
Emit a unit length field.
virtual void emitCFIWindowSave(SMLoc Loc={})
Definition: MCStreamer.cpp:676
virtual void emitCOFFSymbolIndex(MCSymbol const *Symbol)
Emits the symbol table index of a Symbol into the current section.
Definition: MCStreamer.cpp:981
virtual void emitCVStringTableDirective()
This implements the CodeView '.cv_stringtable' assembler directive.
Definition: MCStreamer.h:989
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText.
Definition: MCStreamer.h:349
virtual void emitIntValueInHex(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers & p...
Definition: MCStreamer.h:729
virtual void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, StringRef FileName)
This implements the DWARF2 '.loc fileno lineno ...' assembler directive.
Definition: MCStreamer.cpp:263
virtual bool isVerboseAsm() const
Return true if this streamer supports verbose assembly and if it is enabled.
Definition: MCStreamer.h:345
virtual void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset)
Emits a COFF image relative relocation.
Definition: MCStreamer.cpp:987
virtual void endCOFFSymbolDef()
Marks the end of the symbol definition.
virtual void emitWinCFIPushFrame(bool Code, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:955
virtual void emitWinEHHandlerData(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:808
virtual void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment)=0
Emit a common symbol.
virtual MCAssembler * getAssemblerPtr()
Definition: MCStreamer.h:308
virtual void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility)
Emit a symbol's linkage and visibility with a linkage directive for XCOFF.
virtual void emitCFIUndefined(int64_t Register, SMLoc Loc={})
Definition: MCStreamer.cpp:655
virtual void emitWinCFISaveXMM(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:940
virtual void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame)
Definition: MCStreamer.cpp:473
virtual void emitCVFileChecksumOffsetDirective(unsigned FileNo)
This implements the CodeView '.cv_filechecksumoffset' assembler directive.
Definition: MCStreamer.h:996
virtual void emitCFINegateRAState(SMLoc Loc={})
Definition: MCStreamer.cpp:685
virtual void emitGPRel32Value(const MCExpr *Value)
Emit the expression Value into the output as a gprel32 (32-bit GP relative) value.
Definition: MCStreamer.cpp:215
virtual void emitCFILsda(const MCSymbol *Sym, unsigned Encoding)
Definition: MCStreamer.cpp:579
virtual void emitBundleUnlock()
Ends a bundle-locked group.
virtual Expected< unsigned > tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, std::optional< MD5::MD5Result > Checksum=std::nullopt, std::optional< StringRef > Source=std::nullopt, unsigned CUID=0)
Associate a filename with a specified logical file number.
Definition: MCStreamer.cpp:232
virtual void addExplicitComment(const Twine &T)
Add explicit comment T.
Definition: MCStreamer.cpp:123
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition: MCStreamer.h:368
virtual void emitCVFPOData(const MCSymbol *ProcSym, SMLoc Loc={})
This implements the CodeView '.cv_fpo_data' assembler directive.
Definition: MCStreamer.h:999
virtual void emitELFSize(MCSymbol *Symbol, const MCExpr *Value)
Emit an ELF .size directive.
virtual void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size, MCSymbol *CsectSym, Align Alignment)
Emits an lcomm directive with XCOFF csect information.
virtual void emitCFIMTETaggedFrame()
Definition: MCStreamer.cpp:256
virtual void emitTPRel32Value(const MCExpr *Value)
Emit the expression Value into the output as a tprel (32-bit TP relative) value.
Definition: MCStreamer.cpp:207
virtual void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset)
Emits a COFF section relative relocation.
Definition: MCStreamer.cpp:985
virtual void doFinalizationAtSectionEnd(MCSection *Section)
Do finalization for the streamer at the end of a section.
Definition: MCStreamer.h:1148
virtual void emitRawComment(const Twine &T, bool TabPrefix=true)
Print T and prefix it with the comment string (normally #) and optionally a tab.
Definition: MCStreamer.cpp:121
virtual std::optional< std::pair< bool, std::string > > emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc, const MCSubtargetInfo &STI)
Record a relocation described by the .reloc directive.
Definition: MCStreamer.h:1078
virtual void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:717
virtual void emitIdent(StringRef IdentString)
Emit the "identifiers" directive.
Definition: MCStreamer.h:892
virtual void emitCVFileChecksumsDirective()
This implements the CodeView '.cv_filechecksums' assembler directive.
Definition: MCStreamer.h:992
virtual void emitDwarfLineStartLabel(MCSymbol *StartSym)
Emit the debug line start label.
virtual void emitCFIEscape(StringRef Values, SMLoc Loc={})
Definition: MCStreamer.cpp:628
virtual void emitXCOFFExceptDirective(const MCSymbol *Symbol, const MCSymbol *Trap, unsigned Lang, unsigned Reason, unsigned FunctionSize, bool hasDebug)
Emit an XCOFF .except directive which adds information about a trap instruction to the object file ex...
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:424
virtual void emitCOFFSectionIndex(MCSymbol const *Symbol)
Emits a COFF section index.
Definition: MCStreamer.cpp:983
void setAllowAutoPadding(bool v)
Definition: MCStreamer.h:317
virtual void emitCFIRememberState(SMLoc Loc)
Definition: MCStreamer.cpp:587
virtual void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart, const MCSymbol *FnEnd)
This implements the CodeView '.cv_linetable' assembler directive.
Definition: MCStreamer.cpp:347
virtual void emitTPRel64Value(const MCExpr *Value)
Emit the expression Value into the output as a tprel (64-bit TP relative) value.
Definition: MCStreamer.cpp:203
virtual void emitCFISections(bool EH, bool Debug)
Definition: MCStreamer.cpp:446
virtual void emitIntValueInHexWithPadding(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers & p...
Definition: MCStreamer.h:741
virtual void emitAssemblerFlag(MCAssemblerFlag Flag)
Note in the output the specified Flag.
virtual void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
Definition: MCStreamer.h:497
virtual void emitValueToAlignment(Align Alignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0)
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
Definition: MCStreamer.cpp:134
virtual void emitWinCFISaveReg(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:923
virtual void emitWinCFIEndChained(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:777
virtual void emitWinCFIEndProlog(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:969
virtual void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, unsigned PointerSize)
If targets does not support representing debug line section by .loc/.file directives in assembly outp...
Definition: MCStreamer.h:1142
virtual void emitWinCFIEndProc(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:735
virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit=0)
Emit nops until the byte alignment ByteAlignment is reached.
virtual void emitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame)
Definition: MCStreamer.cpp:484
virtual void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue)
Set the DescValue for the Symbol.
virtual void emitCFIDefCfaRegister(int64_t Register, SMLoc Loc={})
Definition: MCStreamer.cpp:527
virtual void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment)
Emit a local common (.lcomm) symbol.
virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)
Definition: MCStreamer.cpp:271
virtual void emitCFIRegister(int64_t Register1, int64_t Register2, SMLoc Loc={})
Definition: MCStreamer.cpp:665
virtual void emitCOFFSafeSEH(MCSymbol const *Symbol)
Definition: MCStreamer.cpp:979
virtual void emitWinCFIFuncletOrFuncEnd(SMLoc Loc=SMLoc())
This is used on platforms, such as Windows on ARM64, that require function or funclet sizes to be emi...
Definition: MCStreamer.cpp:753
virtual void emitXCOFFRenameDirective(const MCSymbol *Name, StringRef Rename)
Emit a XCOFF .rename directive which creates a synonym for an illegal or undesirable name.
virtual void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type, uint64_t Attr, uint64_t Discriminator, const MCPseudoProbeInlineStack &InlineStack, MCSymbol *FnSym)
Emit the a pseudo probe into the current section.
virtual void emitCGProfileEntry(const MCSymbolRefExpr *From, const MCSymbolRefExpr *To, uint64_t Count)
Definition: MCStreamer.cpp:816
virtual void emitDataRegion(MCDataRegionType Kind)
Note in the output the specified region Kind.
Definition: MCStreamer.h:484
virtual void emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc={})
Definition: MCStreamer.cpp:517
virtual void emitULEB128Value(const MCExpr *Value)
virtual void emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc)
Definition: MCStreamer.cpp:560
virtual void emitLinkerOptions(ArrayRef< std::string > Kind)
Emit the given list Options of strings as linker options into the output.
Definition: MCStreamer.h:481
virtual void emitValueToOffset(const MCExpr *Offset, unsigned char Value, SMLoc Loc)
Emit some number of copies of Value until the byte offset Offset is reached.
virtual void emitExplicitComments()
Emit added explicit comments.
Definition: MCStreamer.cpp:124
virtual void emitThumbFunc(MCSymbol *Func)
Note in the output that the specified Func is a Thumb mode function (ARM target only).
virtual void emitCFIRestoreState(SMLoc Loc)
Definition: MCStreamer.cpp:597
virtual void emitXCOFFRefDirective(const MCSymbol *Symbol)
Emit a XCOFF .ref directive which creates R_REF type entry in the relocation table for one or more sy...
virtual void emitCVDefRangeDirective(ArrayRef< std::pair< const MCSymbol *, const MCSymbol * > > Ranges, StringRef FixedSizePortion)
This implements the CodeView '.cv_def_range' assembler directive.
Definition: MCStreamer.cpp:369
virtual void emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc={})
Definition: MCStreamer.cpp:550
virtual void emitWinCFISetFrame(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:884
virtual void emitDTPRel32Value(const MCExpr *Value)
Emit the expression Value into the output as a dtprel (32-bit DTP relative) value.
Definition: MCStreamer.cpp:199
virtual void emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc={})
Definition: MCStreamer.cpp:507
virtual void emitZerofill(MCSection *Section, MCSymbol *Symbol=nullptr, uint64_t Size=0, Align ByteAlignment=Align(1), SMLoc Loc=SMLoc())=0
Emit the zerofill section and an optional symbol.
virtual void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line, unsigned Column, bool PrologueEnd, bool IsStmt, StringRef FileName, SMLoc Loc)
This implements the CodeView '.cv_loc' assembler directive.
Definition: MCStreamer.cpp:320
virtual void emitWinCFIAllocStack(unsigned Size, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:906
virtual void emitFileDirective(StringRef Filename)
Switch to a new logical file.
virtual void emitSLEB128Value(const MCExpr *Value)
virtual void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name, bool KeepOriginalSym)
Emit an ELF .symver directive.
virtual void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata)
Emit a C_INFO symbol with XCOFF embedded metadata to the .info section.
virtual void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Emit the expression Value into the output as a native integer of the given Size bytes.
virtual void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args)
Emit a Linker Optimization Hint (LOH) directive.
Definition: MCStreamer.h:652
virtual bool emitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc, unsigned IAFile, unsigned IALine, unsigned IACol, SMLoc Loc)
Introduces an inline call site id for use with .cv_loc.
Definition: MCStreamer.cpp:306
virtual void emitCFISignalFrame()
Definition: MCStreamer.cpp:648
virtual void emitVersionMin(MCVersionMinType Type, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
Specify the Mach-O minimum deployment target version.
Definition: MCStreamer.h:487
virtual void emitCOFFSymbolStorageClass(int StorageClass)
Emit the storage class of the symbol.
virtual void emitConditionalAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol, but only if Value is also emitted.
Definition: MCStreamer.cpp:443
virtual void emitWinCFIStartChained(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:764
virtual void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, Align ByteAlignment=Align(1))
Emit a thread local bss (.tbss) symbol.
virtual void emitCFIRestore(int64_t Register, SMLoc Loc={})
Definition: MCStreamer.cpp:618
virtual void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym)
This implements the CodeView '.cv_inline_linetable' assembler directive.
Definition: MCStreamer.cpp:351
void emitFill(uint64_t NumBytes, uint8_t FillValue)
Emit NumBytes bytes worth of the value specified by FillValue.
Definition: MCStreamer.cpp:221
virtual void emitBundleAlignMode(Align Alignment)
Set the bundle alignment mode from now on in the section.
virtual void emitRawTextImpl(StringRef String)
EmitRawText - If this file is backed by an assembly streamer, this dumps the specified string in the ...
Definition: MCStreamer.cpp:992
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
virtual void emitAddrsigSym(const MCSymbol *Sym)
Definition: MCStreamer.h:1084
virtual void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol)
Emit an weak reference from Alias to Symbol.
virtual void emitDwarfFile0Directive(StringRef Directory, StringRef Filename, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, unsigned CUID=0)
Specify the "root" file of the compilation, using the ".file 0" extension.
Definition: MCStreamer.cpp:240
virtual void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
Emit/Specify Mach-O build version command.
Definition: MCStreamer.h:493
virtual void changeSection(MCSection *, uint32_t)
This is called by popSection and switchSection, if the current section changes.
virtual void emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset, int64_t AddressSpace, SMLoc Loc={})
Definition: MCStreamer.cpp:538
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
const MCSymbol & getSymbol() const
Definition: MCExpr.h:410
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:397
StringRef getSymbolTableName() const
Definition: MCSymbolXCOFF.h:68
bool hasRename() const
Definition: MCSymbolXCOFF.h:61
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:58
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:269
Target specific streamer interface.
Definition: MCStreamer.h:94
Root of the metadata hierarchy.
Definition: Metadata.h:62
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Represents a location in source code.
Definition: SMLoc.h:23
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
void append(StringRef RHS)
Append from a StringRef.
Definition: SmallString.h:68
bool empty() const
Definition: SmallVector.h:94
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void resize(size_type N)
Definition: SmallVector.h:651
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:223
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:564
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:258
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
char back() const
back - Get the last character in the string.
Definition: StringRef.h:146
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:677
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
char front() const
front - Get the first character in the string.
Definition: StringRef.h:140
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
Definition: StringRef.h:370
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:290
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:5022
Represents a version number in the form major[.minor[.subminor[.build]]].
Definition: VersionTuple.h:29
unsigned getMajor() const
Retrieve the major version number.
Definition: VersionTuple.h:71
std::optional< unsigned > getSubminor() const
Retrieve the subminor version number, if provided.
Definition: VersionTuple.h:81
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero).
Definition: VersionTuple.h:66
std::optional< unsigned > getMinor() const
Retrieve the minor version number, if provided.
Definition: VersionTuple.h:74
formatted_raw_ostream - A raw_ostream that wraps another one and keeps track of line and column posit...
A raw_ostream that discards all output.
Definition: raw_ostream.h:731
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
size_t GetNumBytesInBuffer() const
Definition: raw_ostream.h:194
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:691
This class represents a function that is read from a sample profile.
Definition: FunctionId.h:36
#define INT64_MAX
Definition: DataTypes.h:71
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ ByteAlignment
Definition: MCAsmInfo.h:50
@ Log2Alignment
Definition: MCAsmInfo.h:50
PlatformType
Definition: MachO.h:500
StorageClass
Definition: XCOFF.h:170
uint8_t getUnitLengthFieldByteSize(DwarfFormat Format)
Get the byte size of the unit length field depending on the DWARF format.
Definition: Dwarf.h:1103
support::ulittle32_t Word
Definition: IRSymtab.h:52
@ ChecksumKind
Definition: LLToken.h:489
int getDwarfVersion()
@ Emitted
Assigned address, still materializing.
NodeAddr< FuncNode * > Func
Definition: RDFGraph.h:393
NodeAddr< CodeNode * > Code
Definition: RDFGraph.h:388
uint32_t read32be(const void *P)
Definition: Endian.h:434
bool isPrint(int c)
Definition: Locale.cpp:13
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition: Path.cpp:672
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:457
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
@ Offset
Definition: DWP.cpp:480
@ Length
Definition: DWP.cpp:480
AddressSpace
Definition: NVPTXBaseInfo.h:21
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
static StringRef MCLOHDirectiveName()
MCDataRegionType
Definition: MCDirectives.h:61
@ MCDR_DataRegionEnd
.end_data_region
Definition: MCDirectives.h:66
@ MCDR_DataRegion
.data_region
Definition: MCDirectives.h:62
@ MCDR_DataRegionJT8
.data_region jt8
Definition: MCDirectives.h:63
@ MCDR_DataRegionJT32
.data_region jt32
Definition: MCDirectives.h:65
@ MCDR_DataRegionJT16
.data_region jt16
Definition: MCDirectives.h:64
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:324
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:275
MCVersionMinType
Definition: MCDirectives.h:69
@ MCVM_WatchOSVersionMin
.watchos_version_min
Definition: MCDirectives.h:73
@ MCVM_OSXVersionMin
.macosx_version_min
Definition: MCDirectives.h:71
@ MCVM_TvOSVersionMin
.tvos_version_min
Definition: MCDirectives.h:72
@ MCVM_IOSVersionMin
.ios_version_min
Definition: MCDirectives.h:70
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
Definition: Format.h:187
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:125
static int MCLOHIdToNbArgs(MCLOHType Kind)
MCAssemblerFlag
Definition: MCDirectives.h:53
@ MCAF_SyntaxUnified
.syntax (ARM/ELF)
Definition: MCDirectives.h:54
@ MCAF_Code64
.code64 (X86)
Definition: MCDirectives.h:58
@ MCAF_Code16
.code16 (X86) / .code 16 (ARM)
Definition: MCDirectives.h:56
@ MCAF_Code32
.code32 (X86) / .code 32 (ARM)
Definition: MCDirectives.h:57
@ MCAF_SubsectionsViaSymbols
.subsections_via_symbols (MachO)
Definition: MCDirectives.h:55
MCLOHType
Linker Optimization Hint Type.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
MCStreamer * createAsmStreamer(MCContext &Ctx, std::unique_ptr< formatted_raw_ostream > OS, bool isVerboseAsm, bool useDwarfDirectory, MCInstPrinter *InstPrint, std::unique_ptr< MCCodeEmitter > &&CE, std::unique_ptr< MCAsmBackend > &&TAB, bool ShowInst)
Create a machine code streamer which will print out assembly for the native target,...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1849
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:80
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition: Alignment.h:208
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition: bit.h:327
MCSymbolAttr
Definition: MCDirectives.h:18
@ MCSA_Local
.local (ELF)
Definition: MCDirectives.h:38
@ MCSA_WeakDefAutoPrivate
.weak_def_can_be_hidden (MachO)
Definition: MCDirectives.h:48
@ MCSA_Memtag
.memtag (ELF)
Definition: MCDirectives.h:50
@ MCSA_Protected
.protected (ELF)
Definition: MCDirectives.h:43
@ MCSA_Exported
.globl _foo, exported (XCOFF)
Definition: MCDirectives.h:34
@ MCSA_PrivateExtern
.private_extern (MachO)
Definition: MCDirectives.h:42
@ MCSA_Internal
.internal (ELF)
Definition: MCDirectives.h:36
@ MCSA_WeakReference
.weak_reference (MachO)
Definition: MCDirectives.h:47
@ MCSA_AltEntry
.alt_entry (MachO)
Definition: MCDirectives.h:41
@ MCSA_ELF_TypeIndFunction
.type _foo, STT_GNU_IFUNC
Definition: MCDirectives.h:24
@ MCSA_LazyReference
.lazy_reference (MachO)
Definition: MCDirectives.h:37
@ MCSA_ELF_TypeNoType
.type _foo, STT_NOTYPE # aka @notype
Definition: MCDirectives.h:28
@ MCSA_Reference
.reference (MachO)
Definition: MCDirectives.h:44
@ MCSA_SymbolResolver
.symbol_resolver (MachO)
Definition: MCDirectives.h:40
@ MCSA_Weak
.weak
Definition: MCDirectives.h:45
@ MCSA_ELF_TypeTLS
.type _foo, STT_TLS # aka @tls_object
Definition: MCDirectives.h:26
@ MCSA_IndirectSymbol
.indirect_symbol (MachO)
Definition: MCDirectives.h:35
@ MCSA_WeakDefinition
.weak_definition (MachO)
Definition: MCDirectives.h:46
@ MCSA_ELF_TypeCommon
.type _foo, STT_COMMON # aka @common
Definition: MCDirectives.h:27
@ MCSA_Global
.type _foo, @gnu_unique_object
Definition: MCDirectives.h:30
@ MCSA_WeakAntiDep
.weak_anti_dep (COFF)
Definition: MCDirectives.h:49
@ MCSA_Extern
.extern (XCOFF)
Definition: MCDirectives.h:32
@ MCSA_Cold
.cold (MachO)
Definition: MCDirectives.h:22
@ MCSA_ELF_TypeObject
.type _foo, STT_OBJECT # aka @object
Definition: MCDirectives.h:25
@ MCSA_ELF_TypeGnuUniqueObject
Definition: MCDirectives.h:29
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Definition: MCDirectives.h:23
@ MCSA_Hidden
.hidden (ELF)
Definition: MCDirectives.h:33
@ MCSA_LGlobal
.lglobl (XCOFF)
Definition: MCDirectives.h:31
@ MCSA_Invalid
Not a valid directive.
Definition: MCDirectives.h:19
@ MCSA_NoDeadStrip
.no_dead_strip (MachO)
Definition: MCDirectives.h:39
static StringRef MCLOHIdToName(MCLOHType Kind)
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
Target independent information on a fixup kind.
const MCSymbol * Function
Definition: MCWinEH.h:44