LLVM 20.0.0git
COFFAsmParser.cpp
Go to the documentation of this file.
1//===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===//
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"
13#include "llvm/MC/MCContext.h"
18#include "llvm/MC/MCStreamer.h"
19#include "llvm/Support/SMLoc.h"
21#include <cassert>
22#include <cstdint>
23#include <limits>
24#include <utility>
25
26using namespace llvm;
27
28namespace {
29
30class COFFAsmParser : public MCAsmParserExtension {
31 template<bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
32 void addDirectiveHandler(StringRef Directive) {
33 MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
34 this, HandleDirective<COFFAsmParser, HandlerMethod>);
36 }
37
38 bool parseSectionSwitch(StringRef Section, unsigned Characteristics);
39
40 bool parseSectionSwitch(StringRef Section, unsigned Characteristics,
41 StringRef COMDATSymName, COFF::COMDATType Type);
42
43 bool parseSectionName(StringRef &SectionName);
45 unsigned *Flags);
46
47 void Initialize(MCAsmParser &Parser) override {
48 // Call the base implementation.
50
51 addDirectiveHandler<&COFFAsmParser::parseSectionDirectiveText>(".text");
52 addDirectiveHandler<&COFFAsmParser::parseSectionDirectiveData>(".data");
53 addDirectiveHandler<&COFFAsmParser::parseSectionDirectiveBSS>(".bss");
54 addDirectiveHandler<&COFFAsmParser::parseDirectiveSection>(".section");
55 addDirectiveHandler<&COFFAsmParser::parseDirectivePushSection>(
56 ".pushsection");
57 addDirectiveHandler<&COFFAsmParser::parseDirectivePopSection>(
58 ".popsection");
59 addDirectiveHandler<&COFFAsmParser::parseDirectiveDef>(".def");
60 addDirectiveHandler<&COFFAsmParser::parseDirectiveScl>(".scl");
61 addDirectiveHandler<&COFFAsmParser::parseDirectiveType>(".type");
62 addDirectiveHandler<&COFFAsmParser::parseDirectiveEndef>(".endef");
63 addDirectiveHandler<&COFFAsmParser::parseDirectiveSecRel32>(".secrel32");
64 addDirectiveHandler<&COFFAsmParser::parseDirectiveSymIdx>(".symidx");
65 addDirectiveHandler<&COFFAsmParser::parseDirectiveSafeSEH>(".safeseh");
66 addDirectiveHandler<&COFFAsmParser::parseDirectiveSecIdx>(".secidx");
67 addDirectiveHandler<&COFFAsmParser::parseDirectiveLinkOnce>(".linkonce");
68 addDirectiveHandler<&COFFAsmParser::parseDirectiveRVA>(".rva");
69 addDirectiveHandler<&COFFAsmParser::parseDirectiveSymbolAttribute>(".weak");
70 addDirectiveHandler<&COFFAsmParser::parseDirectiveSymbolAttribute>(
71 ".weak_anti_dep");
72 addDirectiveHandler<&COFFAsmParser::parseDirectiveCGProfile>(".cg_profile");
73 addDirectiveHandler<&COFFAsmParser::parseDirectiveSecNum>(".secnum");
74 addDirectiveHandler<&COFFAsmParser::parseDirectiveSecOffset>(".secoffset");
75
76 // Win64 EH directives.
77 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveStartProc>(
78 ".seh_proc");
79 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndProc>(
80 ".seh_endproc");
81 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndFuncletOrFunc>(
82 ".seh_endfunclet");
83 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveStartChained>(
84 ".seh_startchained");
85 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndChained>(
86 ".seh_endchained");
87 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveHandler>(
88 ".seh_handler");
89 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveHandlerData>(
90 ".seh_handlerdata");
91 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveAllocStack>(
92 ".seh_stackalloc");
93 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndProlog>(
94 ".seh_endprologue");
95 }
96
97 bool parseSectionDirectiveText(StringRef, SMLoc) {
98 return parseSectionSwitch(".text", COFF::IMAGE_SCN_CNT_CODE |
101 }
102
103 bool parseSectionDirectiveData(StringRef, SMLoc) {
104 return parseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
107 }
108
109 bool parseSectionDirectiveBSS(StringRef, SMLoc) {
110 return parseSectionSwitch(".bss", COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
113 }
114
115 bool parseDirectiveSection(StringRef, SMLoc);
116 bool parseSectionArguments(StringRef, SMLoc);
117 bool parseDirectivePushSection(StringRef, SMLoc);
118 bool parseDirectivePopSection(StringRef, SMLoc);
119 bool parseDirectiveDef(StringRef, SMLoc);
120 bool parseDirectiveScl(StringRef, SMLoc);
121 bool parseDirectiveType(StringRef, SMLoc);
122 bool parseDirectiveEndef(StringRef, SMLoc);
123 bool parseDirectiveSecRel32(StringRef, SMLoc);
124 bool parseDirectiveSecIdx(StringRef, SMLoc);
125 bool parseDirectiveSafeSEH(StringRef, SMLoc);
126 bool parseDirectiveSymIdx(StringRef, SMLoc);
127 bool parseCOMDATType(COFF::COMDATType &Type);
128 bool parseDirectiveLinkOnce(StringRef, SMLoc);
129 bool parseDirectiveRVA(StringRef, SMLoc);
131 bool parseDirectiveSecNum(StringRef, SMLoc);
132 bool parseDirectiveSecOffset(StringRef, SMLoc);
133
134 // Win64 EH directives.
135 bool parseSEHDirectiveStartProc(StringRef, SMLoc);
136 bool parseSEHDirectiveEndProc(StringRef, SMLoc);
137 bool parseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc);
138 bool parseSEHDirectiveStartChained(StringRef, SMLoc);
139 bool parseSEHDirectiveEndChained(StringRef, SMLoc);
140 bool parseSEHDirectiveHandler(StringRef, SMLoc);
141 bool parseSEHDirectiveHandlerData(StringRef, SMLoc);
142 bool parseSEHDirectiveAllocStack(StringRef, SMLoc);
143 bool parseSEHDirectiveEndProlog(StringRef, SMLoc);
144
145 bool parseAtUnwindOrAtExcept(bool &unwind, bool &except);
146 bool parseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
147
148public:
149 COFFAsmParser() = default;
150};
151
152} // end anonymous namespace.
153
154bool COFFAsmParser::parseSectionFlags(StringRef SectionName,
155 StringRef FlagsString, unsigned *Flags) {
156 enum {
157 None = 0,
158 Alloc = 1 << 0,
159 Code = 1 << 1,
160 Load = 1 << 2,
161 InitData = 1 << 3,
162 Shared = 1 << 4,
163 NoLoad = 1 << 5,
164 NoRead = 1 << 6,
165 NoWrite = 1 << 7,
166 Discardable = 1 << 8,
167 Info = 1 << 9,
168 };
169
170 bool ReadOnlyRemoved = false;
171 unsigned SecFlags = None;
172
173 for (char FlagChar : FlagsString) {
174 switch (FlagChar) {
175 case 'a':
176 // Ignored.
177 break;
178
179 case 'b': // bss section
180 SecFlags |= Alloc;
181 if (SecFlags & InitData)
182 return TokError("conflicting section flags 'b' and 'd'.");
183 SecFlags &= ~Load;
184 break;
185
186 case 'd': // data section
187 SecFlags |= InitData;
188 if (SecFlags & Alloc)
189 return TokError("conflicting section flags 'b' and 'd'.");
190 SecFlags &= ~NoWrite;
191 if ((SecFlags & NoLoad) == 0)
192 SecFlags |= Load;
193 break;
194
195 case 'n': // section is not loaded
196 SecFlags |= NoLoad;
197 SecFlags &= ~Load;
198 break;
199
200 case 'D': // discardable
201 SecFlags |= Discardable;
202 break;
203
204 case 'r': // read-only
205 ReadOnlyRemoved = false;
206 SecFlags |= NoWrite;
207 if ((SecFlags & Code) == 0)
208 SecFlags |= InitData;
209 if ((SecFlags & NoLoad) == 0)
210 SecFlags |= Load;
211 break;
212
213 case 's': // shared section
214 SecFlags |= Shared | InitData;
215 SecFlags &= ~NoWrite;
216 if ((SecFlags & NoLoad) == 0)
217 SecFlags |= Load;
218 break;
219
220 case 'w': // writable
221 SecFlags &= ~NoWrite;
222 ReadOnlyRemoved = true;
223 break;
224
225 case 'x': // executable section
226 SecFlags |= Code;
227 if ((SecFlags & NoLoad) == 0)
228 SecFlags |= Load;
229 if (!ReadOnlyRemoved)
230 SecFlags |= NoWrite;
231 break;
232
233 case 'y': // not readable
234 SecFlags |= NoRead | NoWrite;
235 break;
236
237 case 'i': // info
238 SecFlags |= Info;
239 break;
240
241 default:
242 return TokError("unknown flag");
243 }
244 }
245
246 *Flags = 0;
247
248 if (SecFlags == None)
249 SecFlags = InitData;
250
251 if (SecFlags & Code)
253 if (SecFlags & InitData)
255 if ((SecFlags & Alloc) && (SecFlags & Load) == 0)
257 if (SecFlags & NoLoad)
259 if ((SecFlags & Discardable) ||
262 if ((SecFlags & NoRead) == 0)
264 if ((SecFlags & NoWrite) == 0)
266 if (SecFlags & Shared)
268 if (SecFlags & Info)
270
271 return false;
272}
273
274/// ParseDirectiveSymbolAttribute
275/// ::= { ".weak", ... } [ identifier ( , identifier )* ]
276bool COFFAsmParser::parseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
278 .Case(".weak", MCSA_Weak)
279 .Case(".weak_anti_dep", MCSA_WeakAntiDep)
281 assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
282 if (getLexer().isNot(AsmToken::EndOfStatement)) {
283 while (true) {
285
286 if (getParser().parseIdentifier(Name))
287 return TokError("expected identifier in directive");
288
289 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
290
291 getStreamer().emitSymbolAttribute(Sym, Attr);
292
293 if (getLexer().is(AsmToken::EndOfStatement))
294 break;
295
296 if (getLexer().isNot(AsmToken::Comma))
297 return TokError("unexpected token in directive");
298 Lex();
299 }
300 }
301
302 Lex();
303 return false;
304}
305
306bool COFFAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
308}
309
310bool COFFAsmParser::parseSectionSwitch(StringRef Section,
311 unsigned Characteristics) {
312 return parseSectionSwitch(Section, Characteristics, "", (COFF::COMDATType)0);
313}
314
315bool COFFAsmParser::parseSectionSwitch(StringRef Section,
316 unsigned Characteristics,
317 StringRef COMDATSymName,
319 if (getLexer().isNot(AsmToken::EndOfStatement))
320 return TokError("unexpected token in section switching directive");
321 Lex();
322
323 getStreamer().switchSection(getContext().getCOFFSection(
324 Section, Characteristics, COMDATSymName, Type));
325
326 return false;
327}
328
329bool COFFAsmParser::parseSectionName(StringRef &SectionName) {
330 if (!getLexer().is(AsmToken::Identifier) && !getLexer().is(AsmToken::String))
331 return true;
332
333 SectionName = getTok().getIdentifier();
334 Lex();
335 return false;
336}
337
338bool COFFAsmParser::parseDirectiveSection(StringRef directive, SMLoc loc) {
339 return parseSectionArguments(directive, loc);
340}
341
342// .section name [, "flags"] [, identifier [ identifier ], identifier]
343// .pushsection <same as above>
344//
345// Supported flags:
346// a: Ignored.
347// b: BSS section (uninitialized data)
348// d: data section (initialized data)
349// n: "noload" section (removed by linker)
350// D: Discardable section
351// r: Readable section
352// s: Shared section
353// w: Writable section
354// x: Executable section
355// y: Not-readable section (clears 'r')
356//
357// Subsections are not supported.
358bool COFFAsmParser::parseSectionArguments(StringRef, SMLoc) {
360
361 if (parseSectionName(SectionName))
362 return TokError("expected identifier in directive");
363
367
368 if (getLexer().is(AsmToken::Comma)) {
369 Lex();
370
371 if (getLexer().isNot(AsmToken::String))
372 return TokError("expected string in directive");
373
374 StringRef FlagsStr = getTok().getStringContents();
375 Lex();
376
377 if (parseSectionFlags(SectionName, FlagsStr, &Flags))
378 return true;
379 }
380
382 StringRef COMDATSymName;
383 if (getLexer().is(AsmToken::Comma)) {
385 Lex();
386
388
389 if (!getLexer().is(AsmToken::Identifier))
390 return TokError("expected comdat type such as 'discard' or 'largest' "
391 "after protection bits");
392
393 if (parseCOMDATType(Type))
394 return true;
395
396 if (getLexer().isNot(AsmToken::Comma))
397 return TokError("expected comma in directive");
398 Lex();
399
400 if (getParser().parseIdentifier(COMDATSymName))
401 return TokError("expected identifier in directive");
402 }
403
404 if (getLexer().isNot(AsmToken::EndOfStatement))
405 return TokError("unexpected token in directive");
406
407 if (Flags & COFF::IMAGE_SCN_CNT_CODE) {
408 const Triple &T = getContext().getTargetTriple();
409 if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
411 }
412 parseSectionSwitch(SectionName, Flags, COMDATSymName, Type);
413 return false;
414}
415
416bool COFFAsmParser::parseDirectivePushSection(StringRef directive, SMLoc loc) {
417 getStreamer().pushSection();
418
419 if (parseSectionArguments(directive, loc)) {
420 getStreamer().popSection();
421 return true;
422 }
423
424 return false;
425}
426
427bool COFFAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
428 if (!getStreamer().popSection())
429 return TokError(".popsection without corresponding .pushsection");
430 return false;
431}
432
433bool COFFAsmParser::parseDirectiveDef(StringRef, SMLoc) {
435
436 if (getParser().parseIdentifier(SymbolName))
437 return TokError("expected identifier in directive");
438
439 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
440
441 getStreamer().beginCOFFSymbolDef(Sym);
442
443 Lex();
444 return false;
445}
446
447bool COFFAsmParser::parseDirectiveScl(StringRef, SMLoc) {
448 int64_t SymbolStorageClass;
449 if (getParser().parseAbsoluteExpression(SymbolStorageClass))
450 return true;
451
452 if (getLexer().isNot(AsmToken::EndOfStatement))
453 return TokError("unexpected token in directive");
454
455 Lex();
456 getStreamer().emitCOFFSymbolStorageClass(SymbolStorageClass);
457 return false;
458}
459
460bool COFFAsmParser::parseDirectiveType(StringRef, SMLoc) {
461 int64_t Type;
462 if (getParser().parseAbsoluteExpression(Type))
463 return true;
464
465 if (getLexer().isNot(AsmToken::EndOfStatement))
466 return TokError("unexpected token in directive");
467
468 Lex();
469 getStreamer().emitCOFFSymbolType(Type);
470 return false;
471}
472
473bool COFFAsmParser::parseDirectiveEndef(StringRef, SMLoc) {
474 Lex();
475 getStreamer().endCOFFSymbolDef();
476 return false;
477}
478
479bool COFFAsmParser::parseDirectiveSecRel32(StringRef, SMLoc) {
480 StringRef SymbolID;
481 if (getParser().parseIdentifier(SymbolID))
482 return TokError("expected identifier in directive");
483
484 int64_t Offset = 0;
485 SMLoc OffsetLoc;
486 if (getLexer().is(AsmToken::Plus)) {
487 OffsetLoc = getLexer().getLoc();
488 if (getParser().parseAbsoluteExpression(Offset))
489 return true;
490 }
491
492 if (getLexer().isNot(AsmToken::EndOfStatement))
493 return TokError("unexpected token in directive");
494
495 if (Offset < 0 || Offset > std::numeric_limits<uint32_t>::max())
496 return Error(
497 OffsetLoc,
498 "invalid '.secrel32' directive offset, can't be less "
499 "than zero or greater than std::numeric_limits<uint32_t>::max()");
500
501 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
502
503 Lex();
504 getStreamer().emitCOFFSecRel32(Symbol, Offset);
505 return false;
506}
507
508bool COFFAsmParser::parseDirectiveRVA(StringRef, SMLoc) {
509 auto parseOp = [&]() -> bool {
510 StringRef SymbolID;
511 if (getParser().parseIdentifier(SymbolID))
512 return TokError("expected identifier in directive");
513
514 int64_t Offset = 0;
515 SMLoc OffsetLoc;
516 if (getLexer().is(AsmToken::Plus) || getLexer().is(AsmToken::Minus)) {
517 OffsetLoc = getLexer().getLoc();
518 if (getParser().parseAbsoluteExpression(Offset))
519 return true;
520 }
521
522 if (Offset < std::numeric_limits<int32_t>::min() ||
523 Offset > std::numeric_limits<int32_t>::max())
524 return Error(OffsetLoc, "invalid '.rva' directive offset, can't be less "
525 "than -2147483648 or greater than "
526 "2147483647");
527
528 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
529
530 getStreamer().emitCOFFImgRel32(Symbol, Offset);
531 return false;
532 };
533
534 if (getParser().parseMany(parseOp))
535 return addErrorSuffix(" in directive");
536 return false;
537}
538
539bool COFFAsmParser::parseDirectiveSafeSEH(StringRef, SMLoc) {
540 StringRef SymbolID;
541 if (getParser().parseIdentifier(SymbolID))
542 return TokError("expected identifier in directive");
543
544 if (getLexer().isNot(AsmToken::EndOfStatement))
545 return TokError("unexpected token in directive");
546
547 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
548
549 Lex();
550 getStreamer().emitCOFFSafeSEH(Symbol);
551 return false;
552}
553
554bool COFFAsmParser::parseDirectiveSecIdx(StringRef, SMLoc) {
555 StringRef SymbolID;
556 if (getParser().parseIdentifier(SymbolID))
557 return TokError("expected identifier in directive");
558
559 if (getLexer().isNot(AsmToken::EndOfStatement))
560 return TokError("unexpected token in directive");
561
562 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
563
564 Lex();
565 getStreamer().emitCOFFSectionIndex(Symbol);
566 return false;
567}
568
569bool COFFAsmParser::parseDirectiveSymIdx(StringRef, SMLoc) {
570 StringRef SymbolID;
571 if (getParser().parseIdentifier(SymbolID))
572 return TokError("expected identifier in directive");
573
574 if (getLexer().isNot(AsmToken::EndOfStatement))
575 return TokError("unexpected token in directive");
576
577 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
578
579 Lex();
580 getStreamer().emitCOFFSymbolIndex(Symbol);
581 return false;
582}
583
584bool COFFAsmParser::parseDirectiveSecNum(StringRef, SMLoc) {
585 StringRef SymbolID;
586 if (getParser().parseIdentifier(SymbolID))
587 return TokError("expected identifier in directive");
588
589 if (getLexer().isNot(AsmToken::EndOfStatement))
590 return TokError("unexpected token in directive");
591
592 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
593
594 Lex();
595 getStreamer().emitCOFFSecNumber(Symbol);
596 return false;
597}
598
599bool COFFAsmParser::parseDirectiveSecOffset(StringRef, SMLoc) {
600 StringRef SymbolID;
601 if (getParser().parseIdentifier(SymbolID))
602 return TokError("expected identifier in directive");
603
604 if (getLexer().isNot(AsmToken::EndOfStatement))
605 return TokError("unexpected token in directive");
606
607 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
608
609 Lex();
610 getStreamer().emitCOFFSecOffset(Symbol);
611 return false;
612}
613
614/// ::= [ identifier ]
615bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
616 StringRef TypeId = getTok().getIdentifier();
617
627
628 if (Type == 0)
629 return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'"));
630
631 Lex();
632
633 return false;
634}
635
636/// ParseDirectiveLinkOnce
637/// ::= .linkonce [ identifier ]
638bool COFFAsmParser::parseDirectiveLinkOnce(StringRef, SMLoc Loc) {
640 if (getLexer().is(AsmToken::Identifier))
641 if (parseCOMDATType(Type))
642 return true;
643
644 const MCSectionCOFF *Current =
645 static_cast<const MCSectionCOFF *>(getStreamer().getCurrentSectionOnly());
646
648 return Error(Loc, "cannot make section associative with .linkonce");
649
651 return Error(Loc, Twine("section '") + Current->getName() +
652 "' is already linkonce");
653
654 Current->setSelection(Type);
655
656 if (getLexer().isNot(AsmToken::EndOfStatement))
657 return TokError("unexpected token in directive");
658
659 return false;
660}
661
662bool COFFAsmParser::parseSEHDirectiveStartProc(StringRef, SMLoc Loc) {
663 StringRef SymbolID;
664 if (getParser().parseIdentifier(SymbolID))
665 return true;
666
667 if (getLexer().isNot(AsmToken::EndOfStatement))
668 return TokError("unexpected token in directive");
669
670 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
671
672 Lex();
673 getStreamer().emitWinCFIStartProc(Symbol, Loc);
674 return false;
675}
676
677bool COFFAsmParser::parseSEHDirectiveEndProc(StringRef, SMLoc Loc) {
678 Lex();
679 getStreamer().emitWinCFIEndProc(Loc);
680 return false;
681}
682
683bool COFFAsmParser::parseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc Loc) {
684 Lex();
685 getStreamer().emitWinCFIFuncletOrFuncEnd(Loc);
686 return false;
687}
688
689bool COFFAsmParser::parseSEHDirectiveStartChained(StringRef, SMLoc Loc) {
690 Lex();
691 getStreamer().emitWinCFIStartChained(Loc);
692 return false;
693}
694
695bool COFFAsmParser::parseSEHDirectiveEndChained(StringRef, SMLoc Loc) {
696 Lex();
697 getStreamer().emitWinCFIEndChained(Loc);
698 return false;
699}
700
701bool COFFAsmParser::parseSEHDirectiveHandler(StringRef, SMLoc Loc) {
702 StringRef SymbolID;
703 if (getParser().parseIdentifier(SymbolID))
704 return true;
705
706 if (getLexer().isNot(AsmToken::Comma))
707 return TokError("you must specify one or both of @unwind or @except");
708 Lex();
709 bool unwind = false, except = false;
710 if (parseAtUnwindOrAtExcept(unwind, except))
711 return true;
712 if (getLexer().is(AsmToken::Comma)) {
713 Lex();
714 if (parseAtUnwindOrAtExcept(unwind, except))
715 return true;
716 }
717 if (getLexer().isNot(AsmToken::EndOfStatement))
718 return TokError("unexpected token in directive");
719
720 MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID);
721
722 Lex();
723 getStreamer().emitWinEHHandler(handler, unwind, except, Loc);
724 return false;
725}
726
727bool COFFAsmParser::parseSEHDirectiveHandlerData(StringRef, SMLoc Loc) {
728 Lex();
729 getStreamer().emitWinEHHandlerData();
730 return false;
731}
732
733bool COFFAsmParser::parseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
734 int64_t Size;
735 if (getParser().parseAbsoluteExpression(Size))
736 return true;
737
738 if (getLexer().isNot(AsmToken::EndOfStatement))
739 return TokError("unexpected token in directive");
740
741 Lex();
742 getStreamer().emitWinCFIAllocStack(Size, Loc);
743 return false;
744}
745
746bool COFFAsmParser::parseSEHDirectiveEndProlog(StringRef, SMLoc Loc) {
747 Lex();
748 getStreamer().emitWinCFIEndProlog(Loc);
749 return false;
750}
751
752bool COFFAsmParser::parseAtUnwindOrAtExcept(bool &unwind, bool &except) {
753 StringRef identifier;
754 if (getLexer().isNot(AsmToken::At) && getLexer().isNot(AsmToken::Percent))
755 return TokError("a handler attribute must begin with '@' or '%'");
756 SMLoc startLoc = getLexer().getLoc();
757 Lex();
758 if (getParser().parseIdentifier(identifier))
759 return Error(startLoc, "expected @unwind or @except");
760 if (identifier == "unwind")
761 unwind = true;
762 else if (identifier == "except")
763 except = true;
764 else
765 return Error(startLoc, "expected @unwind or @except");
766 return false;
767}
768
769namespace llvm {
770
772 return new COFFAsmParser;
773}
774
775} // end namespace llvm
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
COFFYAML::WeakExternalCharacteristics Characteristics
Definition: COFFYAML.cpp:350
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
static unsigned parseSectionFlags(const Triple &TT, StringRef flagsStr, bool *UseLastGroup)
std::string Name
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
bool parseDirectiveCGProfile(StringRef, SMLoc)
parseDirectiveCGProfile ::= .cg_profile identifier, identifier, <number>
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:123
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
Definition: MCAsmParser.h:127
virtual void addDirectiveHandler(StringRef Directive, ExtensionDirectiveHandler Handler)=0
This represents a section on Windows.
Definition: MCSectionCOFF.h:27
static bool isImplicitlyDiscardable(StringRef Name)
Definition: MCSectionCOFF.h:87
unsigned getCharacteristics() const
Definition: MCSectionCOFF.h:69
void setSelection(int Selection) const
StringRef getName() const
Definition: MCSection.h:130
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
Represents a location in source code.
Definition: SMLoc.h:23
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
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
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
@ IMAGE_SCN_MEM_SHARED
Definition: COFF.h:333
@ IMAGE_SCN_LNK_REMOVE
Definition: COFF.h:307
@ IMAGE_SCN_CNT_CODE
Definition: COFF.h:302
@ IMAGE_SCN_MEM_READ
Definition: COFF.h:335
@ IMAGE_SCN_MEM_EXECUTE
Definition: COFF.h:334
@ IMAGE_SCN_CNT_UNINITIALIZED_DATA
Definition: COFF.h:304
@ IMAGE_SCN_MEM_DISCARDABLE
Definition: COFF.h:330
@ IMAGE_SCN_LNK_INFO
Definition: COFF.h:306
@ IMAGE_SCN_MEM_16BIT
Definition: COFF.h:311
@ IMAGE_SCN_CNT_INITIALIZED_DATA
Definition: COFF.h:303
@ IMAGE_SCN_LNK_COMDAT
Definition: COFF.h:308
@ IMAGE_SCN_MEM_WRITE
Definition: COFF.h:336
SymbolStorageClass
Storage class tells where and what the symbol represents.
Definition: COFF.h:217
COMDATType
Definition: COFF.h:453
@ IMAGE_COMDAT_SELECT_NODUPLICATES
Definition: COFF.h:454
@ IMAGE_COMDAT_SELECT_LARGEST
Definition: COFF.h:459
@ IMAGE_COMDAT_SELECT_NEWEST
Definition: COFF.h:460
@ IMAGE_COMDAT_SELECT_SAME_SIZE
Definition: COFF.h:456
@ IMAGE_COMDAT_SELECT_ASSOCIATIVE
Definition: COFF.h:458
@ IMAGE_COMDAT_SELECT_EXACT_MATCH
Definition: COFF.h:457
@ IMAGE_COMDAT_SELECT_ANY
Definition: COFF.h:455
NodeAddr< CodeNode * > Code
Definition: RDFGraph.h:388
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
MCAsmParserExtension * createCOFFAsmParser()
@ None
Definition: CodeGenData.h:106
MCSymbolAttr
Definition: MCDirectives.h:18
@ MCSA_Weak
.weak
Definition: MCDirectives.h:45
@ MCSA_WeakAntiDep
.weak_anti_dep (COFF)
Definition: MCDirectives.h:49
@ MCSA_Invalid
Not a valid directive.
Definition: MCDirectives.h:19