1 //===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
11 #include "llvm/ADT/StringSwitch.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/MC/MCAsmInfo.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCParser/MCAsmLexer.h"
17 #include "llvm/MC/MCRegisterInfo.h"
18 #include "llvm/MC/MCSectionCOFF.h"
19 #include "llvm/MC/MCStreamer.h"
20 #include "llvm/MC/MCTargetAsmParser.h"
21 #include "llvm/Support/COFF.h"
26 class COFFAsmParser : public MCAsmParserExtension {
27 template<bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
28 void addDirectiveHandler(StringRef Directive) {
29 MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
30 this, HandleDirective<COFFAsmParser, HandlerMethod>);
31 getParser().addDirectiveHandler(Directive, Handler);
34 bool ParseSectionSwitch(StringRef Section,
35 unsigned Characteristics,
38 bool ParseSectionSwitch(StringRef Section, unsigned Characteristics,
39 SectionKind Kind, StringRef COMDATSymName,
40 COFF::COMDATType Type);
42 bool ParseSectionName(StringRef &SectionName);
43 bool ParseSectionFlags(StringRef FlagsString, unsigned* Flags);
45 void Initialize(MCAsmParser &Parser) override {
46 // Call the base implementation.
47 MCAsmParserExtension::Initialize(Parser);
49 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
50 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
51 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
52 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(".section");
53 addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
54 addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
55 addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
56 addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
57 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
58 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx");
59 addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce");
61 // Win64 EH directives.
62 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
64 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
66 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
68 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
70 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
72 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
74 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
76 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
78 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
80 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
82 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
84 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
86 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
88 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
91 bool ParseSectionDirectiveText(StringRef, SMLoc) {
92 return ParseSectionSwitch(".text",
93 COFF::IMAGE_SCN_CNT_CODE
94 | COFF::IMAGE_SCN_MEM_EXECUTE
95 | COFF::IMAGE_SCN_MEM_READ,
96 SectionKind::getText());
98 bool ParseSectionDirectiveData(StringRef, SMLoc) {
99 return ParseSectionSwitch(".data",
100 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
101 | COFF::IMAGE_SCN_MEM_READ
102 | COFF::IMAGE_SCN_MEM_WRITE,
103 SectionKind::getDataRel());
105 bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
106 return ParseSectionSwitch(".bss",
107 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
108 | COFF::IMAGE_SCN_MEM_READ
109 | COFF::IMAGE_SCN_MEM_WRITE,
110 SectionKind::getBSS());
113 bool ParseDirectiveSection(StringRef, SMLoc);
114 bool ParseDirectiveDef(StringRef, SMLoc);
115 bool ParseDirectiveScl(StringRef, SMLoc);
116 bool ParseDirectiveType(StringRef, SMLoc);
117 bool ParseDirectiveEndef(StringRef, SMLoc);
118 bool ParseDirectiveSecRel32(StringRef, SMLoc);
119 bool ParseDirectiveSecIdx(StringRef, SMLoc);
120 bool parseCOMDATType(COFF::COMDATType &Type);
121 bool ParseDirectiveLinkOnce(StringRef, SMLoc);
123 // Win64 EH directives.
124 bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
125 bool ParseSEHDirectiveEndProc(StringRef, SMLoc);
126 bool ParseSEHDirectiveStartChained(StringRef, SMLoc);
127 bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
128 bool ParseSEHDirectiveHandler(StringRef, SMLoc);
129 bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
130 bool ParseSEHDirectivePushReg(StringRef, SMLoc);
131 bool ParseSEHDirectiveSetFrame(StringRef, SMLoc);
132 bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
133 bool ParseSEHDirectiveSaveReg(StringRef, SMLoc);
134 bool ParseSEHDirectiveSaveXMM(StringRef, SMLoc);
135 bool ParseSEHDirectivePushFrame(StringRef, SMLoc);
136 bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
138 bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
139 bool ParseSEHRegisterNumber(unsigned &RegNo);
140 bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
145 } // end annonomous namespace.
147 static SectionKind computeSectionKind(unsigned Flags) {
148 if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
149 return SectionKind::getText();
150 if (Flags & COFF::IMAGE_SCN_MEM_READ &&
151 (Flags & COFF::IMAGE_SCN_MEM_WRITE) == 0)
152 return SectionKind::getReadOnly();
153 return SectionKind::getDataRel();
156 bool COFFAsmParser::ParseSectionFlags(StringRef FlagsString, unsigned* Flags) {
169 bool ReadOnlyRemoved = false;
170 unsigned SecFlags = None;
172 for (unsigned i = 0; i < FlagsString.size(); ++i) {
173 switch (FlagsString[i]) {
178 case 'b': // bss section
180 if (SecFlags & InitData)
181 return TokError("conflicting section flags 'b' and 'd'.");
185 case 'd': // data section
186 SecFlags |= InitData;
187 if (SecFlags & Alloc)
188 return TokError("conflicting section flags 'b' and 'd'.");
189 SecFlags &= ~NoWrite;
190 if ((SecFlags & NoLoad) == 0)
194 case 'n': // section is not loaded
199 case 'r': // read-only
200 ReadOnlyRemoved = false;
202 if ((SecFlags & Code) == 0)
203 SecFlags |= InitData;
204 if ((SecFlags & NoLoad) == 0)
208 case 's': // shared section
209 SecFlags |= Shared | InitData;
210 SecFlags &= ~NoWrite;
211 if ((SecFlags & NoLoad) == 0)
215 case 'w': // writable
216 SecFlags &= ~NoWrite;
217 ReadOnlyRemoved = true;
220 case 'x': // executable section
222 if ((SecFlags & NoLoad) == 0)
224 if (!ReadOnlyRemoved)
228 case 'y': // not readable
229 SecFlags |= NoRead | NoWrite;
233 return TokError("unknown flag");
239 if (SecFlags == None)
243 *Flags |= COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE;
244 if (SecFlags & InitData)
245 *Flags |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
246 if ((SecFlags & Alloc) && (SecFlags & Load) == 0)
247 *Flags |= COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
248 if (SecFlags & NoLoad)
249 *Flags |= COFF::IMAGE_SCN_LNK_REMOVE;
250 if ((SecFlags & NoRead) == 0)
251 *Flags |= COFF::IMAGE_SCN_MEM_READ;
252 if ((SecFlags & NoWrite) == 0)
253 *Flags |= COFF::IMAGE_SCN_MEM_WRITE;
254 if (SecFlags & Shared)
255 *Flags |= COFF::IMAGE_SCN_MEM_SHARED;
260 /// ParseDirectiveSymbolAttribute
261 /// ::= { ".weak", ... } [ identifier ( , identifier )* ]
262 bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
263 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
264 .Case(".weak", MCSA_Weak)
265 .Default(MCSA_Invalid);
266 assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
267 if (getLexer().isNot(AsmToken::EndOfStatement)) {
271 if (getParser().parseIdentifier(Name))
272 return TokError("expected identifier in directive");
274 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
276 getStreamer().EmitSymbolAttribute(Sym, Attr);
278 if (getLexer().is(AsmToken::EndOfStatement))
281 if (getLexer().isNot(AsmToken::Comma))
282 return TokError("unexpected token in directive");
291 bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
292 unsigned Characteristics,
294 return ParseSectionSwitch(Section, Characteristics, Kind, "",
295 COFF::IMAGE_COMDAT_SELECT_ANY);
298 bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
299 unsigned Characteristics,
301 StringRef COMDATSymName,
302 COFF::COMDATType Type) {
303 if (getLexer().isNot(AsmToken::EndOfStatement))
304 return TokError("unexpected token in section switching directive");
307 getStreamer().SwitchSection(getContext().getCOFFSection(
308 Section, Characteristics, Kind, COMDATSymName, Type));
313 bool COFFAsmParser::ParseSectionName(StringRef &SectionName) {
314 if (!getLexer().is(AsmToken::Identifier))
317 SectionName = getTok().getIdentifier();
322 // .section name [, "flags"] [, identifier [ identifier ], identifier]
326 // b: BSS section (uninitialized data)
327 // d: data section (initialized data)
328 // n: Discardable section
329 // r: Readable section
331 // w: Writable section
332 // x: Executable section
333 // y: Not-readable section (clears 'r')
335 // Subsections are not supported.
336 bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
337 StringRef SectionName;
339 if (ParseSectionName(SectionName))
340 return TokError("expected identifier in directive");
342 unsigned Flags = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
343 COFF::IMAGE_SCN_MEM_READ |
344 COFF::IMAGE_SCN_MEM_WRITE;
346 if (getLexer().is(AsmToken::Comma)) {
349 if (getLexer().isNot(AsmToken::String))
350 return TokError("expected string in directive");
352 StringRef FlagsStr = getTok().getStringContents();
355 if (ParseSectionFlags(FlagsStr, &Flags))
359 COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
360 StringRef COMDATSymName;
361 if (getLexer().is(AsmToken::Comma)) {
364 Flags |= COFF::IMAGE_SCN_LNK_COMDAT;
366 if (parseCOMDATType(Type))
369 if (getLexer().isNot(AsmToken::Comma))
370 return TokError("expected comma in directive");
373 if (getParser().parseIdentifier(COMDATSymName))
374 return TokError("expected identifier in directive");
377 if (getLexer().isNot(AsmToken::EndOfStatement))
378 return TokError("unexpected token in directive");
380 SectionKind Kind = computeSectionKind(Flags);
381 ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type);
385 bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
386 StringRef SymbolName;
388 if (getParser().parseIdentifier(SymbolName))
389 return TokError("expected identifier in directive");
391 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
393 getStreamer().BeginCOFFSymbolDef(Sym);
399 bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
400 int64_t SymbolStorageClass;
401 if (getParser().parseAbsoluteExpression(SymbolStorageClass))
404 if (getLexer().isNot(AsmToken::EndOfStatement))
405 return TokError("unexpected token in directive");
408 getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
412 bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
414 if (getParser().parseAbsoluteExpression(Type))
417 if (getLexer().isNot(AsmToken::EndOfStatement))
418 return TokError("unexpected token in directive");
421 getStreamer().EmitCOFFSymbolType(Type);
425 bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
427 getStreamer().EndCOFFSymbolDef();
431 bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
433 if (getParser().parseIdentifier(SymbolID))
434 return TokError("expected identifier in directive");
436 if (getLexer().isNot(AsmToken::EndOfStatement))
437 return TokError("unexpected token in directive");
439 MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);
442 getStreamer().EmitCOFFSecRel32(Symbol);
446 bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) {
448 if (getParser().parseIdentifier(SymbolID))
449 return TokError("expected identifier in directive");
451 if (getLexer().isNot(AsmToken::EndOfStatement))
452 return TokError("unexpected token in directive");
454 MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);
457 getStreamer().EmitCOFFSectionIndex(Symbol);
461 /// ::= [ identifier ]
462 bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
463 StringRef TypeId = getTok().getIdentifier();
465 Type = StringSwitch<COFF::COMDATType>(TypeId)
466 .Case("one_only", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES)
467 .Case("discard", COFF::IMAGE_COMDAT_SELECT_ANY)
468 .Case("same_size", COFF::IMAGE_COMDAT_SELECT_SAME_SIZE)
469 .Case("same_contents", COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH)
470 .Case("associative", COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
471 .Case("largest", COFF::IMAGE_COMDAT_SELECT_LARGEST)
472 .Case("newest", COFF::IMAGE_COMDAT_SELECT_NEWEST)
473 .Default((COFF::COMDATType)0);
476 return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'"));
483 /// ParseDirectiveLinkOnce
484 /// ::= .linkonce [ identifier ]
485 bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
486 COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
487 if (getLexer().is(AsmToken::Identifier))
488 if (parseCOMDATType(Type))
491 const MCSectionCOFF *Current = static_cast<const MCSectionCOFF*>(
492 getStreamer().getCurrentSection().first);
494 if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
495 return Error(Loc, "cannot make section associative with .linkonce");
497 if (Current->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
498 return Error(Loc, Twine("section '") + Current->getSectionName() +
499 "' is already linkonce");
501 Current->setSelection(Type);
503 if (getLexer().isNot(AsmToken::EndOfStatement))
504 return TokError("unexpected token in directive");
509 bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
511 if (getParser().parseIdentifier(SymbolID))
514 if (getLexer().isNot(AsmToken::EndOfStatement))
515 return TokError("unexpected token in directive");
517 MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);
520 getStreamer().EmitWin64EHStartProc(Symbol);
524 bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) {
526 getStreamer().EmitWin64EHEndProc();
530 bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) {
532 getStreamer().EmitWin64EHStartChained();
536 bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
538 getStreamer().EmitWin64EHEndChained();
542 bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
544 if (getParser().parseIdentifier(SymbolID))
547 if (getLexer().isNot(AsmToken::Comma))
548 return TokError("you must specify one or both of @unwind or @except");
550 bool unwind = false, except = false;
551 if (ParseAtUnwindOrAtExcept(unwind, except))
553 if (getLexer().is(AsmToken::Comma)) {
555 if (ParseAtUnwindOrAtExcept(unwind, except))
558 if (getLexer().isNot(AsmToken::EndOfStatement))
559 return TokError("unexpected token in directive");
561 MCSymbol *handler = getContext().GetOrCreateSymbol(SymbolID);
564 getStreamer().EmitWin64EHHandler(handler, unwind, except);
568 bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) {
570 getStreamer().EmitWin64EHHandlerData();
574 bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) {
576 if (ParseSEHRegisterNumber(Reg))
579 if (getLexer().isNot(AsmToken::EndOfStatement))
580 return TokError("unexpected token in directive");
583 getStreamer().EmitWin64EHPushReg(Reg);
587 bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
590 if (ParseSEHRegisterNumber(Reg))
592 if (getLexer().isNot(AsmToken::Comma))
593 return TokError("you must specify a stack pointer offset");
596 SMLoc startLoc = getLexer().getLoc();
597 if (getParser().parseAbsoluteExpression(Off))
601 return Error(startLoc, "offset is not a multiple of 16");
603 if (getLexer().isNot(AsmToken::EndOfStatement))
604 return TokError("unexpected token in directive");
607 getStreamer().EmitWin64EHSetFrame(Reg, Off);
611 bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) {
613 SMLoc startLoc = getLexer().getLoc();
614 if (getParser().parseAbsoluteExpression(Size))
618 return Error(startLoc, "size is not a multiple of 8");
620 if (getLexer().isNot(AsmToken::EndOfStatement))
621 return TokError("unexpected token in directive");
624 getStreamer().EmitWin64EHAllocStack(Size);
628 bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
631 if (ParseSEHRegisterNumber(Reg))
633 if (getLexer().isNot(AsmToken::Comma))
634 return TokError("you must specify an offset on the stack");
637 SMLoc startLoc = getLexer().getLoc();
638 if (getParser().parseAbsoluteExpression(Off))
642 return Error(startLoc, "size is not a multiple of 8");
644 if (getLexer().isNot(AsmToken::EndOfStatement))
645 return TokError("unexpected token in directive");
648 // FIXME: Err on %xmm* registers
649 getStreamer().EmitWin64EHSaveReg(Reg, Off);
653 // FIXME: This method is inherently x86-specific. It should really be in the
655 bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
658 if (ParseSEHRegisterNumber(Reg))
660 if (getLexer().isNot(AsmToken::Comma))
661 return TokError("you must specify an offset on the stack");
664 SMLoc startLoc = getLexer().getLoc();
665 if (getParser().parseAbsoluteExpression(Off))
668 if (getLexer().isNot(AsmToken::EndOfStatement))
669 return TokError("unexpected token in directive");
672 return Error(startLoc, "offset is not a multiple of 16");
675 // FIXME: Err on non-%xmm* registers
676 getStreamer().EmitWin64EHSaveXMM(Reg, Off);
680 bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) {
683 if (getLexer().is(AsmToken::At)) {
684 SMLoc startLoc = getLexer().getLoc();
686 if (!getParser().parseIdentifier(CodeID)) {
687 if (CodeID != "code")
688 return Error(startLoc, "expected @code");
693 if (getLexer().isNot(AsmToken::EndOfStatement))
694 return TokError("unexpected token in directive");
697 getStreamer().EmitWin64EHPushFrame(Code);
701 bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) {
703 getStreamer().EmitWin64EHEndProlog();
707 bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
708 StringRef identifier;
709 if (getLexer().isNot(AsmToken::At))
710 return TokError("a handler attribute must begin with '@'");
711 SMLoc startLoc = getLexer().getLoc();
713 if (getParser().parseIdentifier(identifier))
714 return Error(startLoc, "expected @unwind or @except");
715 if (identifier == "unwind")
717 else if (identifier == "except")
720 return Error(startLoc, "expected @unwind or @except");
724 bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) {
725 SMLoc startLoc = getLexer().getLoc();
726 if (getLexer().is(AsmToken::Percent)) {
727 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
730 if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
734 // FIXME: TargetAsmInfo::getCalleeSavedRegs() commits a serious layering
735 // violation so this validation code is disabled.
737 // Check that this is a non-volatile register.
738 const unsigned *NVRegs = TAI.getCalleeSavedRegs();
740 for (i = 0; NVRegs[i] != 0; ++i)
741 if (NVRegs[i] == LLVMRegNo)
744 return Error(startLoc, "expected non-volatile register");
747 int SEHRegNo = MRI->getSEHRegNum(LLVMRegNo);
749 return Error(startLoc,"register can't be represented in SEH unwind info");
754 if (getParser().parseAbsoluteExpression(n))
757 return Error(startLoc, "register number is too high");
766 MCAsmParserExtension *createCOFFAsmParser() {
767 return new COFFAsmParser;