36 template<
bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
37 void addDirectiveHandler(
StringRef Directive) {
39 this, HandleDirective<COFFAsmParser, HandlerMethod>);
40 getParser().addDirectiveHandler(Directive, Handler);
59 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(
".text");
60 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(
".data");
61 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(
".bss");
62 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(
".section");
63 addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(
".def");
64 addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(
".scl");
65 addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(
".type");
66 addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(
".endef");
67 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(
".secrel32");
68 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymIdx>(
".symidx");
69 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSafeSEH>(
".safeseh");
70 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(
".secidx");
71 addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(
".linkonce");
72 addDirectiveHandler<&COFFAsmParser::ParseDirectiveRVA>(
".rva");
75 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
77 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
79 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
81 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
83 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
85 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
87 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
89 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
91 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
93 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
95 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
97 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
99 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
101 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(
".weak");
105 return ParseSectionSwitch(
".text",
120 return ParseSectionSwitch(
".bss",
155 bool ParseAtUnwindOrAtExcept(
bool &unwind,
bool &except);
156 bool ParseSEHRegisterNumber(
unsigned &RegNo);
160 COFFAsmParser() =
default;
175 StringRef FlagsString,
unsigned *Flags) {
186 Discardable = 1 << 8,
189 bool ReadOnlyRemoved =
false;
190 unsigned SecFlags =
None;
192 for (
char FlagChar : FlagsString) {
200 if (SecFlags & InitData)
201 return TokError(
"conflicting section flags 'b' and 'd'.");
206 SecFlags |= InitData;
207 if (SecFlags & Alloc)
208 return TokError(
"conflicting section flags 'b' and 'd'.");
209 SecFlags &= ~NoWrite;
210 if ((SecFlags & NoLoad) == 0)
220 SecFlags |= Discardable;
224 ReadOnlyRemoved =
false;
226 if ((SecFlags & Code) == 0)
227 SecFlags |= InitData;
228 if ((SecFlags & NoLoad) == 0)
233 SecFlags |= Shared | InitData;
234 SecFlags &= ~NoWrite;
235 if ((SecFlags & NoLoad) == 0)
240 SecFlags &= ~NoWrite;
241 ReadOnlyRemoved =
true;
246 if ((SecFlags & NoLoad) == 0)
248 if (!ReadOnlyRemoved)
253 SecFlags |= NoRead | NoWrite;
257 return TokError(
"unknown flag");
263 if (SecFlags ==
None)
268 if (SecFlags & InitData)
270 if ((SecFlags & Alloc) && (SecFlags &
Load) == 0)
272 if (SecFlags & NoLoad)
274 if ((SecFlags & Discardable) ||
277 if ((SecFlags & NoRead) == 0)
279 if ((SecFlags & NoWrite) == 0)
281 if (SecFlags & Shared)
289 bool COFFAsmParser::ParseDirectiveSymbolAttribute(
StringRef Directive,
SMLoc) {
298 if (getParser().parseIdentifier(Name))
299 return TokError(
"expected identifier in directive");
301 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
303 getStreamer().EmitSymbolAttribute(Sym, Attr);
309 return TokError(
"unexpected token in directive");
321 return ParseSectionSwitch(Section, Characteristics, Kind,
"", (
COFF::COMDATType)0);
324 bool COFFAsmParser::ParseSectionSwitch(
StringRef Section,
325 unsigned Characteristics,
330 return TokError(
"unexpected token in section switching directive");
333 getStreamer().SwitchSection(getContext().getCOFFSection(
334 Section, Characteristics, Kind, COMDATSymName, Type));
339 bool COFFAsmParser::ParseSectionName(
StringRef &SectionName) {
343 SectionName = getTok().getIdentifier();
366 if (ParseSectionName(SectionName))
367 return TokError(
"expected identifier in directive");
377 return TokError(
"expected string in directive");
379 StringRef FlagsStr = getTok().getStringContents();
382 if (ParseSectionFlags(SectionName, FlagsStr, &Flags))
395 return TokError(
"expected comdat type such as 'discard' or 'largest' " 396 "after protection bits");
398 if (parseCOMDATType(Type))
402 return TokError(
"expected comma in directive");
405 if (getParser().parseIdentifier(COMDATSymName))
406 return TokError(
"expected identifier in directive");
410 return TokError(
"unexpected token in directive");
414 const Triple &
T = getContext().getObjectFileInfo()->getTargetTriple();
418 ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type);
425 if (getParser().parseIdentifier(SymbolName))
426 return TokError(
"expected identifier in directive");
428 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
430 getStreamer().BeginCOFFSymbolDef(Sym);
438 if (getParser().parseAbsoluteExpression(SymbolStorageClass))
442 return TokError(
"unexpected token in directive");
445 getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
451 if (getParser().parseAbsoluteExpression(Type))
455 return TokError(
"unexpected token in directive");
458 getStreamer().EmitCOFFSymbolType(Type);
464 getStreamer().EndCOFFSymbolDef();
470 if (getParser().parseIdentifier(SymbolID))
471 return TokError(
"expected identifier in directive");
476 OffsetLoc = getLexer().getLoc();
477 if (getParser().parseAbsoluteExpression(Offset))
482 return TokError(
"unexpected token in directive");
487 "invalid '.secrel32' directive offset, can't be less " 488 "than zero or greater than std::numeric_limits<uint32_t>::max()");
493 getStreamer().EmitCOFFSecRel32(Symbol, Offset);
498 auto parseOp = [&]() ->
bool {
500 if (getParser().parseIdentifier(SymbolID))
501 return TokError(
"expected identifier in directive");
506 OffsetLoc = getLexer().getLoc();
507 if (getParser().parseAbsoluteExpression(Offset))
511 if (Offset < std::numeric_limits<int32_t>::min() ||
513 return Error(OffsetLoc,
"invalid '.rva' directive offset, can't be less " 514 "than -2147483648 or greater than " 519 getStreamer().EmitCOFFImgRel32(Symbol, Offset);
523 if (getParser().parseMany(parseOp))
524 return addErrorSuffix(
" in directive");
530 if (getParser().parseIdentifier(SymbolID))
531 return TokError(
"expected identifier in directive");
534 return TokError(
"unexpected token in directive");
539 getStreamer().EmitCOFFSafeSEH(Symbol);
545 if (getParser().parseIdentifier(SymbolID))
546 return TokError(
"expected identifier in directive");
549 return TokError(
"unexpected token in directive");
554 getStreamer().EmitCOFFSectionIndex(Symbol);
560 if (getParser().parseIdentifier(SymbolID))
561 return TokError(
"expected identifier in directive");
564 return TokError(
"unexpected token in directive");
569 getStreamer().EmitCOFFSymbolIndex(Symbol);
575 StringRef TypeId = getTok().getIdentifier();
588 return TokError(
Twine(
"unrecognized COMDAT type '" + TypeId +
"'"));
597 bool COFFAsmParser::ParseDirectiveLinkOnce(
StringRef,
SMLoc Loc) {
600 if (parseCOMDATType(Type))
604 static_cast<const MCSectionCOFF *
>(getStreamer().getCurrentSectionOnly());
607 return Error(Loc,
"cannot make section associative with .linkonce");
611 "' is already linkonce");
616 return TokError(
"unexpected token in directive");
621 bool COFFAsmParser::ParseSEHDirectiveStartProc(
StringRef,
SMLoc Loc) {
623 if (getParser().parseIdentifier(SymbolID))
627 return TokError(
"unexpected token in directive");
632 getStreamer().EmitWinCFIStartProc(Symbol, Loc);
636 bool COFFAsmParser::ParseSEHDirectiveEndProc(
StringRef,
SMLoc Loc) {
638 getStreamer().EmitWinCFIEndProc(Loc);
642 bool COFFAsmParser::ParseSEHDirectiveStartChained(
StringRef,
SMLoc Loc) {
644 getStreamer().EmitWinCFIStartChained(Loc);
648 bool COFFAsmParser::ParseSEHDirectiveEndChained(
StringRef,
SMLoc Loc) {
650 getStreamer().EmitWinCFIEndChained(Loc);
654 bool COFFAsmParser::ParseSEHDirectiveHandler(
StringRef,
SMLoc Loc) {
656 if (getParser().parseIdentifier(SymbolID))
660 return TokError(
"you must specify one or both of @unwind or @except");
662 bool unwind =
false, except =
false;
663 if (ParseAtUnwindOrAtExcept(unwind, except))
667 if (ParseAtUnwindOrAtExcept(unwind, except))
671 return TokError(
"unexpected token in directive");
673 MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID);
676 getStreamer().EmitWinEHHandler(handler, unwind, except, Loc);
680 bool COFFAsmParser::ParseSEHDirectiveHandlerData(
StringRef,
SMLoc Loc) {
682 getStreamer().EmitWinEHHandlerData();
686 bool COFFAsmParser::ParseSEHDirectivePushReg(
StringRef,
SMLoc Loc) {
688 if (ParseSEHRegisterNumber(Reg))
692 return TokError(
"unexpected token in directive");
695 getStreamer().EmitWinCFIPushReg(Reg, Loc);
699 bool COFFAsmParser::ParseSEHDirectiveSetFrame(
StringRef,
SMLoc Loc) {
702 if (ParseSEHRegisterNumber(Reg))
705 return TokError(
"you must specify a stack pointer offset");
708 if (getParser().parseAbsoluteExpression(Off))
712 return TokError(
"unexpected token in directive");
715 getStreamer().EmitWinCFISetFrame(Reg, Off, Loc);
719 bool COFFAsmParser::ParseSEHDirectiveAllocStack(
StringRef,
SMLoc Loc) {
721 if (getParser().parseAbsoluteExpression(Size))
725 return TokError(
"unexpected token in directive");
728 getStreamer().EmitWinCFIAllocStack(Size, Loc);
732 bool COFFAsmParser::ParseSEHDirectiveSaveReg(
StringRef,
SMLoc Loc) {
735 if (ParseSEHRegisterNumber(Reg))
738 return TokError(
"you must specify an offset on the stack");
741 if (getParser().parseAbsoluteExpression(Off))
745 return TokError(
"unexpected token in directive");
749 getStreamer().EmitWinCFISaveReg(Reg, Off, Loc);
755 bool COFFAsmParser::ParseSEHDirectiveSaveXMM(
StringRef,
SMLoc Loc) {
758 if (ParseSEHRegisterNumber(Reg))
761 return TokError(
"you must specify an offset on the stack");
764 if (getParser().parseAbsoluteExpression(Off))
768 return TokError(
"unexpected token in directive");
772 getStreamer().EmitWinCFISaveXMM(Reg, Off, Loc);
776 bool COFFAsmParser::ParseSEHDirectivePushFrame(
StringRef,
SMLoc Loc) {
780 SMLoc startLoc = getLexer().getLoc();
782 if (!getParser().parseIdentifier(CodeID)) {
783 if (CodeID !=
"code")
784 return Error(startLoc,
"expected @code");
790 return TokError(
"unexpected token in directive");
793 getStreamer().EmitWinCFIPushFrame(Code, Loc);
797 bool COFFAsmParser::ParseSEHDirectiveEndProlog(
StringRef,
SMLoc Loc) {
799 getStreamer().EmitWinCFIEndProlog(Loc);
803 bool COFFAsmParser::ParseAtUnwindOrAtExcept(
bool &unwind,
bool &except) {
806 return TokError(
"a handler attribute must begin with '@'");
807 SMLoc startLoc = getLexer().getLoc();
809 if (getParser().parseIdentifier(identifier))
810 return Error(startLoc,
"expected @unwind or @except");
811 if (identifier ==
"unwind")
813 else if (identifier ==
"except")
816 return Error(startLoc,
"expected @unwind or @except");
820 bool COFFAsmParser::ParseSEHRegisterNumber(
unsigned &RegNo) {
821 SMLoc startLoc = getLexer().getLoc();
826 if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
834 const unsigned *NVRegs = TAI.getCalleeSavedRegs();
836 for (i = 0; NVRegs[i] != 0; ++i)
837 if (NVRegs[i] == LLVMRegNo)
840 return Error(startLoc,
"expected non-volatile register");
845 return Error(startLoc,
"register can't be represented in SEH unwind info");
850 if (getParser().parseAbsoluteExpression(n))
853 return Error(startLoc,
"register number is too high");
863 return new COFFAsmParser;
static SectionKind getData()
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This class represents lattice values for constants.
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.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
static SectionKind getBSS()
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
unsigned getCharacteristics() const
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.
MCAsmParserExtension * createCOFFAsmParser()
StringRef getSectionName() const
Triple - Helper class for working with autoconf configuration names.
SymbolStorageClass
Storage class tells where and what the symbol represents.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
COFFYAML::WeakExternalCharacteristics Characteristics
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
int getSEHRegNum(unsigned RegNum) const
Map a target register to an equivalent SEH register number.
static bool isImplicitlyDiscardable(StringRef Name)
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
StringRef - Represent a constant reference to a string, i.e.
Represents a location in source code.
static SectionKind getReadOnly()
static SectionKind getText()