28 template<
bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
29 void addDirectiveHandler(
StringRef Directive) {
31 this, HandleDirective<COFFAsmParser, HandlerMethod>);
32 getParser().addDirectiveHandler(Directive, Handler);
43 bool ParseSectionName(
StringRef &SectionName);
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::ParseDirectiveSafeSEH>(
".safeseh");
61 addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(
".linkonce");
64 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
66 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
68 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
70 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
72 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
74 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
76 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
78 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
80 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
82 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
84 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
86 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
88 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
90 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(
".weak");
94 return ParseSectionSwitch(
".text",
101 return ParseSectionSwitch(
".data",
108 return ParseSectionSwitch(
".bss",
141 bool ParseAtUnwindOrAtExcept(
bool &unwind,
bool &except);
142 bool ParseSEHRegisterNumber(
unsigned &RegNo);
159 bool COFFAsmParser::ParseSectionFlags(
StringRef FlagsString,
unsigned*
Flags) {
172 bool ReadOnlyRemoved =
false;
173 unsigned SecFlags =
None;
175 for (
char FlagChar : FlagsString) {
183 if (SecFlags & InitData)
184 return TokError(
"conflicting section flags 'b' and 'd'.");
189 SecFlags |= InitData;
190 if (SecFlags & Alloc)
191 return TokError(
"conflicting section flags 'b' and 'd'.");
192 SecFlags &= ~NoWrite;
193 if ((SecFlags & NoLoad) == 0)
203 ReadOnlyRemoved =
false;
205 if ((SecFlags & Code) == 0)
206 SecFlags |= InitData;
207 if ((SecFlags & NoLoad) == 0)
212 SecFlags |= Shared | InitData;
213 SecFlags &= ~NoWrite;
214 if ((SecFlags & NoLoad) == 0)
219 SecFlags &= ~NoWrite;
220 ReadOnlyRemoved =
true;
225 if ((SecFlags & NoLoad) == 0)
227 if (!ReadOnlyRemoved)
232 SecFlags |= NoRead | NoWrite;
236 return TokError(
"unknown flag");
242 if (SecFlags ==
None)
247 if (SecFlags & InitData)
249 if ((SecFlags & Alloc) && (SecFlags &
Load) == 0)
251 if (SecFlags & NoLoad)
253 if ((SecFlags & NoRead) == 0)
255 if ((SecFlags & NoWrite) == 0)
257 if (SecFlags & Shared)
265 bool COFFAsmParser::ParseDirectiveSymbolAttribute(
StringRef Directive,
SMLoc) {
269 assert(Attr !=
MCSA_Invalid &&
"unexpected symbol attribute directive!");
274 if (getParser().parseIdentifier(Name))
275 return TokError(
"expected identifier in directive");
277 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
279 getStreamer().EmitSymbolAttribute(Sym, Attr);
285 return TokError(
"unexpected token in directive");
297 return ParseSectionSwitch(Section, Characteristics, Kind,
"", (
COFF::COMDATType)0);
300 bool COFFAsmParser::ParseSectionSwitch(
StringRef Section,
301 unsigned Characteristics,
306 return TokError(
"unexpected token in section switching directive");
309 getStreamer().SwitchSection(getContext().getCOFFSection(
310 Section, Characteristics, Kind, COMDATSymName, Type));
315 bool COFFAsmParser::ParseSectionName(
StringRef &SectionName) {
319 SectionName = getTok().getIdentifier();
341 if (ParseSectionName(SectionName))
342 return TokError(
"expected identifier in directive");
352 return TokError(
"expected string in directive");
354 StringRef FlagsStr = getTok().getStringContents();
357 if (ParseSectionFlags(FlagsStr, &Flags))
370 return TokError(
"expected comdat type such as 'discard' or 'largest' "
371 "after protection bits");
373 if (parseCOMDATType(Type))
377 return TokError(
"expected comma in directive");
380 if (getParser().parseIdentifier(COMDATSymName))
381 return TokError(
"expected identifier in directive");
385 return TokError(
"unexpected token in directive");
389 const Triple &
T = getContext().getObjectFileInfo()->getTargetTriple();
393 ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type);
400 if (getParser().parseIdentifier(SymbolName))
401 return TokError(
"expected identifier in directive");
403 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
405 getStreamer().BeginCOFFSymbolDef(Sym);
413 if (getParser().parseAbsoluteExpression(SymbolStorageClass))
417 return TokError(
"unexpected token in directive");
420 getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
426 if (getParser().parseAbsoluteExpression(Type))
430 return TokError(
"unexpected token in directive");
433 getStreamer().EmitCOFFSymbolType(Type);
439 getStreamer().EndCOFFSymbolDef();
445 if (getParser().parseIdentifier(SymbolID))
446 return TokError(
"expected identifier in directive");
449 return TokError(
"unexpected token in directive");
454 getStreamer().EmitCOFFSecRel32(Symbol);
460 if (getParser().parseIdentifier(SymbolID))
461 return TokError(
"expected identifier in directive");
464 return TokError(
"unexpected token in directive");
466 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
469 getStreamer().EmitCOFFSafeSEH(Symbol);
475 if (getParser().parseIdentifier(SymbolID))
476 return TokError(
"expected identifier in directive");
479 return TokError(
"unexpected token in directive");
481 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
484 getStreamer().EmitCOFFSectionIndex(Symbol);
490 StringRef TypeId = getTok().getIdentifier();
503 return TokError(
Twine(
"unrecognized COMDAT type '" + TypeId +
"'"));
512 bool COFFAsmParser::ParseDirectiveLinkOnce(
StringRef,
SMLoc Loc) {
515 if (parseCOMDATType(Type))
519 getStreamer().getCurrentSection().first);
522 return Error(Loc,
"cannot make section associative with .linkonce");
526 "' is already linkonce");
531 return TokError(
"unexpected token in directive");
536 bool COFFAsmParser::ParseSEHDirectiveStartProc(
StringRef,
SMLoc) {
538 if (getParser().parseIdentifier(SymbolID))
542 return TokError(
"unexpected token in directive");
544 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
547 getStreamer().EmitWinCFIStartProc(Symbol);
553 getStreamer().EmitWinCFIEndProc();
557 bool COFFAsmParser::ParseSEHDirectiveStartChained(
StringRef,
SMLoc) {
559 getStreamer().EmitWinCFIStartChained();
563 bool COFFAsmParser::ParseSEHDirectiveEndChained(
StringRef,
SMLoc) {
565 getStreamer().EmitWinCFIEndChained();
571 if (getParser().parseIdentifier(SymbolID))
575 return TokError(
"you must specify one or both of @unwind or @except");
577 bool unwind =
false, except =
false;
578 if (ParseAtUnwindOrAtExcept(unwind, except))
582 if (ParseAtUnwindOrAtExcept(unwind, except))
586 return TokError(
"unexpected token in directive");
588 MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID);
591 getStreamer().EmitWinEHHandler(handler, unwind, except);
595 bool COFFAsmParser::ParseSEHDirectiveHandlerData(
StringRef,
SMLoc) {
597 getStreamer().EmitWinEHHandlerData();
601 bool COFFAsmParser::ParseSEHDirectivePushReg(
StringRef,
SMLoc L) {
603 if (ParseSEHRegisterNumber(Reg))
607 return TokError(
"unexpected token in directive");
610 getStreamer().EmitWinCFIPushReg(Reg);
614 bool COFFAsmParser::ParseSEHDirectiveSetFrame(
StringRef,
SMLoc L) {
617 if (ParseSEHRegisterNumber(Reg))
620 return TokError(
"you must specify a stack pointer offset");
623 SMLoc startLoc = getLexer().getLoc();
624 if (getParser().parseAbsoluteExpression(Off))
628 return Error(startLoc,
"offset is not a multiple of 16");
631 return TokError(
"unexpected token in directive");
634 getStreamer().EmitWinCFISetFrame(Reg, Off);
638 bool COFFAsmParser::ParseSEHDirectiveAllocStack(
StringRef,
SMLoc) {
640 SMLoc startLoc = getLexer().getLoc();
641 if (getParser().parseAbsoluteExpression(Size))
645 return Error(startLoc,
"size is not a multiple of 8");
648 return TokError(
"unexpected token in directive");
651 getStreamer().EmitWinCFIAllocStack(Size);
655 bool COFFAsmParser::ParseSEHDirectiveSaveReg(
StringRef,
SMLoc L) {
658 if (ParseSEHRegisterNumber(Reg))
661 return TokError(
"you must specify an offset on the stack");
664 SMLoc startLoc = getLexer().getLoc();
665 if (getParser().parseAbsoluteExpression(Off))
669 return Error(startLoc,
"size is not a multiple of 8");
672 return TokError(
"unexpected token in directive");
676 getStreamer().EmitWinCFISaveReg(Reg, Off);
682 bool COFFAsmParser::ParseSEHDirectiveSaveXMM(
StringRef,
SMLoc L) {
685 if (ParseSEHRegisterNumber(Reg))
688 return TokError(
"you must specify an offset on the stack");
691 SMLoc startLoc = getLexer().getLoc();
692 if (getParser().parseAbsoluteExpression(Off))
696 return TokError(
"unexpected token in directive");
699 return Error(startLoc,
"offset is not a multiple of 16");
703 getStreamer().EmitWinCFISaveXMM(Reg, Off);
707 bool COFFAsmParser::ParseSEHDirectivePushFrame(
StringRef,
SMLoc) {
711 SMLoc startLoc = getLexer().getLoc();
713 if (!getParser().parseIdentifier(CodeID)) {
714 if (CodeID !=
"code")
715 return Error(startLoc,
"expected @code");
721 return TokError(
"unexpected token in directive");
724 getStreamer().EmitWinCFIPushFrame(Code);
728 bool COFFAsmParser::ParseSEHDirectiveEndProlog(
StringRef,
SMLoc) {
730 getStreamer().EmitWinCFIEndProlog();
734 bool COFFAsmParser::ParseAtUnwindOrAtExcept(
bool &unwind,
bool &except) {
737 return TokError(
"a handler attribute must begin with '@'");
738 SMLoc startLoc = getLexer().getLoc();
740 if (getParser().parseIdentifier(identifier))
741 return Error(startLoc,
"expected @unwind or @except");
742 if (identifier ==
"unwind")
744 else if (identifier ==
"except")
747 return Error(startLoc,
"expected @unwind or @except");
751 bool COFFAsmParser::ParseSEHRegisterNumber(
unsigned &RegNo) {
752 SMLoc startLoc = getLexer().getLoc();
757 if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
765 const unsigned *NVRegs = TAI.getCalleeSavedRegs();
767 for (i = 0; NVRegs[i] != 0; ++i)
768 if (NVRegs[i] == LLVMRegNo)
771 return Error(startLoc,
"expected non-volatile register");
776 return Error(startLoc,
"register can't be represented in SEH unwind info");
781 if (getParser().parseAbsoluteExpression(n))
784 return Error(startLoc,
"register number is too high");
794 return new COFFAsmParser;
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static SectionKind getDataRel()
void setSelection(int Selection) const
StringSwitch & Case(const char(&S)[N], const T &Value)
static SectionKind computeSectionKind(unsigned Flags)
MCSectionCOFF - This represents a section on Windows.
static SectionKind getBSS()
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Reg
All possible values of the reg field in the ModR/M byte.
int getSEHRegNum(unsigned RegNum) const
Map a target register to an equivalent SEH register number.
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
A switch()-like statement whose cases are string literals.
The instances of the Type class are immutable: once they are created, they are never changed...
SectionKind - This is a simple POD value that classifies the properties of a section.
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
MCAsmParserExtension * createCOFFAsmParser()
unsigned getCharacteristics() const
Triple - Helper class for working with autoconf configuration names.
StringRef getSectionName() const
R Default(const T &Value) const
SymbolStorageClass
Storage class tells where and what the symbol represents.
COFFYAML::WeakExternalCharacteristics Characteristics
const ARM::ArchExtKind Kind
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
StringRef - Represent a constant reference to a string, i.e.
Represents a location in source code.
static SectionKind getReadOnly()
static SectionKind getText()