27 template<
bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
28 void addDirectiveHandler(
StringRef Directive) {
30 this, HandleDirective<COFFAsmParser, HandlerMethod>);
31 getParser().addDirectiveHandler(Directive, Handler);
38 bool ParseSectionName(
StringRef &SectionName);
45 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(
".text");
46 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(
".data");
47 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(
".bss");
48 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(
".section");
49 addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(
".def");
50 addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(
".scl");
51 addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(
".type");
52 addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(
".endef");
53 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(
".secrel32");
54 addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(
".linkonce");
57 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
59 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
61 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
63 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
65 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
67 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
69 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
71 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
73 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
75 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
77 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
79 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
81 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
83 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(
".weak");
87 return ParseSectionSwitch(
".text",
88 COFF::IMAGE_SCN_CNT_CODE
89 | COFF::IMAGE_SCN_MEM_EXECUTE
90 | COFF::IMAGE_SCN_MEM_READ,
94 return ParseSectionSwitch(
".data",
95 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
96 | COFF::IMAGE_SCN_MEM_READ
97 | COFF::IMAGE_SCN_MEM_WRITE,
101 return ParseSectionSwitch(
".bss",
102 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
103 | COFF::IMAGE_SCN_MEM_READ
104 | COFF::IMAGE_SCN_MEM_WRITE,
131 bool ParseAtUnwindOrAtExcept(
bool &unwind,
bool &except);
132 bool ParseSEHRegisterNumber(
unsigned &RegNo);
141 if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
143 if (Flags & COFF::IMAGE_SCN_MEM_READ &&
144 (Flags & COFF::IMAGE_SCN_MEM_WRITE) == 0)
149 bool COFFAsmParser::ParseSectionFlags(
StringRef FlagsString,
unsigned*
Flags) {
162 bool ReadOnlyRemoved =
false;
163 unsigned SecFlags =
None;
165 for (
unsigned i = 0; i < FlagsString.
size(); ++i) {
166 switch (FlagsString[i]) {
173 if (SecFlags & InitData)
174 return TokError(
"conflicting section flags 'b' and 'd'.");
179 SecFlags |= InitData;
180 if (SecFlags & Alloc)
181 return TokError(
"conflicting section flags 'b' and 'd'.");
182 SecFlags &= ~NoWrite;
183 if ((SecFlags & NoLoad) == 0)
193 ReadOnlyRemoved =
false;
195 if ((SecFlags &
Code) == 0)
196 SecFlags |= InitData;
197 if ((SecFlags & NoLoad) == 0)
202 SecFlags |= Shared | InitData;
203 SecFlags &= ~NoWrite;
204 if ((SecFlags & NoLoad) == 0)
209 SecFlags &= ~NoWrite;
210 ReadOnlyRemoved =
true;
215 if ((SecFlags & NoLoad) == 0)
217 if (!ReadOnlyRemoved)
222 SecFlags |= NoRead | NoWrite;
226 return TokError(
"unknown flag");
232 if (SecFlags ==
None)
236 *Flags |= COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE;
237 if (SecFlags & InitData)
238 *Flags |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
239 if ((SecFlags & Alloc) && (SecFlags &
Load) == 0)
240 *Flags |= COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
241 if (SecFlags & NoLoad)
242 *Flags |= COFF::IMAGE_SCN_LNK_REMOVE;
243 if ((SecFlags & NoRead) == 0)
244 *Flags |= COFF::IMAGE_SCN_MEM_READ;
245 if ((SecFlags & NoWrite) == 0)
246 *Flags |= COFF::IMAGE_SCN_MEM_WRITE;
247 if (SecFlags & Shared)
248 *Flags |= COFF::IMAGE_SCN_MEM_SHARED;
255 bool COFFAsmParser::ParseDirectiveSymbolAttribute(
StringRef Directive,
SMLoc) {
259 assert(Attr !=
MCSA_Invalid &&
"unexpected symbol attribute directive!");
264 if (getParser().parseIdentifier(Name))
265 return TokError(
"expected identifier in directive");
267 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
269 getStreamer().EmitSymbolAttribute(Sym, Attr);
275 return TokError(
"unexpected token in directive");
288 return TokError(
"unexpected token in section switching directive");
291 getStreamer().SwitchSection(getContext().getCOFFSection(
292 Section, Characteristics, Kind));
297 bool COFFAsmParser::ParseSectionName(
StringRef &SectionName) {
301 SectionName = getTok().getIdentifier();
323 if (ParseSectionName(SectionName))
324 return TokError(
"expected identifier in directive");
326 unsigned Flags = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
327 COFF::IMAGE_SCN_MEM_READ |
328 COFF::IMAGE_SCN_MEM_WRITE;
334 return TokError(
"expected string in directive");
336 StringRef FlagsStr = getTok().getStringContents();
339 if (ParseSectionFlags(FlagsStr, &Flags))
344 return TokError(
"unexpected token in directive");
347 ParseSectionSwitch(SectionName, Flags, Kind);
354 if (getParser().parseIdentifier(SymbolName))
355 return TokError(
"expected identifier in directive");
357 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
359 getStreamer().BeginCOFFSymbolDef(Sym);
367 if (getParser().parseAbsoluteExpression(SymbolStorageClass))
371 return TokError(
"unexpected token in directive");
374 getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
380 if (getParser().parseAbsoluteExpression(Type))
384 return TokError(
"unexpected token in directive");
387 getStreamer().EmitCOFFSymbolType(Type);
393 getStreamer().EndCOFFSymbolDef();
399 if (getParser().parseIdentifier(SymbolID))
403 return TokError(
"unexpected token in directive");
408 getStreamer().EmitCOFFSecRel32(Symbol);
414 bool COFFAsmParser::ParseDirectiveLinkOnce(
StringRef,
SMLoc Loc) {
418 StringRef TypeId = getTok().getIdentifier();
431 return TokError(
Twine(
"unrecognized COMDAT type '" + TypeId +
"'"));
437 getStreamer().getCurrentSection().first);
442 SMLoc Loc = getTok().getLoc();
443 if (ParseSectionName(AssocName))
444 return TokError(
"expected associated section name");
447 getContext().getCOFFSection(AssocName));
449 return Error(Loc,
"cannot associate unknown section '" + AssocName +
"'");
450 if (Assoc == Current)
451 return Error(Loc,
"cannot associate a section with itself");
453 return Error(Loc,
"associated section must be a COMDAT section");
455 return Error(Loc,
"associated section cannot be itself associative");
460 "' is already linkonce");
465 return TokError(
"unexpected token in directive");
470 bool COFFAsmParser::ParseSEHDirectiveStartProc(
StringRef,
SMLoc) {
472 if (getParser().parseIdentifier(SymbolID))
476 return TokError(
"unexpected token in directive");
478 MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);
481 getStreamer().EmitWin64EHStartProc(Symbol);
487 getStreamer().EmitWin64EHEndProc();
491 bool COFFAsmParser::ParseSEHDirectiveStartChained(
StringRef,
SMLoc) {
493 getStreamer().EmitWin64EHStartChained();
497 bool COFFAsmParser::ParseSEHDirectiveEndChained(
StringRef,
SMLoc) {
499 getStreamer().EmitWin64EHEndChained();
505 if (getParser().parseIdentifier(SymbolID))
509 return TokError(
"you must specify one or both of @unwind or @except");
511 bool unwind =
false, except =
false;
512 if (ParseAtUnwindOrAtExcept(unwind, except))
516 if (ParseAtUnwindOrAtExcept(unwind, except))
520 return TokError(
"unexpected token in directive");
522 MCSymbol *handler = getContext().GetOrCreateSymbol(SymbolID);
525 getStreamer().EmitWin64EHHandler(handler, unwind, except);
529 bool COFFAsmParser::ParseSEHDirectiveHandlerData(
StringRef,
SMLoc) {
531 getStreamer().EmitWin64EHHandlerData();
535 bool COFFAsmParser::ParseSEHDirectivePushReg(
StringRef,
SMLoc L) {
537 if (ParseSEHRegisterNumber(Reg))
541 return TokError(
"unexpected token in directive");
544 getStreamer().EmitWin64EHPushReg(Reg);
548 bool COFFAsmParser::ParseSEHDirectiveSetFrame(
StringRef,
SMLoc L) {
551 if (ParseSEHRegisterNumber(Reg))
554 return TokError(
"you must specify a stack pointer offset");
557 SMLoc startLoc = getLexer().getLoc();
558 if (getParser().parseAbsoluteExpression(Off))
562 return Error(startLoc,
"offset is not a multiple of 16");
565 return TokError(
"unexpected token in directive");
568 getStreamer().EmitWin64EHSetFrame(Reg, Off);
572 bool COFFAsmParser::ParseSEHDirectiveAllocStack(
StringRef,
SMLoc) {
574 SMLoc startLoc = getLexer().getLoc();
575 if (getParser().parseAbsoluteExpression(Size))
579 return Error(startLoc,
"size is not a multiple of 8");
582 return TokError(
"unexpected token in directive");
585 getStreamer().EmitWin64EHAllocStack(Size);
589 bool COFFAsmParser::ParseSEHDirectiveSaveReg(
StringRef,
SMLoc L) {
592 if (ParseSEHRegisterNumber(Reg))
595 return TokError(
"you must specify an offset on the stack");
598 SMLoc startLoc = getLexer().getLoc();
599 if (getParser().parseAbsoluteExpression(Off))
603 return Error(startLoc,
"size is not a multiple of 8");
606 return TokError(
"unexpected token in directive");
610 getStreamer().EmitWin64EHSaveReg(Reg, Off);
616 bool COFFAsmParser::ParseSEHDirectiveSaveXMM(
StringRef,
SMLoc L) {
619 if (ParseSEHRegisterNumber(Reg))
622 return TokError(
"you must specify an offset on the stack");
625 SMLoc startLoc = getLexer().getLoc();
626 if (getParser().parseAbsoluteExpression(Off))
630 return TokError(
"unexpected token in directive");
633 return Error(startLoc,
"offset is not a multiple of 16");
637 getStreamer().EmitWin64EHSaveXMM(Reg, Off);
641 bool COFFAsmParser::ParseSEHDirectivePushFrame(
StringRef,
SMLoc) {
645 SMLoc startLoc = getLexer().getLoc();
647 if (!getParser().parseIdentifier(CodeID)) {
648 if (CodeID !=
"code")
649 return Error(startLoc,
"expected @code");
655 return TokError(
"unexpected token in directive");
658 getStreamer().EmitWin64EHPushFrame(Code);
662 bool COFFAsmParser::ParseSEHDirectiveEndProlog(
StringRef,
SMLoc) {
664 getStreamer().EmitWin64EHEndProlog();
668 bool COFFAsmParser::ParseAtUnwindOrAtExcept(
bool &unwind,
bool &except) {
671 return TokError(
"a handler attribute must begin with '@'");
672 SMLoc startLoc = getLexer().getLoc();
674 if (getParser().parseIdentifier(identifier))
675 return Error(startLoc,
"expected @unwind or @except");
676 if (identifier ==
"unwind")
678 else if (identifier ==
"except")
681 return Error(startLoc,
"expected @unwind or @except");
685 bool COFFAsmParser::ParseSEHRegisterNumber(
unsigned &RegNo) {
686 SMLoc startLoc = getLexer().getLoc();
691 if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
699 const unsigned *NVRegs = TAI.getCalleeSavedRegs();
701 for (i = 0; NVRegs[i] != 0; ++i)
702 if (NVRegs[i] == LLVMRegNo)
705 return Error(startLoc,
"expected non-volatile register");
710 return Error(startLoc,
"register can't be represented in SEH unwind info");
715 if (getParser().parseAbsoluteExpression(n))
718 return Error(startLoc,
"register number is too high");
728 return new COFFAsmParser;
COFF::RelocationTypeX86 Type
size_t size() const
size - Get the string size.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser. The extension should use the AsmParser i...
static SectionKind getDataRel()
StringSwitch & Case(const char(&S)[N], const T &Value)
static SectionKind computeSectionKind(unsigned Flags)
MCSectionCOFF - This represents a section on Windows.
static SectionKind getBSS()
int getSEHRegNum(unsigned RegNum) const
Map a target register to an equivalent SEH register number. Returns LLVM register number if there is ...
A switch()-like statement whose cases are string literals.
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
MCAsmParserExtension * createCOFFAsmParser()
unsigned getCharacteristics() const
StringRef getSectionName() const
R Default(const T &Value) const
SymbolStorageClass
Storage class tells where and what the symbol represents.
void setSelection(int Selection, const MCSectionCOFF *Assoc=0) const
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
const MCRegisterInfo & MRI
COFF::SectionCharacteristics Characteristics
Represents a location in source code.
static SectionKind getReadOnly()
static SectionKind getText()