LLVM  10.0.0svn
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 
9 #include "llvm/ADT/StringRef.h"
10 #include "llvm/ADT/StringSwitch.h"
11 #include "llvm/ADT/Triple.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/BinaryFormat/COFF.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCDirectives.h"
20 #include "llvm/MC/MCRegisterInfo.h"
21 #include "llvm/MC/MCSectionCOFF.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/SectionKind.h"
24 #include "llvm/Support/SMLoc.h"
25 #include <cassert>
26 #include <cstdint>
27 #include <limits>
28 #include <utility>
29 
30 using namespace llvm;
31 
32 namespace {
33 
34 class COFFAsmParser : public MCAsmParserExtension {
35  template<bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
36  void addDirectiveHandler(StringRef Directive) {
37  MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38  this, HandleDirective<COFFAsmParser, HandlerMethod>);
39  getParser().addDirectiveHandler(Directive, Handler);
40  }
41 
42  bool ParseSectionSwitch(StringRef Section,
43  unsigned Characteristics,
45 
46  bool ParseSectionSwitch(StringRef Section, unsigned Characteristics,
47  SectionKind Kind, StringRef COMDATSymName,
49 
50  bool ParseSectionName(StringRef &SectionName);
51  bool ParseSectionFlags(StringRef SectionName, StringRef FlagsString,
52  unsigned *Flags);
53 
54  void Initialize(MCAsmParser &Parser) override {
55  // Call the base implementation.
57 
58  addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
59  addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
60  addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
61  addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(".section");
62  addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
63  addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
64  addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
65  addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
66  addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
67  addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymIdx>(".symidx");
68  addDirectiveHandler<&COFFAsmParser::ParseDirectiveSafeSEH>(".safeseh");
69  addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx");
70  addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce");
71  addDirectiveHandler<&COFFAsmParser::ParseDirectiveRVA>(".rva");
72  addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
73 
74  // Win64 EH directives.
75  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
76  ".seh_proc");
77  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
78  ".seh_endproc");
79  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
80  ".seh_startchained");
81  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
82  ".seh_endchained");
83  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
84  ".seh_handler");
85  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
86  ".seh_handlerdata");
87  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
88  ".seh_stackalloc");
89  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
90  ".seh_endprologue");
91  }
92 
93  bool ParseSectionDirectiveText(StringRef, SMLoc) {
94  return ParseSectionSwitch(".text",
99  }
100 
101  bool ParseSectionDirectiveData(StringRef, SMLoc) {
102  return ParseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
106  }
107 
108  bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
109  return ParseSectionSwitch(".bss",
114  }
115 
116  bool ParseDirectiveSection(StringRef, SMLoc);
117  bool ParseDirectiveDef(StringRef, SMLoc);
118  bool ParseDirectiveScl(StringRef, SMLoc);
119  bool ParseDirectiveType(StringRef, SMLoc);
120  bool ParseDirectiveEndef(StringRef, SMLoc);
121  bool ParseDirectiveSecRel32(StringRef, SMLoc);
122  bool ParseDirectiveSecIdx(StringRef, SMLoc);
123  bool ParseDirectiveSafeSEH(StringRef, SMLoc);
124  bool ParseDirectiveSymIdx(StringRef, SMLoc);
125  bool parseCOMDATType(COFF::COMDATType &Type);
126  bool ParseDirectiveLinkOnce(StringRef, SMLoc);
127  bool ParseDirectiveRVA(StringRef, SMLoc);
128 
129  // Win64 EH directives.
130  bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
131  bool ParseSEHDirectiveEndProc(StringRef, SMLoc);
132  bool ParseSEHDirectiveStartChained(StringRef, SMLoc);
133  bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
134  bool ParseSEHDirectiveHandler(StringRef, SMLoc);
135  bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
136  bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
137  bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
138 
139  bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
140  bool ParseSEHRegisterNumber(unsigned &RegNo);
141  bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
142 
143 public:
144  COFFAsmParser() = default;
145 };
146 
147 } // end annonomous namespace.
148 
149 static SectionKind computeSectionKind(unsigned Flags) {
150  if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
151  return SectionKind::getText();
152  if (Flags & COFF::IMAGE_SCN_MEM_READ &&
153  (Flags & COFF::IMAGE_SCN_MEM_WRITE) == 0)
154  return SectionKind::getReadOnly();
155  return SectionKind::getData();
156 }
157 
158 bool COFFAsmParser::ParseSectionFlags(StringRef SectionName,
159  StringRef FlagsString, unsigned *Flags) {
160  enum {
161  None = 0,
162  Alloc = 1 << 0,
163  Code = 1 << 1,
164  Load = 1 << 2,
165  InitData = 1 << 3,
166  Shared = 1 << 4,
167  NoLoad = 1 << 5,
168  NoRead = 1 << 6,
169  NoWrite = 1 << 7,
170  Discardable = 1 << 8,
171  };
172 
173  bool ReadOnlyRemoved = false;
174  unsigned SecFlags = None;
175 
176  for (char FlagChar : FlagsString) {
177  switch (FlagChar) {
178  case 'a':
179  // Ignored.
180  break;
181 
182  case 'b': // bss section
183  SecFlags |= Alloc;
184  if (SecFlags & InitData)
185  return TokError("conflicting section flags 'b' and 'd'.");
186  SecFlags &= ~Load;
187  break;
188 
189  case 'd': // data section
190  SecFlags |= InitData;
191  if (SecFlags & Alloc)
192  return TokError("conflicting section flags 'b' and 'd'.");
193  SecFlags &= ~NoWrite;
194  if ((SecFlags & NoLoad) == 0)
195  SecFlags |= Load;
196  break;
197 
198  case 'n': // section is not loaded
199  SecFlags |= NoLoad;
200  SecFlags &= ~Load;
201  break;
202 
203  case 'D': // discardable
204  SecFlags |= Discardable;
205  break;
206 
207  case 'r': // read-only
208  ReadOnlyRemoved = false;
209  SecFlags |= NoWrite;
210  if ((SecFlags & Code) == 0)
211  SecFlags |= InitData;
212  if ((SecFlags & NoLoad) == 0)
213  SecFlags |= Load;
214  break;
215 
216  case 's': // shared section
217  SecFlags |= Shared | InitData;
218  SecFlags &= ~NoWrite;
219  if ((SecFlags & NoLoad) == 0)
220  SecFlags |= Load;
221  break;
222 
223  case 'w': // writable
224  SecFlags &= ~NoWrite;
225  ReadOnlyRemoved = true;
226  break;
227 
228  case 'x': // executable section
229  SecFlags |= Code;
230  if ((SecFlags & NoLoad) == 0)
231  SecFlags |= Load;
232  if (!ReadOnlyRemoved)
233  SecFlags |= NoWrite;
234  break;
235 
236  case 'y': // not readable
237  SecFlags |= NoRead | NoWrite;
238  break;
239 
240  default:
241  return TokError("unknown flag");
242  }
243  }
244 
245  *Flags = 0;
246 
247  if (SecFlags == None)
248  SecFlags = InitData;
249 
250  if (SecFlags & Code)
252  if (SecFlags & InitData)
254  if ((SecFlags & Alloc) && (SecFlags & Load) == 0)
256  if (SecFlags & NoLoad)
257  *Flags |= COFF::IMAGE_SCN_LNK_REMOVE;
258  if ((SecFlags & Discardable) ||
261  if ((SecFlags & NoRead) == 0)
262  *Flags |= COFF::IMAGE_SCN_MEM_READ;
263  if ((SecFlags & NoWrite) == 0)
264  *Flags |= COFF::IMAGE_SCN_MEM_WRITE;
265  if (SecFlags & Shared)
266  *Flags |= COFF::IMAGE_SCN_MEM_SHARED;
267 
268  return false;
269 }
270 
271 /// ParseDirectiveSymbolAttribute
272 /// ::= { ".weak", ... } [ identifier ( , identifier )* ]
273 bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
274  MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
275  .Case(".weak", MCSA_Weak)
277  assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
278  if (getLexer().isNot(AsmToken::EndOfStatement)) {
279  while (true) {
280  StringRef Name;
281 
282  if (getParser().parseIdentifier(Name))
283  return TokError("expected identifier in directive");
284 
285  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
286 
287  getStreamer().EmitSymbolAttribute(Sym, Attr);
288 
289  if (getLexer().is(AsmToken::EndOfStatement))
290  break;
291 
292  if (getLexer().isNot(AsmToken::Comma))
293  return TokError("unexpected token in directive");
294  Lex();
295  }
296  }
297 
298  Lex();
299  return false;
300 }
301 
302 bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
303  unsigned Characteristics,
304  SectionKind Kind) {
305  return ParseSectionSwitch(Section, Characteristics, Kind, "", (COFF::COMDATType)0);
306 }
307 
308 bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
309  unsigned Characteristics,
310  SectionKind Kind,
311  StringRef COMDATSymName,
313  if (getLexer().isNot(AsmToken::EndOfStatement))
314  return TokError("unexpected token in section switching directive");
315  Lex();
316 
317  getStreamer().SwitchSection(getContext().getCOFFSection(
318  Section, Characteristics, Kind, COMDATSymName, Type));
319 
320  return false;
321 }
322 
323 bool COFFAsmParser::ParseSectionName(StringRef &SectionName) {
324  if (!getLexer().is(AsmToken::Identifier))
325  return true;
326 
327  SectionName = getTok().getIdentifier();
328  Lex();
329  return false;
330 }
331 
332 // .section name [, "flags"] [, identifier [ identifier ], identifier]
333 //
334 // Supported flags:
335 // a: Ignored.
336 // b: BSS section (uninitialized data)
337 // d: data section (initialized data)
338 // n: "noload" section (removed by linker)
339 // D: Discardable section
340 // r: Readable section
341 // s: Shared section
342 // w: Writable section
343 // x: Executable section
344 // y: Not-readable section (clears 'r')
345 //
346 // Subsections are not supported.
347 bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
349 
350  if (ParseSectionName(SectionName))
351  return TokError("expected identifier in directive");
352 
353  unsigned Flags = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
356 
357  if (getLexer().is(AsmToken::Comma)) {
358  Lex();
359 
360  if (getLexer().isNot(AsmToken::String))
361  return TokError("expected string in directive");
362 
363  StringRef FlagsStr = getTok().getStringContents();
364  Lex();
365 
366  if (ParseSectionFlags(SectionName, FlagsStr, &Flags))
367  return true;
368  }
369 
371  StringRef COMDATSymName;
372  if (getLexer().is(AsmToken::Comma)) {
374  Lex();
375 
377 
378  if (!getLexer().is(AsmToken::Identifier))
379  return TokError("expected comdat type such as 'discard' or 'largest' "
380  "after protection bits");
381 
382  if (parseCOMDATType(Type))
383  return true;
384 
385  if (getLexer().isNot(AsmToken::Comma))
386  return TokError("expected comma in directive");
387  Lex();
388 
389  if (getParser().parseIdentifier(COMDATSymName))
390  return TokError("expected identifier in directive");
391  }
392 
393  if (getLexer().isNot(AsmToken::EndOfStatement))
394  return TokError("unexpected token in directive");
395 
396  SectionKind Kind = computeSectionKind(Flags);
397  if (Kind.isText()) {
398  const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
399  if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
400  Flags |= COFF::IMAGE_SCN_MEM_16BIT;
401  }
402  ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type);
403  return false;
404 }
405 
406 bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
408 
409  if (getParser().parseIdentifier(SymbolName))
410  return TokError("expected identifier in directive");
411 
412  MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
413 
414  getStreamer().BeginCOFFSymbolDef(Sym);
415 
416  Lex();
417  return false;
418 }
419 
420 bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
421  int64_t SymbolStorageClass;
422  if (getParser().parseAbsoluteExpression(SymbolStorageClass))
423  return true;
424 
425  if (getLexer().isNot(AsmToken::EndOfStatement))
426  return TokError("unexpected token in directive");
427 
428  Lex();
429  getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
430  return false;
431 }
432 
433 bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
434  int64_t Type;
435  if (getParser().parseAbsoluteExpression(Type))
436  return true;
437 
438  if (getLexer().isNot(AsmToken::EndOfStatement))
439  return TokError("unexpected token in directive");
440 
441  Lex();
442  getStreamer().EmitCOFFSymbolType(Type);
443  return false;
444 }
445 
446 bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
447  Lex();
448  getStreamer().EndCOFFSymbolDef();
449  return false;
450 }
451 
452 bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
453  StringRef SymbolID;
454  if (getParser().parseIdentifier(SymbolID))
455  return TokError("expected identifier in directive");
456 
457  int64_t Offset = 0;
458  SMLoc OffsetLoc;
459  if (getLexer().is(AsmToken::Plus)) {
460  OffsetLoc = getLexer().getLoc();
461  if (getParser().parseAbsoluteExpression(Offset))
462  return true;
463  }
464 
465  if (getLexer().isNot(AsmToken::EndOfStatement))
466  return TokError("unexpected token in directive");
467 
468  if (Offset < 0 || Offset > std::numeric_limits<uint32_t>::max())
469  return Error(
470  OffsetLoc,
471  "invalid '.secrel32' directive offset, can't be less "
472  "than zero or greater than std::numeric_limits<uint32_t>::max()");
473 
474  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
475 
476  Lex();
477  getStreamer().EmitCOFFSecRel32(Symbol, Offset);
478  return false;
479 }
480 
481 bool COFFAsmParser::ParseDirectiveRVA(StringRef, SMLoc) {
482  auto parseOp = [&]() -> bool {
483  StringRef SymbolID;
484  if (getParser().parseIdentifier(SymbolID))
485  return TokError("expected identifier in directive");
486 
487  int64_t Offset = 0;
488  SMLoc OffsetLoc;
489  if (getLexer().is(AsmToken::Plus) || getLexer().is(AsmToken::Minus)) {
490  OffsetLoc = getLexer().getLoc();
491  if (getParser().parseAbsoluteExpression(Offset))
492  return true;
493  }
494 
495  if (Offset < std::numeric_limits<int32_t>::min() ||
497  return Error(OffsetLoc, "invalid '.rva' directive offset, can't be less "
498  "than -2147483648 or greater than "
499  "2147483647");
500 
501  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
502 
503  getStreamer().EmitCOFFImgRel32(Symbol, Offset);
504  return false;
505  };
506 
507  if (getParser().parseMany(parseOp))
508  return addErrorSuffix(" in directive");
509  return false;
510 }
511 
512 bool COFFAsmParser::ParseDirectiveSafeSEH(StringRef, SMLoc) {
513  StringRef SymbolID;
514  if (getParser().parseIdentifier(SymbolID))
515  return TokError("expected identifier in directive");
516 
517  if (getLexer().isNot(AsmToken::EndOfStatement))
518  return TokError("unexpected token in directive");
519 
520  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
521 
522  Lex();
523  getStreamer().EmitCOFFSafeSEH(Symbol);
524  return false;
525 }
526 
527 bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) {
528  StringRef SymbolID;
529  if (getParser().parseIdentifier(SymbolID))
530  return TokError("expected identifier in directive");
531 
532  if (getLexer().isNot(AsmToken::EndOfStatement))
533  return TokError("unexpected token in directive");
534 
535  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
536 
537  Lex();
538  getStreamer().EmitCOFFSectionIndex(Symbol);
539  return false;
540 }
541 
542 bool COFFAsmParser::ParseDirectiveSymIdx(StringRef, SMLoc) {
543  StringRef SymbolID;
544  if (getParser().parseIdentifier(SymbolID))
545  return TokError("expected identifier in directive");
546 
547  if (getLexer().isNot(AsmToken::EndOfStatement))
548  return TokError("unexpected token in directive");
549 
550  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
551 
552  Lex();
553  getStreamer().EmitCOFFSymbolIndex(Symbol);
554  return false;
555 }
556 
557 /// ::= [ identifier ]
558 bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
559  StringRef TypeId = getTok().getIdentifier();
560 
561  Type = StringSwitch<COFF::COMDATType>(TypeId)
562  .Case("one_only", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES)
570 
571  if (Type == 0)
572  return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'"));
573 
574  Lex();
575 
576  return false;
577 }
578 
579 /// ParseDirectiveLinkOnce
580 /// ::= .linkonce [ identifier ]
581 bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
583  if (getLexer().is(AsmToken::Identifier))
584  if (parseCOMDATType(Type))
585  return true;
586 
587  const MCSectionCOFF *Current =
588  static_cast<const MCSectionCOFF *>(getStreamer().getCurrentSectionOnly());
589 
591  return Error(Loc, "cannot make section associative with .linkonce");
592 
594  return Error(Loc, Twine("section '") + Current->getSectionName() +
595  "' is already linkonce");
596 
597  Current->setSelection(Type);
598 
599  if (getLexer().isNot(AsmToken::EndOfStatement))
600  return TokError("unexpected token in directive");
601 
602  return false;
603 }
604 
605 bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc Loc) {
606  StringRef SymbolID;
607  if (getParser().parseIdentifier(SymbolID))
608  return true;
609 
610  if (getLexer().isNot(AsmToken::EndOfStatement))
611  return TokError("unexpected token in directive");
612 
613  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
614 
615  Lex();
616  getStreamer().EmitWinCFIStartProc(Symbol, Loc);
617  return false;
618 }
619 
620 bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc Loc) {
621  Lex();
622  getStreamer().EmitWinCFIEndProc(Loc);
623  return false;
624 }
625 
626 bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc Loc) {
627  Lex();
628  getStreamer().EmitWinCFIStartChained(Loc);
629  return false;
630 }
631 
632 bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc Loc) {
633  Lex();
634  getStreamer().EmitWinCFIEndChained(Loc);
635  return false;
636 }
637 
638 bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc Loc) {
639  StringRef SymbolID;
640  if (getParser().parseIdentifier(SymbolID))
641  return true;
642 
643  if (getLexer().isNot(AsmToken::Comma))
644  return TokError("you must specify one or both of @unwind or @except");
645  Lex();
646  bool unwind = false, except = false;
647  if (ParseAtUnwindOrAtExcept(unwind, except))
648  return true;
649  if (getLexer().is(AsmToken::Comma)) {
650  Lex();
651  if (ParseAtUnwindOrAtExcept(unwind, except))
652  return true;
653  }
654  if (getLexer().isNot(AsmToken::EndOfStatement))
655  return TokError("unexpected token in directive");
656 
657  MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID);
658 
659  Lex();
660  getStreamer().EmitWinEHHandler(handler, unwind, except, Loc);
661  return false;
662 }
663 
664 bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc Loc) {
665  Lex();
666  getStreamer().EmitWinEHHandlerData();
667  return false;
668 }
669 
670 bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
671  int64_t Size;
672  if (getParser().parseAbsoluteExpression(Size))
673  return true;
674 
675  if (getLexer().isNot(AsmToken::EndOfStatement))
676  return TokError("unexpected token in directive");
677 
678  Lex();
679  getStreamer().EmitWinCFIAllocStack(Size, Loc);
680  return false;
681 }
682 
683 bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc Loc) {
684  Lex();
685  getStreamer().EmitWinCFIEndProlog(Loc);
686  return false;
687 }
688 
689 bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
690  StringRef identifier;
691  if (getLexer().isNot(AsmToken::At))
692  return TokError("a handler attribute must begin with '@'");
693  SMLoc startLoc = getLexer().getLoc();
694  Lex();
695  if (getParser().parseIdentifier(identifier))
696  return Error(startLoc, "expected @unwind or @except");
697  if (identifier == "unwind")
698  unwind = true;
699  else if (identifier == "except")
700  except = true;
701  else
702  return Error(startLoc, "expected @unwind or @except");
703  return false;
704 }
705 
706 namespace llvm {
707 
709  return new COFFAsmParser;
710 }
711 
712 } // end namespace llvm
static SectionKind getData()
Definition: SectionKind.h:201
This class represents lattice values for constants.
Definition: AllocatorList.h:23
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
Not a valid directive.
Definition: MCDirectives.h:19
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:109
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
void setSelection(int Selection) const
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:67
static SectionKind computeSectionKind(unsigned Flags)
This represents a section on Windows.
Definition: MCSectionCOFF.h:26
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
static SectionKind getBSS()
Definition: SectionKind.h:197
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:181
bool isText() const
Definition: SectionKind.h:118
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:296
unsigned getCharacteristics() const
Definition: MCSectionCOFF.h:70
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition: SectionKind.h:22
MCAsmParserExtension * createCOFFAsmParser()
StringRef getSectionName() const
Definition: MCSectionCOFF.h:69
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:390
MCSymbolAttr
Definition: MCDirectives.h:18
COMDATType
Definition: COFF.h:405
SymbolStorageClass
Storage class tells where and what the symbol represents.
Definition: COFF.h:203
COFFYAML::WeakExternalCharacteristics Characteristics
Definition: COFFYAML.cpp:325
uint32_t Size
Definition: Profile.cpp:46
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImplicitlyDiscardable(StringRef Name)
Definition: MCSectionCOFF.h:88
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
Definition: MCAsmParser.h:113
const char SectionName[]
Definition: AMDGPUPTNote.h:23
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Represents a location in source code.
Definition: SMLoc.h:23
static SectionKind getReadOnly()
Definition: SectionKind.h:181
static SectionKind getText()
Definition: SectionKind.h:179