28 template<
bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
29 void addDirectiveHandler(
StringRef Directive) {
31 this, HandleDirective<COFFAsmParser, HandlerMethod>);
32 getParser().addDirectiveHandler(Directive, Handler);
51 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(
".text");
52 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(
".data");
53 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(
".bss");
54 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(
".section");
55 addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(
".def");
56 addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(
".scl");
57 addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(
".type");
58 addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(
".endef");
59 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(
".secrel32");
60 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(
".secidx");
61 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSafeSEH>(
".safeseh");
62 addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(
".linkonce");
65 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
67 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
69 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
71 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
73 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
75 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
77 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
79 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
81 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
83 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
85 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
87 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
89 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
91 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(
".weak");
95 return ParseSectionSwitch(
".text",
108 return ParseSectionSwitch(
".bss",
141 bool ParseAtUnwindOrAtExcept(
bool &unwind,
bool &except);
142 bool ParseSEHRegisterNumber(
unsigned &RegNo);
171 Discardable = 1 << 8,
174 bool ReadOnlyRemoved =
false;
175 unsigned SecFlags =
None;
177 for (
char FlagChar : FlagsString) {
185 if (SecFlags & InitData)
186 return TokError(
"conflicting section flags 'b' and 'd'.");
191 SecFlags |= InitData;
192 if (SecFlags & Alloc)
193 return TokError(
"conflicting section flags 'b' and 'd'.");
194 SecFlags &= ~NoWrite;
195 if ((SecFlags & NoLoad) == 0)
205 SecFlags |= Discardable;
209 ReadOnlyRemoved =
false;
211 if ((SecFlags & Code) == 0)
212 SecFlags |= InitData;
213 if ((SecFlags & NoLoad) == 0)
218 SecFlags |= Shared | InitData;
219 SecFlags &= ~NoWrite;
220 if ((SecFlags & NoLoad) == 0)
225 SecFlags &= ~NoWrite;
226 ReadOnlyRemoved =
true;
231 if ((SecFlags & NoLoad) == 0)
233 if (!ReadOnlyRemoved)
238 SecFlags |= NoRead | NoWrite;
242 return TokError(
"unknown flag");
248 if (SecFlags ==
None)
253 if (SecFlags & InitData)
255 if ((SecFlags & Alloc) && (SecFlags &
Load) == 0)
257 if (SecFlags & NoLoad)
259 if ((SecFlags & Discardable) ||
262 if ((SecFlags & NoRead) == 0)
264 if ((SecFlags & NoWrite) == 0)
266 if (SecFlags & Shared)
274 bool COFFAsmParser::ParseDirectiveSymbolAttribute(
StringRef Directive,
SMLoc) {
283 if (getParser().parseIdentifier(Name))
284 return TokError(
"expected identifier in directive");
286 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
288 getStreamer().EmitSymbolAttribute(Sym, Attr);
294 return TokError(
"unexpected token in directive");
306 return ParseSectionSwitch(Section, Characteristics, Kind,
"", (
COFF::COMDATType)0);
309 bool COFFAsmParser::ParseSectionSwitch(
StringRef Section,
310 unsigned Characteristics,
315 return TokError(
"unexpected token in section switching directive");
318 getStreamer().SwitchSection(getContext().getCOFFSection(
319 Section, Characteristics, Kind, COMDATSymName, Type));
324 bool COFFAsmParser::ParseSectionName(
StringRef &SectionName) {
328 SectionName = getTok().getIdentifier();
351 if (ParseSectionName(SectionName))
352 return TokError(
"expected identifier in directive");
362 return TokError(
"expected string in directive");
364 StringRef FlagsStr = getTok().getStringContents();
367 if (ParseSectionFlags(SectionName, FlagsStr, &Flags))
380 return TokError(
"expected comdat type such as 'discard' or 'largest' "
381 "after protection bits");
383 if (parseCOMDATType(Type))
387 return TokError(
"expected comma in directive");
390 if (getParser().parseIdentifier(COMDATSymName))
391 return TokError(
"expected identifier in directive");
395 return TokError(
"unexpected token in directive");
399 const Triple &
T = getContext().getObjectFileInfo()->getTargetTriple();
403 ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type);
410 if (getParser().parseIdentifier(SymbolName))
411 return TokError(
"expected identifier in directive");
413 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
415 getStreamer().BeginCOFFSymbolDef(Sym);
423 if (getParser().parseAbsoluteExpression(SymbolStorageClass))
427 return TokError(
"unexpected token in directive");
430 getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
436 if (getParser().parseAbsoluteExpression(Type))
440 return TokError(
"unexpected token in directive");
443 getStreamer().EmitCOFFSymbolType(Type);
449 getStreamer().EndCOFFSymbolDef();
455 if (getParser().parseIdentifier(SymbolID))
456 return TokError(
"expected identifier in directive");
461 OffsetLoc = getLexer().getLoc();
462 if (getParser().parseAbsoluteExpression(Offset))
467 return TokError(
"unexpected token in directive");
469 if (Offset < 0 || Offset > UINT32_MAX)
470 return Error(OffsetLoc,
471 "invalid '.secrel32' directive offset, can't be less "
472 "than zero or greater than UINT32_MAX");
477 getStreamer().EmitCOFFSecRel32(Symbol, Offset);
483 if (getParser().parseIdentifier(SymbolID))
484 return TokError(
"expected identifier in directive");
487 return TokError(
"unexpected token in directive");
489 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
492 getStreamer().EmitCOFFSafeSEH(Symbol);
498 if (getParser().parseIdentifier(SymbolID))
499 return TokError(
"expected identifier in directive");
502 return TokError(
"unexpected token in directive");
504 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
507 getStreamer().EmitCOFFSectionIndex(Symbol);
513 StringRef TypeId = getTok().getIdentifier();
526 return TokError(
Twine(
"unrecognized COMDAT type '" + TypeId +
"'"));
535 bool COFFAsmParser::ParseDirectiveLinkOnce(
StringRef,
SMLoc Loc) {
538 if (parseCOMDATType(Type))
542 static_cast<const MCSectionCOFF *
>(getStreamer().getCurrentSectionOnly());
545 return Error(Loc,
"cannot make section associative with .linkonce");
549 "' is already linkonce");
554 return TokError(
"unexpected token in directive");
559 bool COFFAsmParser::ParseSEHDirectiveStartProc(
StringRef,
SMLoc) {
561 if (getParser().parseIdentifier(SymbolID))
565 return TokError(
"unexpected token in directive");
567 MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
570 getStreamer().EmitWinCFIStartProc(Symbol);
576 getStreamer().EmitWinCFIEndProc();
580 bool COFFAsmParser::ParseSEHDirectiveStartChained(
StringRef,
SMLoc) {
582 getStreamer().EmitWinCFIStartChained();
586 bool COFFAsmParser::ParseSEHDirectiveEndChained(
StringRef,
SMLoc) {
588 getStreamer().EmitWinCFIEndChained();
594 if (getParser().parseIdentifier(SymbolID))
598 return TokError(
"you must specify one or both of @unwind or @except");
600 bool unwind =
false, except =
false;
601 if (ParseAtUnwindOrAtExcept(unwind, except))
605 if (ParseAtUnwindOrAtExcept(unwind, except))
609 return TokError(
"unexpected token in directive");
611 MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID);
614 getStreamer().EmitWinEHHandler(handler, unwind, except);
618 bool COFFAsmParser::ParseSEHDirectiveHandlerData(
StringRef,
SMLoc) {
620 getStreamer().EmitWinEHHandlerData();
626 if (ParseSEHRegisterNumber(Reg))
630 return TokError(
"unexpected token in directive");
633 getStreamer().EmitWinCFIPushReg(Reg);
637 bool COFFAsmParser::ParseSEHDirectiveSetFrame(
StringRef,
SMLoc L) {
640 if (ParseSEHRegisterNumber(Reg))
643 return TokError(
"you must specify a stack pointer offset");
646 SMLoc startLoc = getLexer().getLoc();
647 if (getParser().parseAbsoluteExpression(Off))
651 return Error(startLoc,
"offset is not a multiple of 16");
654 return TokError(
"unexpected token in directive");
657 getStreamer().EmitWinCFISetFrame(Reg, Off);
661 bool COFFAsmParser::ParseSEHDirectiveAllocStack(
StringRef,
SMLoc) {
663 SMLoc startLoc = getLexer().getLoc();
664 if (getParser().parseAbsoluteExpression(Size))
668 return Error(startLoc,
"size is not a multiple of 8");
671 return TokError(
"unexpected token in directive");
674 getStreamer().EmitWinCFIAllocStack(Size);
678 bool COFFAsmParser::ParseSEHDirectiveSaveReg(
StringRef,
SMLoc L) {
681 if (ParseSEHRegisterNumber(Reg))
684 return TokError(
"you must specify an offset on the stack");
687 SMLoc startLoc = getLexer().getLoc();
688 if (getParser().parseAbsoluteExpression(Off))
692 return Error(startLoc,
"size is not a multiple of 8");
695 return TokError(
"unexpected token in directive");
699 getStreamer().EmitWinCFISaveReg(Reg, Off);
705 bool COFFAsmParser::ParseSEHDirectiveSaveXMM(
StringRef,
SMLoc L) {
708 if (ParseSEHRegisterNumber(Reg))
711 return TokError(
"you must specify an offset on the stack");
714 SMLoc startLoc = getLexer().getLoc();
715 if (getParser().parseAbsoluteExpression(Off))
719 return TokError(
"unexpected token in directive");
722 return Error(startLoc,
"offset is not a multiple of 16");
726 getStreamer().EmitWinCFISaveXMM(Reg, Off);
730 bool COFFAsmParser::ParseSEHDirectivePushFrame(
StringRef,
SMLoc) {
734 SMLoc startLoc = getLexer().getLoc();
736 if (!getParser().parseIdentifier(CodeID)) {
737 if (CodeID !=
"code")
738 return Error(startLoc,
"expected @code");
744 return TokError(
"unexpected token in directive");
747 getStreamer().EmitWinCFIPushFrame(Code);
751 bool COFFAsmParser::ParseSEHDirectiveEndProlog(
StringRef,
SMLoc) {
753 getStreamer().EmitWinCFIEndProlog();
757 bool COFFAsmParser::ParseAtUnwindOrAtExcept(
bool &unwind,
bool &except) {
760 return TokError(
"a handler attribute must begin with '@'");
761 SMLoc startLoc = getLexer().getLoc();
763 if (getParser().parseIdentifier(identifier))
764 return Error(startLoc,
"expected @unwind or @except");
765 if (identifier ==
"unwind")
767 else if (identifier ==
"except")
770 return Error(startLoc,
"expected @unwind or @except");
774 bool COFFAsmParser::ParseSEHRegisterNumber(
unsigned &RegNo) {
775 SMLoc startLoc = getLexer().getLoc();
780 if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
788 const unsigned *NVRegs = TAI.getCalleeSavedRegs();
790 for (i = 0; NVRegs[
i] != 0; ++
i)
791 if (NVRegs[i] == LLVMRegNo)
794 return Error(startLoc,
"expected non-volatile register");
799 return Error(startLoc,
"register can't be represented in SEH unwind info");
804 if (getParser().parseAbsoluteExpression(n))
807 return Error(startLoc,
"register number is too high");
817 return new COFFAsmParser;
static SectionKind getData()
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.
void setSelection(int Selection) const
static SectionKind computeSectionKind(unsigned Flags)
This represents a section on Windows.
static SectionKind getBSS()
struct fuzzer::@269 Flags
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
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.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
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.
unsigned const MachineRegisterInfo * MRI
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
SymbolStorageClass
Storage class tells where and what the symbol represents.
COFFYAML::WeakExternalCharacteristics Characteristics
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImplicitlyDiscardable(StringRef Name)
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()