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