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