[MIPS GlobalISel] Select MSA vector generic and builtin add
[llvm-complete.git] / lib / MC / MCStreamer.cpp
blobb8278cb1107994b9b09575527a55fcfe86a143fe
1 //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
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 //===----------------------------------------------------------------------===//
9 #include "llvm/MC/MCStreamer.h"
10 #include "llvm/ADT/Optional.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/BinaryFormat/COFF.h"
15 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
16 #include "llvm/MC/MCAsmBackend.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCCodeView.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCDwarf.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCInstPrinter.h"
24 #include "llvm/MC/MCObjectFileInfo.h"
25 #include "llvm/MC/MCRegister.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCSection.h"
28 #include "llvm/MC/MCSectionCOFF.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/MC/MCWin64EH.h"
31 #include "llvm/MC/MCWinEH.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/LEB128.h"
35 #include "llvm/Support/MathExtras.h"
36 #include "llvm/Support/raw_ostream.h"
37 #include <cassert>
38 #include <cstdint>
39 #include <cstdlib>
40 #include <utility>
42 using namespace llvm;
44 MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
45 S.setTargetStreamer(this);
48 // Pin the vtables to this file.
49 MCTargetStreamer::~MCTargetStreamer() = default;
51 void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
53 void MCTargetStreamer::finish() {}
55 void MCTargetStreamer::changeSection(const MCSection *CurSection,
56 MCSection *Section,
57 const MCExpr *Subsection,
58 raw_ostream &OS) {
59 Section->PrintSwitchToSection(
60 *Streamer.getContext().getAsmInfo(),
61 Streamer.getContext().getObjectFileInfo()->getTargetTriple(), OS,
62 Subsection);
65 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
66 Streamer.EmitRawText(Directive);
69 void MCTargetStreamer::emitValue(const MCExpr *Value) {
70 SmallString<128> Str;
71 raw_svector_ostream OS(Str);
73 Value->print(OS, Streamer.getContext().getAsmInfo());
74 Streamer.EmitRawText(OS.str());
77 void MCTargetStreamer::emitRawBytes(StringRef Data) {
78 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
79 const char *Directive = MAI->getData8bitsDirective();
80 for (const unsigned char C : Data.bytes()) {
81 SmallString<128> Str;
82 raw_svector_ostream OS(Str);
84 OS << Directive << (unsigned)C;
85 Streamer.EmitRawText(OS.str());
89 void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
91 MCStreamer::MCStreamer(MCContext &Ctx)
92 : Context(Ctx), CurrentWinFrameInfo(nullptr),
93 UseAssemblerInfoForParsing(false) {
94 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
97 MCStreamer::~MCStreamer() {}
99 void MCStreamer::reset() {
100 DwarfFrameInfos.clear();
101 CurrentWinFrameInfo = nullptr;
102 WinFrameInfos.clear();
103 SymbolOrdering.clear();
104 SectionStack.clear();
105 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
108 raw_ostream &MCStreamer::GetCommentOS() {
109 // By default, discard comments.
110 return nulls();
113 unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos.size(); }
114 ArrayRef<MCDwarfFrameInfo> MCStreamer::getDwarfFrameInfos() const {
115 return DwarfFrameInfos;
118 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
120 void MCStreamer::addExplicitComment(const Twine &T) {}
121 void MCStreamer::emitExplicitComments() {}
123 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
124 for (auto &FI : DwarfFrameInfos)
125 FI.CompactUnwindEncoding =
126 (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
129 /// EmitIntValue - Special case of EmitValue that avoids the client having to
130 /// pass in a MCExpr for constant integers.
131 void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
132 assert(1 <= Size && Size <= 8 && "Invalid size");
133 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
134 "Invalid size");
135 char buf[8];
136 const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian();
137 for (unsigned i = 0; i != Size; ++i) {
138 unsigned index = isLittleEndian ? i : (Size - i - 1);
139 buf[i] = uint8_t(Value >> (index * 8));
141 EmitBytes(StringRef(buf, Size));
144 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
145 /// client having to pass in a MCExpr for constant integers.
146 void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned PadTo) {
147 SmallString<128> Tmp;
148 raw_svector_ostream OSE(Tmp);
149 encodeULEB128(Value, OSE, PadTo);
150 EmitBytes(OSE.str());
153 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
154 /// client having to pass in a MCExpr for constant integers.
155 void MCStreamer::EmitSLEB128IntValue(int64_t Value) {
156 SmallString<128> Tmp;
157 raw_svector_ostream OSE(Tmp);
158 encodeSLEB128(Value, OSE);
159 EmitBytes(OSE.str());
162 void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
163 EmitValueImpl(Value, Size, Loc);
166 void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
167 bool IsSectionRelative) {
168 assert((!IsSectionRelative || Size == 4) &&
169 "SectionRelative value requires 4-bytes");
171 if (!IsSectionRelative)
172 EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
173 else
174 EmitCOFFSecRel32(Sym, /*Offset=*/0);
177 void MCStreamer::EmitDTPRel64Value(const MCExpr *Value) {
178 report_fatal_error("unsupported directive in streamer");
181 void MCStreamer::EmitDTPRel32Value(const MCExpr *Value) {
182 report_fatal_error("unsupported directive in streamer");
185 void MCStreamer::EmitTPRel64Value(const MCExpr *Value) {
186 report_fatal_error("unsupported directive in streamer");
189 void MCStreamer::EmitTPRel32Value(const MCExpr *Value) {
190 report_fatal_error("unsupported directive in streamer");
193 void MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
194 report_fatal_error("unsupported directive in streamer");
197 void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
198 report_fatal_error("unsupported directive in streamer");
201 /// Emit NumBytes bytes worth of the value specified by FillValue.
202 /// This implements directives such as '.space'.
203 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
204 emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
207 /// The implementation in this class just redirects to emitFill.
208 void MCStreamer::EmitZeros(uint64_t NumBytes) {
209 emitFill(NumBytes, 0);
212 Expected<unsigned>
213 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
214 StringRef Filename,
215 Optional<MD5::MD5Result> Checksum,
216 Optional<StringRef> Source,
217 unsigned CUID) {
218 return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
219 Source, CUID);
222 void MCStreamer::emitDwarfFile0Directive(StringRef Directory,
223 StringRef Filename,
224 Optional<MD5::MD5Result> Checksum,
225 Optional<StringRef> Source,
226 unsigned CUID) {
227 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
228 Source);
231 void MCStreamer::EmitCFIBKeyFrame() {
232 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
233 if (!CurFrame)
234 return;
235 CurFrame->IsBKeyFrame = true;
238 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
239 unsigned Column, unsigned Flags,
240 unsigned Isa,
241 unsigned Discriminator,
242 StringRef FileName) {
243 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
244 Discriminator);
247 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
248 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
249 if (!Table.getLabel()) {
250 StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
251 Table.setLabel(
252 Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
254 return Table.getLabel();
257 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
258 return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
261 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
262 if (!hasUnfinishedDwarfFrameInfo()) {
263 getContext().reportError(SMLoc(), "this directive must appear between "
264 ".cfi_startproc and .cfi_endproc "
265 "directives");
266 return nullptr;
268 return &DwarfFrameInfos.back();
271 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
272 ArrayRef<uint8_t> Checksum,
273 unsigned ChecksumKind) {
274 return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
275 ChecksumKind);
278 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {
279 return getContext().getCVContext().recordFunctionId(FunctionId);
282 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId,
283 unsigned IAFunc, unsigned IAFile,
284 unsigned IALine, unsigned IACol,
285 SMLoc Loc) {
286 if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
287 getContext().reportError(Loc, "parent function id not introduced by "
288 ".cv_func_id or .cv_inline_site_id");
289 return true;
292 return getContext().getCVContext().recordInlinedCallSiteId(
293 FunctionId, IAFunc, IAFile, IALine, IACol);
296 void MCStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
297 unsigned Line, unsigned Column,
298 bool PrologueEnd, bool IsStmt,
299 StringRef FileName, SMLoc Loc) {}
301 bool MCStreamer::checkCVLocSection(unsigned FuncId, unsigned FileNo,
302 SMLoc Loc) {
303 CodeViewContext &CVC = getContext().getCVContext();
304 MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FuncId);
305 if (!FI) {
306 getContext().reportError(
307 Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
308 return false;
311 // Track the section
312 if (FI->Section == nullptr)
313 FI->Section = getCurrentSectionOnly();
314 else if (FI->Section != getCurrentSectionOnly()) {
315 getContext().reportError(
316 Loc,
317 "all .cv_loc directives for a function must be in the same section");
318 return false;
320 return true;
323 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId,
324 const MCSymbol *Begin,
325 const MCSymbol *End) {}
327 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
328 unsigned SourceFileId,
329 unsigned SourceLineNum,
330 const MCSymbol *FnStartSym,
331 const MCSymbol *FnEndSym) {}
333 /// Only call this on endian-specific types like ulittle16_t and little32_t, or
334 /// structs composed of them.
335 template <typename T>
336 static void copyBytesForDefRange(SmallString<20> &BytePrefix,
337 codeview::SymbolKind SymKind,
338 const T &DefRangeHeader) {
339 BytePrefix.resize(2 + sizeof(T));
340 codeview::ulittle16_t SymKindLE = codeview::ulittle16_t(SymKind);
341 memcpy(&BytePrefix[0], &SymKindLE, 2);
342 memcpy(&BytePrefix[2], &DefRangeHeader, sizeof(T));
345 void MCStreamer::EmitCVDefRangeDirective(
346 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
347 StringRef FixedSizePortion) {}
349 void MCStreamer::EmitCVDefRangeDirective(
350 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
351 codeview::DefRangeRegisterRelHeader DRHdr) {
352 SmallString<20> BytePrefix;
353 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER_REL, DRHdr);
354 EmitCVDefRangeDirective(Ranges, BytePrefix);
357 void MCStreamer::EmitCVDefRangeDirective(
358 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
359 codeview::DefRangeSubfieldRegisterHeader DRHdr) {
360 SmallString<20> BytePrefix;
361 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_SUBFIELD_REGISTER,
362 DRHdr);
363 EmitCVDefRangeDirective(Ranges, BytePrefix);
366 void MCStreamer::EmitCVDefRangeDirective(
367 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
368 codeview::DefRangeRegisterHeader DRHdr) {
369 SmallString<20> BytePrefix;
370 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER, DRHdr);
371 EmitCVDefRangeDirective(Ranges, BytePrefix);
374 void MCStreamer::EmitCVDefRangeDirective(
375 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
376 codeview::DefRangeFramePointerRelHeader DRHdr) {
377 SmallString<20> BytePrefix;
378 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_FRAMEPOINTER_REL,
379 DRHdr);
380 EmitCVDefRangeDirective(Ranges, BytePrefix);
383 void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
384 MCSymbol *EHSymbol) {
387 void MCStreamer::InitSections(bool NoExecStack) {
388 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
391 void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
392 assert(Fragment);
393 Symbol->setFragment(Fragment);
395 // As we emit symbols into a section, track the order so that they can
396 // be sorted upon later. Zero is reserved to mean 'unemitted'.
397 SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
400 void MCStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
401 Symbol->redefineIfPossible();
403 if (!Symbol->isUndefined() || Symbol->isVariable())
404 return getContext().reportError(Loc, "invalid symbol redefinition");
406 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
407 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
408 assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
409 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
411 Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
413 MCTargetStreamer *TS = getTargetStreamer();
414 if (TS)
415 TS->emitLabel(Symbol);
418 void MCStreamer::EmitCFISections(bool EH, bool Debug) {
419 assert(EH || Debug);
422 void MCStreamer::EmitCFIStartProc(bool IsSimple, SMLoc Loc) {
423 if (hasUnfinishedDwarfFrameInfo())
424 return getContext().reportError(
425 Loc, "starting new .cfi frame before finishing the previous one");
427 MCDwarfFrameInfo Frame;
428 Frame.IsSimple = IsSimple;
429 EmitCFIStartProcImpl(Frame);
431 const MCAsmInfo* MAI = Context.getAsmInfo();
432 if (MAI) {
433 for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
434 if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
435 Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
436 Frame.CurrentCfaRegister = Inst.getRegister();
441 DwarfFrameInfos.push_back(Frame);
444 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
447 void MCStreamer::EmitCFIEndProc() {
448 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
449 if (!CurFrame)
450 return;
451 EmitCFIEndProcImpl(*CurFrame);
454 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
455 // Put a dummy non-null value in Frame.End to mark that this frame has been
456 // closed.
457 Frame.End = (MCSymbol *)1;
460 MCSymbol *MCStreamer::EmitCFILabel() {
461 // Return a dummy non-null value so that label fields appear filled in when
462 // generating textual assembly.
463 return (MCSymbol *)1;
466 void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
467 MCSymbol *Label = EmitCFILabel();
468 MCCFIInstruction Instruction =
469 MCCFIInstruction::createDefCfa(Label, Register, Offset);
470 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
471 if (!CurFrame)
472 return;
473 CurFrame->Instructions.push_back(Instruction);
474 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
477 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
478 MCSymbol *Label = EmitCFILabel();
479 MCCFIInstruction Instruction =
480 MCCFIInstruction::createDefCfaOffset(Label, Offset);
481 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
482 if (!CurFrame)
483 return;
484 CurFrame->Instructions.push_back(Instruction);
487 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
488 MCSymbol *Label = EmitCFILabel();
489 MCCFIInstruction Instruction =
490 MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
491 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
492 if (!CurFrame)
493 return;
494 CurFrame->Instructions.push_back(Instruction);
497 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
498 MCSymbol *Label = EmitCFILabel();
499 MCCFIInstruction Instruction =
500 MCCFIInstruction::createDefCfaRegister(Label, Register);
501 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
502 if (!CurFrame)
503 return;
504 CurFrame->Instructions.push_back(Instruction);
505 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
508 void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
509 MCSymbol *Label = EmitCFILabel();
510 MCCFIInstruction Instruction =
511 MCCFIInstruction::createOffset(Label, Register, Offset);
512 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
513 if (!CurFrame)
514 return;
515 CurFrame->Instructions.push_back(Instruction);
518 void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
519 MCSymbol *Label = EmitCFILabel();
520 MCCFIInstruction Instruction =
521 MCCFIInstruction::createRelOffset(Label, Register, Offset);
522 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
523 if (!CurFrame)
524 return;
525 CurFrame->Instructions.push_back(Instruction);
528 void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
529 unsigned Encoding) {
530 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
531 if (!CurFrame)
532 return;
533 CurFrame->Personality = Sym;
534 CurFrame->PersonalityEncoding = Encoding;
537 void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
538 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
539 if (!CurFrame)
540 return;
541 CurFrame->Lsda = Sym;
542 CurFrame->LsdaEncoding = Encoding;
545 void MCStreamer::EmitCFIRememberState() {
546 MCSymbol *Label = EmitCFILabel();
547 MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
548 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
549 if (!CurFrame)
550 return;
551 CurFrame->Instructions.push_back(Instruction);
554 void MCStreamer::EmitCFIRestoreState() {
555 // FIXME: Error if there is no matching cfi_remember_state.
556 MCSymbol *Label = EmitCFILabel();
557 MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
558 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
559 if (!CurFrame)
560 return;
561 CurFrame->Instructions.push_back(Instruction);
564 void MCStreamer::EmitCFISameValue(int64_t Register) {
565 MCSymbol *Label = EmitCFILabel();
566 MCCFIInstruction Instruction =
567 MCCFIInstruction::createSameValue(Label, Register);
568 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
569 if (!CurFrame)
570 return;
571 CurFrame->Instructions.push_back(Instruction);
574 void MCStreamer::EmitCFIRestore(int64_t Register) {
575 MCSymbol *Label = EmitCFILabel();
576 MCCFIInstruction Instruction =
577 MCCFIInstruction::createRestore(Label, Register);
578 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
579 if (!CurFrame)
580 return;
581 CurFrame->Instructions.push_back(Instruction);
584 void MCStreamer::EmitCFIEscape(StringRef Values) {
585 MCSymbol *Label = EmitCFILabel();
586 MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
587 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
588 if (!CurFrame)
589 return;
590 CurFrame->Instructions.push_back(Instruction);
593 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
594 MCSymbol *Label = EmitCFILabel();
595 MCCFIInstruction Instruction =
596 MCCFIInstruction::createGnuArgsSize(Label, Size);
597 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
598 if (!CurFrame)
599 return;
600 CurFrame->Instructions.push_back(Instruction);
603 void MCStreamer::EmitCFISignalFrame() {
604 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
605 if (!CurFrame)
606 return;
607 CurFrame->IsSignalFrame = true;
610 void MCStreamer::EmitCFIUndefined(int64_t Register) {
611 MCSymbol *Label = EmitCFILabel();
612 MCCFIInstruction Instruction =
613 MCCFIInstruction::createUndefined(Label, Register);
614 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
615 if (!CurFrame)
616 return;
617 CurFrame->Instructions.push_back(Instruction);
620 void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
621 MCSymbol *Label = EmitCFILabel();
622 MCCFIInstruction Instruction =
623 MCCFIInstruction::createRegister(Label, Register1, Register2);
624 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
625 if (!CurFrame)
626 return;
627 CurFrame->Instructions.push_back(Instruction);
630 void MCStreamer::EmitCFIWindowSave() {
631 MCSymbol *Label = EmitCFILabel();
632 MCCFIInstruction Instruction =
633 MCCFIInstruction::createWindowSave(Label);
634 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
635 if (!CurFrame)
636 return;
637 CurFrame->Instructions.push_back(Instruction);
640 void MCStreamer::EmitCFINegateRAState() {
641 MCSymbol *Label = EmitCFILabel();
642 MCCFIInstruction Instruction = MCCFIInstruction::createNegateRAState(Label);
643 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
644 if (!CurFrame)
645 return;
646 CurFrame->Instructions.push_back(Instruction);
649 void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
650 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
651 if (!CurFrame)
652 return;
653 CurFrame->RAReg = Register;
656 WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
657 const MCAsmInfo *MAI = Context.getAsmInfo();
658 if (!MAI->usesWindowsCFI()) {
659 getContext().reportError(
660 Loc, ".seh_* directives are not supported on this target");
661 return nullptr;
663 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
664 getContext().reportError(
665 Loc, ".seh_ directive must appear within an active frame");
666 return nullptr;
668 return CurrentWinFrameInfo;
671 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
672 const MCAsmInfo *MAI = Context.getAsmInfo();
673 if (!MAI->usesWindowsCFI())
674 return getContext().reportError(
675 Loc, ".seh_* directives are not supported on this target");
676 if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
677 getContext().reportError(
678 Loc, "Starting a function before ending the previous one!");
680 MCSymbol *StartProc = EmitCFILabel();
682 WinFrameInfos.emplace_back(
683 std::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
684 CurrentWinFrameInfo = WinFrameInfos.back().get();
685 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
688 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
689 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
690 if (!CurFrame)
691 return;
692 if (CurFrame->ChainedParent)
693 getContext().reportError(Loc, "Not all chained regions terminated!");
695 MCSymbol *Label = EmitCFILabel();
696 CurFrame->End = Label;
699 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
700 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
701 if (!CurFrame)
702 return;
703 if (CurFrame->ChainedParent)
704 getContext().reportError(Loc, "Not all chained regions terminated!");
706 MCSymbol *Label = EmitCFILabel();
707 CurFrame->FuncletOrFuncEnd = Label;
710 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) {
711 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
712 if (!CurFrame)
713 return;
715 MCSymbol *StartProc = EmitCFILabel();
717 WinFrameInfos.emplace_back(std::make_unique<WinEH::FrameInfo>(
718 CurFrame->Function, StartProc, CurFrame));
719 CurrentWinFrameInfo = WinFrameInfos.back().get();
720 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
723 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) {
724 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
725 if (!CurFrame)
726 return;
727 if (!CurFrame->ChainedParent)
728 return getContext().reportError(
729 Loc, "End of a chained region outside a chained region!");
731 MCSymbol *Label = EmitCFILabel();
733 CurFrame->End = Label;
734 CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
737 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
738 SMLoc Loc) {
739 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
740 if (!CurFrame)
741 return;
742 if (CurFrame->ChainedParent)
743 return getContext().reportError(
744 Loc, "Chained unwind areas can't have handlers!");
745 CurFrame->ExceptionHandler = Sym;
746 if (!Except && !Unwind)
747 getContext().reportError(Loc, "Don't know what kind of handler this is!");
748 if (Unwind)
749 CurFrame->HandlesUnwind = true;
750 if (Except)
751 CurFrame->HandlesExceptions = true;
754 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
755 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
756 if (!CurFrame)
757 return;
758 if (CurFrame->ChainedParent)
759 getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
762 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
763 const MCSymbolRefExpr *To, uint64_t Count) {
766 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
767 MCSection *MainCFISec,
768 const MCSection *TextSec) {
769 // If this is the main .text section, use the main unwind info section.
770 if (TextSec == Context.getObjectFileInfo()->getTextSection())
771 return MainCFISec;
773 const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
774 auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec);
775 unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
777 // If this section is COMDAT, this unwind section should be COMDAT associative
778 // with its group.
779 const MCSymbol *KeySym = nullptr;
780 if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
781 KeySym = TextSecCOFF->getCOMDATSymbol();
783 // In a GNU environment, we can't use associative comdats. Instead, do what
784 // GCC does, which is to make plain comdat selectany section named like
785 // ".[px]data$_Z3foov".
786 if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) {
787 std::string SectionName =
788 (MainCFISecCOFF->getSectionName() + "$" +
789 TextSecCOFF->getSectionName().split('$').second)
790 .str();
791 return Context.getCOFFSection(
792 SectionName,
793 MainCFISecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT,
794 MainCFISecCOFF->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY);
798 return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
801 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
802 return getWinCFISection(getContext(), &NextWinCFIID,
803 getContext().getObjectFileInfo()->getPDataSection(),
804 TextSec);
807 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
808 return getWinCFISection(getContext(), &NextWinCFIID,
809 getContext().getObjectFileInfo()->getXDataSection(),
810 TextSec);
813 void MCStreamer::EmitSyntaxDirective() {}
815 static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) {
816 return Ctx.getRegisterInfo()->getSEHRegNum(Reg);
819 void MCStreamer::EmitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
820 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
821 if (!CurFrame)
822 return;
824 MCSymbol *Label = EmitCFILabel();
826 WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(
827 Label, encodeSEHRegNum(Context, Register));
828 CurFrame->Instructions.push_back(Inst);
831 void MCStreamer::EmitWinCFISetFrame(MCRegister Register, unsigned Offset,
832 SMLoc Loc) {
833 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
834 if (!CurFrame)
835 return;
836 if (CurFrame->LastFrameInst >= 0)
837 return getContext().reportError(
838 Loc, "frame register and offset can be set at most once");
839 if (Offset & 0x0F)
840 return getContext().reportError(Loc, "offset is not a multiple of 16");
841 if (Offset > 240)
842 return getContext().reportError(
843 Loc, "frame offset must be less than or equal to 240");
845 MCSymbol *Label = EmitCFILabel();
847 WinEH::Instruction Inst = Win64EH::Instruction::SetFPReg(
848 Label, encodeSEHRegNum(getContext(), Register), Offset);
849 CurFrame->LastFrameInst = CurFrame->Instructions.size();
850 CurFrame->Instructions.push_back(Inst);
853 void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
854 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
855 if (!CurFrame)
856 return;
857 if (Size == 0)
858 return getContext().reportError(Loc,
859 "stack allocation size must be non-zero");
860 if (Size & 7)
861 return getContext().reportError(
862 Loc, "stack allocation size is not a multiple of 8");
864 MCSymbol *Label = EmitCFILabel();
866 WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
867 CurFrame->Instructions.push_back(Inst);
870 void MCStreamer::EmitWinCFISaveReg(MCRegister Register, unsigned Offset,
871 SMLoc Loc) {
872 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
873 if (!CurFrame)
874 return;
876 if (Offset & 7)
877 return getContext().reportError(
878 Loc, "register save offset is not 8 byte aligned");
880 MCSymbol *Label = EmitCFILabel();
882 WinEH::Instruction Inst = Win64EH::Instruction::SaveNonVol(
883 Label, encodeSEHRegNum(Context, Register), Offset);
884 CurFrame->Instructions.push_back(Inst);
887 void MCStreamer::EmitWinCFISaveXMM(MCRegister Register, unsigned Offset,
888 SMLoc Loc) {
889 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
890 if (!CurFrame)
891 return;
892 if (Offset & 0x0F)
893 return getContext().reportError(Loc, "offset is not a multiple of 16");
895 MCSymbol *Label = EmitCFILabel();
897 WinEH::Instruction Inst = Win64EH::Instruction::SaveXMM(
898 Label, encodeSEHRegNum(Context, Register), Offset);
899 CurFrame->Instructions.push_back(Inst);
902 void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
903 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
904 if (!CurFrame)
905 return;
906 if (!CurFrame->Instructions.empty())
907 return getContext().reportError(
908 Loc, "If present, PushMachFrame must be the first UOP");
910 MCSymbol *Label = EmitCFILabel();
912 WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
913 CurFrame->Instructions.push_back(Inst);
916 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
917 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
918 if (!CurFrame)
919 return;
921 MCSymbol *Label = EmitCFILabel();
923 CurFrame->PrologEnd = Label;
926 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {}
928 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {}
930 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {}
932 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
934 void MCStreamer::EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
936 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
937 /// the specified string in the output .s file. This capability is
938 /// indicated by the hasRawTextSupport() predicate.
939 void MCStreamer::EmitRawTextImpl(StringRef String) {
940 // This is not llvm_unreachable for the sake of out of tree backend
941 // developers who may not have assembly streamers and should serve as a
942 // reminder to not accidentally call EmitRawText in the absence of such.
943 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
944 "it (target backend is likely missing an AsmStreamer "
945 "implementation)");
948 void MCStreamer::EmitRawText(const Twine &T) {
949 SmallString<128> Str;
950 EmitRawTextImpl(T.toStringRef(Str));
953 void MCStreamer::EmitWindowsUnwindTables() {
956 void MCStreamer::Finish() {
957 if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
958 (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
959 getContext().reportError(SMLoc(), "Unfinished frame!");
960 return;
963 MCTargetStreamer *TS = getTargetStreamer();
964 if (TS)
965 TS->finish();
967 FinishImpl();
970 void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
971 visitUsedExpr(*Value);
972 Symbol->setVariableValue(Value);
974 MCTargetStreamer *TS = getTargetStreamer();
975 if (TS)
976 TS->emitAssignment(Symbol, Value);
979 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter,
980 raw_ostream &OS, const MCInst &Inst,
981 const MCSubtargetInfo &STI) {
982 InstPrinter.printInst(&Inst, OS, "", STI);
985 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
988 void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
989 switch (Expr.getKind()) {
990 case MCExpr::Target:
991 cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
992 break;
994 case MCExpr::Constant:
995 break;
997 case MCExpr::Binary: {
998 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
999 visitUsedExpr(*BE.getLHS());
1000 visitUsedExpr(*BE.getRHS());
1001 break;
1004 case MCExpr::SymbolRef:
1005 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
1006 break;
1008 case MCExpr::Unary:
1009 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
1010 break;
1014 void MCStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
1015 // Scan for values.
1016 for (unsigned i = Inst.getNumOperands(); i--;)
1017 if (Inst.getOperand(i).isExpr())
1018 visitUsedExpr(*Inst.getOperand(i).getExpr());
1021 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
1022 unsigned Size) {
1023 // Get the Hi-Lo expression.
1024 const MCExpr *Diff =
1025 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1026 MCSymbolRefExpr::create(Lo, Context), Context);
1028 const MCAsmInfo *MAI = Context.getAsmInfo();
1029 if (!MAI->doesSetDirectiveSuppressReloc()) {
1030 EmitValue(Diff, Size);
1031 return;
1034 // Otherwise, emit with .set (aka assignment).
1035 MCSymbol *SetLabel = Context.createTempSymbol("set", true);
1036 EmitAssignment(SetLabel, Diff);
1037 EmitSymbolValue(SetLabel, Size);
1040 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
1041 const MCSymbol *Lo) {
1042 // Get the Hi-Lo expression.
1043 const MCExpr *Diff =
1044 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1045 MCSymbolRefExpr::create(Lo, Context), Context);
1047 EmitULEB128Value(Diff);
1050 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {}
1051 void MCStreamer::EmitThumbFunc(MCSymbol *Func) {}
1052 void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
1053 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
1054 llvm_unreachable("this directive only supported on COFF targets");
1056 void MCStreamer::EndCOFFSymbolDef() {
1057 llvm_unreachable("this directive only supported on COFF targets");
1059 void MCStreamer::EmitFileDirective(StringRef Filename) {}
1060 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
1061 llvm_unreachable("this directive only supported on COFF targets");
1063 void MCStreamer::EmitCOFFSymbolType(int Type) {
1064 llvm_unreachable("this directive only supported on COFF targets");
1066 void MCStreamer::EmitXCOFFLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1067 unsigned ByteAlign) {
1068 llvm_unreachable("this directive only supported on XCOFF targets");
1070 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
1071 void MCStreamer::emitELFSymverDirective(StringRef AliasName,
1072 const MCSymbol *Aliasee) {}
1073 void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1074 unsigned ByteAlignment) {}
1075 void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1076 uint64_t Size, unsigned ByteAlignment) {}
1077 void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {}
1078 void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
1079 void MCStreamer::EmitBytes(StringRef Data) {}
1080 void MCStreamer::EmitBinaryData(StringRef Data) { EmitBytes(Data); }
1081 void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
1082 visitUsedExpr(*Value);
1084 void MCStreamer::EmitULEB128Value(const MCExpr *Value) {}
1085 void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {}
1086 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
1087 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
1088 SMLoc Loc) {}
1089 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
1090 unsigned ValueSize,
1091 unsigned MaxBytesToEmit) {}
1092 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment,
1093 unsigned MaxBytesToEmit) {}
1094 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
1095 SMLoc Loc) {}
1096 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {}
1097 void MCStreamer::EmitBundleLock(bool AlignToEnd) {}
1098 void MCStreamer::FinishImpl() {}
1099 void MCStreamer::EmitBundleUnlock() {}
1101 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) {
1102 assert(Section && "Cannot switch to a null section!");
1103 MCSectionSubPair curSection = SectionStack.back().first;
1104 SectionStack.back().second = curSection;
1105 if (MCSectionSubPair(Section, Subsection) != curSection) {
1106 ChangeSection(Section, Subsection);
1107 SectionStack.back().first = MCSectionSubPair(Section, Subsection);
1108 assert(!Section->hasEnded() && "Section already ended");
1109 MCSymbol *Sym = Section->getBeginSymbol();
1110 if (Sym && !Sym->isInSection())
1111 EmitLabel(Sym);
1115 MCSymbol *MCStreamer::endSection(MCSection *Section) {
1116 // TODO: keep track of the last subsection so that this symbol appears in the
1117 // correct place.
1118 MCSymbol *Sym = Section->getEndSymbol(Context);
1119 if (Sym->isInSection())
1120 return Sym;
1122 SwitchSection(Section);
1123 EmitLabel(Sym);
1124 return Sym;
1127 void MCStreamer::EmitVersionForTarget(const Triple &Target,
1128 const VersionTuple &SDKVersion) {
1129 if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
1130 return;
1131 // Do we even know the version?
1132 if (Target.getOSMajorVersion() == 0)
1133 return;
1135 unsigned Major;
1136 unsigned Minor;
1137 unsigned Update;
1138 if (Target.isMacCatalystEnvironment()) {
1139 // Mac Catalyst always uses the build version load command.
1140 Target.getiOSVersion(Major, Minor, Update);
1141 assert(Major && "A non-zero major version is expected");
1142 EmitBuildVersion(MachO::PLATFORM_MACCATALYST, Major, Minor, Update,
1143 SDKVersion);
1144 return;
1147 MCVersionMinType VersionType;
1148 if (Target.isWatchOS()) {
1149 VersionType = MCVM_WatchOSVersionMin;
1150 Target.getWatchOSVersion(Major, Minor, Update);
1151 } else if (Target.isTvOS()) {
1152 VersionType = MCVM_TvOSVersionMin;
1153 Target.getiOSVersion(Major, Minor, Update);
1154 } else if (Target.isMacOSX()) {
1155 VersionType = MCVM_OSXVersionMin;
1156 if (!Target.getMacOSXVersion(Major, Minor, Update))
1157 Major = 0;
1158 } else {
1159 VersionType = MCVM_IOSVersionMin;
1160 Target.getiOSVersion(Major, Minor, Update);
1162 if (Major != 0)
1163 EmitVersionMin(VersionType, Major, Minor, Update, SDKVersion);