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/MCObjectFileInfo.h"
17 #include "llvm/MC/MCParser/MCAsmLexer.h"
18 #include "llvm/MC/MCRegisterInfo.h"
19 #include "llvm/MC/MCSectionCOFF.h"
20 #include "llvm/MC/MCStreamer.h"
21 #include "llvm/MC/MCTargetAsmParser.h"
22 #include "llvm/Support/COFF.h"
27 class COFFAsmParser
: public MCAsmParserExtension
{
28 template<bool (COFFAsmParser::*HandlerMethod
)(StringRef
, SMLoc
)>
29 void addDirectiveHandler(StringRef Directive
) {
30 MCAsmParser::ExtensionDirectiveHandler Handler
= std::make_pair(
31 this, HandleDirective
<COFFAsmParser
, HandlerMethod
>);
32 getParser().addDirectiveHandler(Directive
, Handler
);
35 bool ParseSectionSwitch(StringRef Section
,
36 unsigned Characteristics
,
39 bool ParseSectionSwitch(StringRef Section
, unsigned Characteristics
,
40 SectionKind Kind
, StringRef COMDATSymName
,
41 COFF::COMDATType Type
);
43 bool ParseSectionName(StringRef
&SectionName
);
44 bool ParseSectionFlags(StringRef FlagsString
, unsigned* Flags
);
46 void Initialize(MCAsmParser
&Parser
) override
{
47 // Call the base implementation.
48 MCAsmParserExtension::Initialize(Parser
);
50 addDirectiveHandler
<&COFFAsmParser::ParseSectionDirectiveText
>(".text");
51 addDirectiveHandler
<&COFFAsmParser::ParseSectionDirectiveData
>(".data");
52 addDirectiveHandler
<&COFFAsmParser::ParseSectionDirectiveBSS
>(".bss");
53 addDirectiveHandler
<&COFFAsmParser::ParseDirectiveSection
>(".section");
54 addDirectiveHandler
<&COFFAsmParser::ParseDirectiveDef
>(".def");
55 addDirectiveHandler
<&COFFAsmParser::ParseDirectiveScl
>(".scl");
56 addDirectiveHandler
<&COFFAsmParser::ParseDirectiveType
>(".type");
57 addDirectiveHandler
<&COFFAsmParser::ParseDirectiveEndef
>(".endef");
58 addDirectiveHandler
<&COFFAsmParser::ParseDirectiveSecRel32
>(".secrel32");
59 addDirectiveHandler
<&COFFAsmParser::ParseDirectiveSecIdx
>(".secidx");
60 addDirectiveHandler
<&COFFAsmParser::ParseDirectiveLinkOnce
>(".linkonce");
62 // Win64 EH directives.
63 addDirectiveHandler
<&COFFAsmParser::ParseSEHDirectiveStartProc
>(
65 addDirectiveHandler
<&COFFAsmParser::ParseSEHDirectiveEndProc
>(
67 addDirectiveHandler
<&COFFAsmParser::ParseSEHDirectiveStartChained
>(
69 addDirectiveHandler
<&COFFAsmParser::ParseSEHDirectiveEndChained
>(
71 addDirectiveHandler
<&COFFAsmParser::ParseSEHDirectiveHandler
>(
73 addDirectiveHandler
<&COFFAsmParser::ParseSEHDirectiveHandlerData
>(
75 addDirectiveHandler
<&COFFAsmParser::ParseSEHDirectivePushReg
>(
77 addDirectiveHandler
<&COFFAsmParser::ParseSEHDirectiveSetFrame
>(
79 addDirectiveHandler
<&COFFAsmParser::ParseSEHDirectiveAllocStack
>(
81 addDirectiveHandler
<&COFFAsmParser::ParseSEHDirectiveSaveReg
>(
83 addDirectiveHandler
<&COFFAsmParser::ParseSEHDirectiveSaveXMM
>(
85 addDirectiveHandler
<&COFFAsmParser::ParseSEHDirectivePushFrame
>(
87 addDirectiveHandler
<&COFFAsmParser::ParseSEHDirectiveEndProlog
>(
89 addDirectiveHandler
<&COFFAsmParser::ParseDirectiveSymbolAttribute
>(".weak");
92 bool ParseSectionDirectiveText(StringRef
, SMLoc
) {
93 return ParseSectionSwitch(".text",
94 COFF::IMAGE_SCN_CNT_CODE
95 | COFF::IMAGE_SCN_MEM_EXECUTE
96 | COFF::IMAGE_SCN_MEM_READ
,
97 SectionKind::getText());
99 bool ParseSectionDirectiveData(StringRef
, SMLoc
) {
100 return ParseSectionSwitch(".data",
101 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
102 | COFF::IMAGE_SCN_MEM_READ
103 | COFF::IMAGE_SCN_MEM_WRITE
,
104 SectionKind::getDataRel());
106 bool ParseSectionDirectiveBSS(StringRef
, SMLoc
) {
107 return ParseSectionSwitch(".bss",
108 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
109 | COFF::IMAGE_SCN_MEM_READ
110 | COFF::IMAGE_SCN_MEM_WRITE
,
111 SectionKind::getBSS());
114 bool ParseDirectiveSection(StringRef
, SMLoc
);
115 bool ParseDirectiveDef(StringRef
, SMLoc
);
116 bool ParseDirectiveScl(StringRef
, SMLoc
);
117 bool ParseDirectiveType(StringRef
, SMLoc
);
118 bool ParseDirectiveEndef(StringRef
, SMLoc
);
119 bool ParseDirectiveSecRel32(StringRef
, SMLoc
);
120 bool ParseDirectiveSecIdx(StringRef
, SMLoc
);
121 bool parseCOMDATType(COFF::COMDATType
&Type
);
122 bool ParseDirectiveLinkOnce(StringRef
, SMLoc
);
124 // Win64 EH directives.
125 bool ParseSEHDirectiveStartProc(StringRef
, SMLoc
);
126 bool ParseSEHDirectiveEndProc(StringRef
, SMLoc
);
127 bool ParseSEHDirectiveStartChained(StringRef
, SMLoc
);
128 bool ParseSEHDirectiveEndChained(StringRef
, SMLoc
);
129 bool ParseSEHDirectiveHandler(StringRef
, SMLoc
);
130 bool ParseSEHDirectiveHandlerData(StringRef
, SMLoc
);
131 bool ParseSEHDirectivePushReg(StringRef
, SMLoc
);
132 bool ParseSEHDirectiveSetFrame(StringRef
, SMLoc
);
133 bool ParseSEHDirectiveAllocStack(StringRef
, SMLoc
);
134 bool ParseSEHDirectiveSaveReg(StringRef
, SMLoc
);
135 bool ParseSEHDirectiveSaveXMM(StringRef
, SMLoc
);
136 bool ParseSEHDirectivePushFrame(StringRef
, SMLoc
);
137 bool ParseSEHDirectiveEndProlog(StringRef
, SMLoc
);
139 bool ParseAtUnwindOrAtExcept(bool &unwind
, bool &except
);
140 bool ParseSEHRegisterNumber(unsigned &RegNo
);
141 bool ParseDirectiveSymbolAttribute(StringRef Directive
, SMLoc
);
146 } // end annonomous namespace.
148 static SectionKind
computeSectionKind(unsigned Flags
) {
149 if (Flags
& COFF::IMAGE_SCN_MEM_EXECUTE
)
150 return SectionKind::getText();
151 if (Flags
& COFF::IMAGE_SCN_MEM_READ
&&
152 (Flags
& COFF::IMAGE_SCN_MEM_WRITE
) == 0)
153 return SectionKind::getReadOnly();
154 return SectionKind::getDataRel();
157 bool COFFAsmParser::ParseSectionFlags(StringRef FlagsString
, unsigned* Flags
) {
170 bool ReadOnlyRemoved
= false;
171 unsigned SecFlags
= None
;
173 for (char FlagChar
: FlagsString
) {
179 case 'b': // bss section
181 if (SecFlags
& InitData
)
182 return TokError("conflicting section flags 'b' and 'd'.");
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)
195 case 'n': // section is not loaded
200 case 'r': // read-only
201 ReadOnlyRemoved
= false;
203 if ((SecFlags
& Code
) == 0)
204 SecFlags
|= InitData
;
205 if ((SecFlags
& NoLoad
) == 0)
209 case 's': // shared section
210 SecFlags
|= Shared
| InitData
;
211 SecFlags
&= ~NoWrite
;
212 if ((SecFlags
& NoLoad
) == 0)
216 case 'w': // writable
217 SecFlags
&= ~NoWrite
;
218 ReadOnlyRemoved
= true;
221 case 'x': // executable section
223 if ((SecFlags
& NoLoad
) == 0)
225 if (!ReadOnlyRemoved
)
229 case 'y': // not readable
230 SecFlags
|= NoRead
| NoWrite
;
234 return TokError("unknown flag");
240 if (SecFlags
== None
)
244 *Flags
|= COFF::IMAGE_SCN_CNT_CODE
| COFF::IMAGE_SCN_MEM_EXECUTE
;
245 if (SecFlags
& InitData
)
246 *Flags
|= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
;
247 if ((SecFlags
& Alloc
) && (SecFlags
& Load
) == 0)
248 *Flags
|= COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
;
249 if (SecFlags
& NoLoad
)
250 *Flags
|= COFF::IMAGE_SCN_LNK_REMOVE
;
251 if ((SecFlags
& NoRead
) == 0)
252 *Flags
|= COFF::IMAGE_SCN_MEM_READ
;
253 if ((SecFlags
& NoWrite
) == 0)
254 *Flags
|= COFF::IMAGE_SCN_MEM_WRITE
;
255 if (SecFlags
& Shared
)
256 *Flags
|= COFF::IMAGE_SCN_MEM_SHARED
;
261 /// ParseDirectiveSymbolAttribute
262 /// ::= { ".weak", ... } [ identifier ( , identifier )* ]
263 bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive
, SMLoc
) {
264 MCSymbolAttr Attr
= StringSwitch
<MCSymbolAttr
>(Directive
)
265 .Case(".weak", MCSA_Weak
)
266 .Default(MCSA_Invalid
);
267 assert(Attr
!= MCSA_Invalid
&& "unexpected symbol attribute directive!");
268 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
272 if (getParser().parseIdentifier(Name
))
273 return TokError("expected identifier in directive");
275 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(Name
);
277 getStreamer().EmitSymbolAttribute(Sym
, Attr
);
279 if (getLexer().is(AsmToken::EndOfStatement
))
282 if (getLexer().isNot(AsmToken::Comma
))
283 return TokError("unexpected token in directive");
292 bool COFFAsmParser::ParseSectionSwitch(StringRef Section
,
293 unsigned Characteristics
,
295 return ParseSectionSwitch(Section
, Characteristics
, Kind
, "", (COFF::COMDATType
)0);
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::COMDATType
)0;
360 StringRef COMDATSymName
;
361 if (getLexer().is(AsmToken::Comma
)) {
362 Type
= COFF::IMAGE_COMDAT_SELECT_ANY
;;
365 Flags
|= COFF::IMAGE_SCN_LNK_COMDAT
;
367 if (!getLexer().is(AsmToken::Identifier
))
368 return TokError("expected comdat type such as 'discard' or 'largest' "
369 "after protection bits");
371 if (parseCOMDATType(Type
))
374 if (getLexer().isNot(AsmToken::Comma
))
375 return TokError("expected comma in directive");
378 if (getParser().parseIdentifier(COMDATSymName
))
379 return TokError("expected identifier in directive");
382 if (getLexer().isNot(AsmToken::EndOfStatement
))
383 return TokError("unexpected token in directive");
385 SectionKind Kind
= computeSectionKind(Flags
);
387 const Triple
&T
= getContext().getObjectFileInfo()->getTargetTriple();
388 if (T
.getArch() == Triple::arm
|| T
.getArch() == Triple::thumb
)
389 Flags
|= COFF::IMAGE_SCN_MEM_16BIT
;
391 ParseSectionSwitch(SectionName
, Flags
, Kind
, COMDATSymName
, Type
);
395 bool COFFAsmParser::ParseDirectiveDef(StringRef
, SMLoc
) {
396 StringRef SymbolName
;
398 if (getParser().parseIdentifier(SymbolName
))
399 return TokError("expected identifier in directive");
401 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(SymbolName
);
403 getStreamer().BeginCOFFSymbolDef(Sym
);
409 bool COFFAsmParser::ParseDirectiveScl(StringRef
, SMLoc
) {
410 int64_t SymbolStorageClass
;
411 if (getParser().parseAbsoluteExpression(SymbolStorageClass
))
414 if (getLexer().isNot(AsmToken::EndOfStatement
))
415 return TokError("unexpected token in directive");
418 getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass
);
422 bool COFFAsmParser::ParseDirectiveType(StringRef
, SMLoc
) {
424 if (getParser().parseAbsoluteExpression(Type
))
427 if (getLexer().isNot(AsmToken::EndOfStatement
))
428 return TokError("unexpected token in directive");
431 getStreamer().EmitCOFFSymbolType(Type
);
435 bool COFFAsmParser::ParseDirectiveEndef(StringRef
, SMLoc
) {
437 getStreamer().EndCOFFSymbolDef();
441 bool COFFAsmParser::ParseDirectiveSecRel32(StringRef
, SMLoc
) {
443 if (getParser().parseIdentifier(SymbolID
))
444 return TokError("expected identifier in directive");
446 if (getLexer().isNot(AsmToken::EndOfStatement
))
447 return TokError("unexpected token in directive");
449 MCSymbol
*Symbol
= getContext().GetOrCreateSymbol(SymbolID
);
452 getStreamer().EmitCOFFSecRel32(Symbol
);
456 bool COFFAsmParser::ParseDirectiveSecIdx(StringRef
, SMLoc
) {
458 if (getParser().parseIdentifier(SymbolID
))
459 return TokError("expected identifier in directive");
461 if (getLexer().isNot(AsmToken::EndOfStatement
))
462 return TokError("unexpected token in directive");
464 MCSymbol
*Symbol
= getContext().GetOrCreateSymbol(SymbolID
);
467 getStreamer().EmitCOFFSectionIndex(Symbol
);
471 /// ::= [ identifier ]
472 bool COFFAsmParser::parseCOMDATType(COFF::COMDATType
&Type
) {
473 StringRef TypeId
= getTok().getIdentifier();
475 Type
= StringSwitch
<COFF::COMDATType
>(TypeId
)
476 .Case("one_only", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES
)
477 .Case("discard", COFF::IMAGE_COMDAT_SELECT_ANY
)
478 .Case("same_size", COFF::IMAGE_COMDAT_SELECT_SAME_SIZE
)
479 .Case("same_contents", COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH
)
480 .Case("associative", COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE
)
481 .Case("largest", COFF::IMAGE_COMDAT_SELECT_LARGEST
)
482 .Case("newest", COFF::IMAGE_COMDAT_SELECT_NEWEST
)
483 .Default((COFF::COMDATType
)0);
486 return TokError(Twine("unrecognized COMDAT type '" + TypeId
+ "'"));
493 /// ParseDirectiveLinkOnce
494 /// ::= .linkonce [ identifier ]
495 bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef
, SMLoc Loc
) {
496 COFF::COMDATType Type
= COFF::IMAGE_COMDAT_SELECT_ANY
;
497 if (getLexer().is(AsmToken::Identifier
))
498 if (parseCOMDATType(Type
))
501 const MCSectionCOFF
*Current
= static_cast<const MCSectionCOFF
*>(
502 getStreamer().getCurrentSection().first
);
504 if (Type
== COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE
)
505 return Error(Loc
, "cannot make section associative with .linkonce");
507 if (Current
->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT
)
508 return Error(Loc
, Twine("section '") + Current
->getSectionName() +
509 "' is already linkonce");
511 Current
->setSelection(Type
);
513 if (getLexer().isNot(AsmToken::EndOfStatement
))
514 return TokError("unexpected token in directive");
519 bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef
, SMLoc
) {
521 if (getParser().parseIdentifier(SymbolID
))
524 if (getLexer().isNot(AsmToken::EndOfStatement
))
525 return TokError("unexpected token in directive");
527 MCSymbol
*Symbol
= getContext().GetOrCreateSymbol(SymbolID
);
530 getStreamer().EmitWinCFIStartProc(Symbol
);
534 bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef
, SMLoc
) {
536 getStreamer().EmitWinCFIEndProc();
540 bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef
, SMLoc
) {
542 getStreamer().EmitWinCFIStartChained();
546 bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef
, SMLoc
) {
548 getStreamer().EmitWinCFIEndChained();
552 bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef
, SMLoc
) {
554 if (getParser().parseIdentifier(SymbolID
))
557 if (getLexer().isNot(AsmToken::Comma
))
558 return TokError("you must specify one or both of @unwind or @except");
560 bool unwind
= false, except
= false;
561 if (ParseAtUnwindOrAtExcept(unwind
, except
))
563 if (getLexer().is(AsmToken::Comma
)) {
565 if (ParseAtUnwindOrAtExcept(unwind
, except
))
568 if (getLexer().isNot(AsmToken::EndOfStatement
))
569 return TokError("unexpected token in directive");
571 MCSymbol
*handler
= getContext().GetOrCreateSymbol(SymbolID
);
574 getStreamer().EmitWinEHHandler(handler
, unwind
, except
);
578 bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef
, SMLoc
) {
580 getStreamer().EmitWinEHHandlerData();
584 bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef
, SMLoc L
) {
586 if (ParseSEHRegisterNumber(Reg
))
589 if (getLexer().isNot(AsmToken::EndOfStatement
))
590 return TokError("unexpected token in directive");
593 getStreamer().EmitWinCFIPushReg(Reg
);
597 bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef
, SMLoc L
) {
600 if (ParseSEHRegisterNumber(Reg
))
602 if (getLexer().isNot(AsmToken::Comma
))
603 return TokError("you must specify a stack pointer offset");
606 SMLoc startLoc
= getLexer().getLoc();
607 if (getParser().parseAbsoluteExpression(Off
))
611 return Error(startLoc
, "offset is not a multiple of 16");
613 if (getLexer().isNot(AsmToken::EndOfStatement
))
614 return TokError("unexpected token in directive");
617 getStreamer().EmitWinCFISetFrame(Reg
, Off
);
621 bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef
, SMLoc
) {
623 SMLoc startLoc
= getLexer().getLoc();
624 if (getParser().parseAbsoluteExpression(Size
))
628 return Error(startLoc
, "size is not a multiple of 8");
630 if (getLexer().isNot(AsmToken::EndOfStatement
))
631 return TokError("unexpected token in directive");
634 getStreamer().EmitWinCFIAllocStack(Size
);
638 bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef
, SMLoc L
) {
641 if (ParseSEHRegisterNumber(Reg
))
643 if (getLexer().isNot(AsmToken::Comma
))
644 return TokError("you must specify an offset on the stack");
647 SMLoc startLoc
= getLexer().getLoc();
648 if (getParser().parseAbsoluteExpression(Off
))
652 return Error(startLoc
, "size is not a multiple of 8");
654 if (getLexer().isNot(AsmToken::EndOfStatement
))
655 return TokError("unexpected token in directive");
658 // FIXME: Err on %xmm* registers
659 getStreamer().EmitWinCFISaveReg(Reg
, Off
);
663 // FIXME: This method is inherently x86-specific. It should really be in the
665 bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef
, SMLoc L
) {
668 if (ParseSEHRegisterNumber(Reg
))
670 if (getLexer().isNot(AsmToken::Comma
))
671 return TokError("you must specify an offset on the stack");
674 SMLoc startLoc
= getLexer().getLoc();
675 if (getParser().parseAbsoluteExpression(Off
))
678 if (getLexer().isNot(AsmToken::EndOfStatement
))
679 return TokError("unexpected token in directive");
682 return Error(startLoc
, "offset is not a multiple of 16");
685 // FIXME: Err on non-%xmm* registers
686 getStreamer().EmitWinCFISaveXMM(Reg
, Off
);
690 bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef
, SMLoc
) {
693 if (getLexer().is(AsmToken::At
)) {
694 SMLoc startLoc
= getLexer().getLoc();
696 if (!getParser().parseIdentifier(CodeID
)) {
697 if (CodeID
!= "code")
698 return Error(startLoc
, "expected @code");
703 if (getLexer().isNot(AsmToken::EndOfStatement
))
704 return TokError("unexpected token in directive");
707 getStreamer().EmitWinCFIPushFrame(Code
);
711 bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef
, SMLoc
) {
713 getStreamer().EmitWinCFIEndProlog();
717 bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind
, bool &except
) {
718 StringRef identifier
;
719 if (getLexer().isNot(AsmToken::At
))
720 return TokError("a handler attribute must begin with '@'");
721 SMLoc startLoc
= getLexer().getLoc();
723 if (getParser().parseIdentifier(identifier
))
724 return Error(startLoc
, "expected @unwind or @except");
725 if (identifier
== "unwind")
727 else if (identifier
== "except")
730 return Error(startLoc
, "expected @unwind or @except");
734 bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo
) {
735 SMLoc startLoc
= getLexer().getLoc();
736 if (getLexer().is(AsmToken::Percent
)) {
737 const MCRegisterInfo
*MRI
= getContext().getRegisterInfo();
740 if (getParser().getTargetParser().ParseRegister(LLVMRegNo
,startLoc
,endLoc
))
744 // FIXME: TargetAsmInfo::getCalleeSavedRegs() commits a serious layering
745 // violation so this validation code is disabled.
747 // Check that this is a non-volatile register.
748 const unsigned *NVRegs
= TAI
.getCalleeSavedRegs();
750 for (i
= 0; NVRegs
[i
] != 0; ++i
)
751 if (NVRegs
[i
] == LLVMRegNo
)
754 return Error(startLoc
, "expected non-volatile register");
757 int SEHRegNo
= MRI
->getSEHRegNum(LLVMRegNo
);
759 return Error(startLoc
,"register can't be represented in SEH unwind info");
764 if (getParser().parseAbsoluteExpression(n
))
767 return Error(startLoc
, "register number is too high");
776 MCAsmParserExtension
*createCOFFAsmParser() {
777 return new COFFAsmParser
;