32 template<
bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
35 this, HandleDirective<COFFAsmParser, HandlerMethod>);
36 getParser().addDirectiveHandler(
Directive, Handler);
39 bool ParseSectionSwitch(
StringRef Section,
55 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(
".text");
56 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(
".data");
57 addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(
".bss");
58 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(
".section");
59 addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(
".def");
60 addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(
".scl");
61 addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(
".type");
62 addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(
".endef");
63 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(
".secrel32");
64 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymIdx>(
".symidx");
65 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSafeSEH>(
".safeseh");
66 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(
".secidx");
67 addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(
".linkonce");
68 addDirectiveHandler<&COFFAsmParser::ParseDirectiveRVA>(
".rva");
69 addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(
".weak");
70 addDirectiveHandler<&COFFAsmParser::ParseDirectiveCGProfile>(
".cg_profile");
73 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
75 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
77 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndFuncletOrFunc>(
79 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
81 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
83 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
85 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
87 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
89 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
94 return ParseSectionSwitch(
".text",
109 return ParseSectionSwitch(
".bss",
141 bool ParseAtUnwindOrAtExcept(
bool &unwind,
bool &except);
145 COFFAsmParser() =
default;
160 StringRef FlagsString,
unsigned *Flags) {
171 Discardable = 1 << 8,
175 bool ReadOnlyRemoved =
false;
176 unsigned SecFlags =
None;
178 for (
char FlagChar : FlagsString) {
186 if (SecFlags & InitData)
187 return TokError(
"conflicting section flags 'b' and 'd'.");
192 SecFlags |= InitData;
193 if (SecFlags & Alloc)
194 return TokError(
"conflicting section flags 'b' and 'd'.");
195 SecFlags &= ~NoWrite;
196 if ((SecFlags & NoLoad) == 0)
206 SecFlags |= Discardable;
210 ReadOnlyRemoved =
false;
212 if ((SecFlags & Code) == 0)
213 SecFlags |= InitData;
214 if ((SecFlags & NoLoad) == 0)
219 SecFlags |=
Shared | InitData;
220 SecFlags &= ~NoWrite;
221 if ((SecFlags & NoLoad) == 0)
226 SecFlags &= ~NoWrite;
227 ReadOnlyRemoved =
true;
232 if ((SecFlags & NoLoad) == 0)
234 if (!ReadOnlyRemoved)
239 SecFlags |= NoRead | NoWrite;
247 return TokError(
"unknown flag");
253 if (SecFlags ==
None)
258 if (SecFlags & InitData)
260 if ((SecFlags & Alloc) && (SecFlags &
Load) == 0)
262 if (SecFlags & NoLoad)
264 if ((SecFlags & Discardable) ||
267 if ((SecFlags & NoRead) == 0)
269 if ((SecFlags & NoWrite) == 0)
271 if (SecFlags & Shared)
290 if (getParser().parseIdentifier(Name))
291 return TokError(
"expected identifier in directive");
293 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
295 getStreamer().emitSymbolAttribute(Sym, Attr);
301 return TokError(
"unexpected token in directive");
314 bool COFFAsmParser::ParseSectionSwitch(
StringRef Section,
320 bool COFFAsmParser::ParseSectionSwitch(
StringRef Section,
326 return TokError(
"unexpected token in section switching directive");
329 getStreamer().switchSection(getContext().getCOFFSection(
363 return TokError(
"expected identifier in directive");
373 return TokError(
"expected string in directive");
375 StringRef FlagsStr = getTok().getStringContents();
378 if (ParseSectionFlags(
SectionName, FlagsStr, &Flags))
391 return TokError(
"expected comdat type such as 'discard' or 'largest' "
392 "after protection bits");
394 if (parseCOMDATType(
Type))
398 return TokError(
"expected comma in directive");
401 if (getParser().parseIdentifier(COMDATSymName))
402 return TokError(
"expected identifier in directive");
406 return TokError(
"unexpected token in directive");
410 const Triple &
T = getContext().getTargetTriple();
422 return TokError(
"expected identifier in directive");
426 getStreamer().beginCOFFSymbolDef(Sym);
438 return TokError(
"unexpected token in directive");
447 if (getParser().parseAbsoluteExpression(
Type))
451 return TokError(
"unexpected token in directive");
454 getStreamer().emitCOFFSymbolType(
Type);
460 getStreamer().endCOFFSymbolDef();
466 if (getParser().parseIdentifier(SymbolID))
467 return TokError(
"expected identifier in directive");
472 OffsetLoc = getLexer().getLoc();
473 if (getParser().parseAbsoluteExpression(
Offset))
478 return TokError(
"unexpected token in directive");
483 "invalid '.secrel32' directive offset, can't be less "
484 "than zero or greater than std::numeric_limits<uint32_t>::max()");
489 getStreamer().emitCOFFSecRel32(Symbol,
Offset);
494 auto parseOp = [&]() ->
bool {
496 if (getParser().parseIdentifier(SymbolID))
497 return TokError(
"expected identifier in directive");
502 OffsetLoc = getLexer().getLoc();
503 if (getParser().parseAbsoluteExpression(
Offset))
509 return Error(OffsetLoc,
"invalid '.rva' directive offset, can't be less "
510 "than -2147483648 or greater than "
515 getStreamer().emitCOFFImgRel32(Symbol,
Offset);
519 if (getParser().parseMany(parseOp))
520 return addErrorSuffix(
" in directive");
526 if (getParser().parseIdentifier(SymbolID))
527 return TokError(
"expected identifier in directive");
530 return TokError(
"unexpected token in directive");
535 getStreamer().emitCOFFSafeSEH(Symbol);
541 if (getParser().parseIdentifier(SymbolID))
542 return TokError(
"expected identifier in directive");
545 return TokError(
"unexpected token in directive");
550 getStreamer().emitCOFFSectionIndex(Symbol);
556 if (getParser().parseIdentifier(SymbolID))
557 return TokError(
"expected identifier in directive");
560 return TokError(
"unexpected token in directive");
565 getStreamer().emitCOFFSymbolIndex(Symbol);
571 StringRef TypeId = getTok().getIdentifier();
584 return TokError(
Twine(
"unrecognized COMDAT type '" + TypeId +
"'"));
593 bool COFFAsmParser::ParseDirectiveLinkOnce(
StringRef,
SMLoc Loc) {
596 if (parseCOMDATType(
Type))
600 static_cast<const MCSectionCOFF *
>(getStreamer().getCurrentSectionOnly());
603 return Error(Loc,
"cannot make section associative with .linkonce");
607 "' is already linkonce");
612 return TokError(
"unexpected token in directive");
617 bool COFFAsmParser::ParseSEHDirectiveStartProc(
StringRef,
SMLoc Loc) {
619 if (getParser().parseIdentifier(SymbolID))
623 return TokError(
"unexpected token in directive");
628 getStreamer().emitWinCFIStartProc(Symbol, Loc);
632 bool COFFAsmParser::ParseSEHDirectiveEndProc(
StringRef,
SMLoc Loc) {
634 getStreamer().emitWinCFIEndProc(Loc);
638 bool COFFAsmParser::ParseSEHDirectiveEndFuncletOrFunc(
StringRef,
SMLoc Loc) {
640 getStreamer().emitWinCFIFuncletOrFuncEnd(Loc);
644 bool COFFAsmParser::ParseSEHDirectiveStartChained(
StringRef,
SMLoc Loc) {
646 getStreamer().emitWinCFIStartChained(Loc);
650 bool COFFAsmParser::ParseSEHDirectiveEndChained(
StringRef,
SMLoc Loc) {
652 getStreamer().emitWinCFIEndChained(Loc);
656 bool COFFAsmParser::ParseSEHDirectiveHandler(
StringRef,
SMLoc Loc) {
658 if (getParser().parseIdentifier(SymbolID))
662 return TokError(
"you must specify one or both of @unwind or @except");
664 bool unwind =
false, except =
false;
665 if (ParseAtUnwindOrAtExcept(unwind, except))
669 if (ParseAtUnwindOrAtExcept(unwind, except))
673 return TokError(
"unexpected token in directive");
675 MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID);
678 getStreamer().emitWinEHHandler(handler, unwind, except, Loc);
682 bool COFFAsmParser::ParseSEHDirectiveHandlerData(
StringRef,
SMLoc Loc) {
684 getStreamer().emitWinEHHandlerData();
688 bool COFFAsmParser::ParseSEHDirectiveAllocStack(
StringRef,
SMLoc Loc) {
690 if (getParser().parseAbsoluteExpression(Size))
694 return TokError(
"unexpected token in directive");
697 getStreamer().emitWinCFIAllocStack(Size, Loc);
701 bool COFFAsmParser::ParseSEHDirectiveEndProlog(
StringRef,
SMLoc Loc) {
703 getStreamer().emitWinCFIEndProlog(Loc);
707 bool COFFAsmParser::ParseAtUnwindOrAtExcept(
bool &unwind,
bool &except) {
710 return TokError(
"a handler attribute must begin with '@' or '%'");
711 SMLoc startLoc = getLexer().getLoc();
713 if (getParser().parseIdentifier(identifier))
714 return Error(startLoc,
"expected @unwind or @except");
715 if (identifier ==
"unwind")
717 else if (identifier ==
"except")
720 return Error(startLoc,
"expected @unwind or @except");
727 return new COFFAsmParser;