29 template <
bool (COFFMasmParser::*HandlerMethod)(StringRef, SMLoc)>
30 void addDirectiveHandler(StringRef Directive) {
32 std::make_pair(
this, HandleDirective<COFFMasmParser, HandlerMethod>);
33 getParser().addDirectiveHandler(Directive, Handler);
36 bool parseSectionSwitch(StringRef SectionName,
unsigned Characteristics);
38 bool parseSectionSwitch(StringRef SectionName,
unsigned Characteristics,
42 bool parseDirectiveProc(StringRef, SMLoc);
43 bool parseDirectiveEndProc(StringRef, SMLoc);
44 bool parseDirectiveSegment(StringRef, SMLoc);
45 bool parseDirectiveSegmentEnd(StringRef, SMLoc);
46 bool parseDirectiveIncludelib(StringRef, SMLoc);
47 bool parseDirectiveOption(StringRef, SMLoc);
49 bool parseDirectiveAlias(StringRef, SMLoc);
51 bool parseSEHDirectiveAllocStack(StringRef, SMLoc);
52 bool parseSEHDirectiveFreeStack(StringRef, SMLoc);
53 bool parseSEHDirectiveEndProlog(StringRef, SMLoc);
54 bool parseSEHDirectiveBeginEpilog(StringRef, SMLoc);
55 bool parseSEHDirectiveEndEpilog(StringRef, SMLoc);
58 bool ensureInsideFrame(SMLoc Loc);
60 bool ensureInProlog(SMLoc Loc);
62 bool ensureInEpilog(SMLoc Loc);
64 bool IgnoreDirective(StringRef, SMLoc) {
71 void Initialize(MCAsmParser &Parser)
override {
76 addDirectiveHandler<&COFFMasmParser::parseSEHDirectiveAllocStack>(
78 addDirectiveHandler<&COFFMasmParser::parseSEHDirectiveFreeStack>(
80 addDirectiveHandler<&COFFMasmParser::parseSEHDirectiveEndProlog>(
82 addDirectiveHandler<&COFFMasmParser::parseSEHDirectiveBeginEpilog>(
84 addDirectiveHandler<&COFFMasmParser::parseSEHDirectiveEndEpilog>(
113 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".cref");
114 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".list");
115 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listall");
116 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listif");
117 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listmacro");
118 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listmacroall");
119 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nocref");
120 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolist");
121 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolistif");
122 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolistmacro");
123 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"page");
124 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"subtitle");
125 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".tfcond");
126 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"title");
132 addDirectiveHandler<&COFFMasmParser::parseDirectiveAlias>(
"alias");
135 addDirectiveHandler<&COFFMasmParser::parseDirectiveIncludelib>(
137 addDirectiveHandler<&COFFMasmParser::parseDirectiveOption>(
"option");
143 addDirectiveHandler<&COFFMasmParser::parseDirectiveEndProc>(
"endp");
145 addDirectiveHandler<&COFFMasmParser::parseDirectiveProc>(
"proc");
149 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".386");
150 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".386p");
151 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".387");
152 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".486");
153 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".486p");
154 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".586");
155 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".586p");
156 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".686");
157 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".686p");
158 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".k3d");
159 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".mmx");
160 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".xmm");
170 addDirectiveHandler<&COFFMasmParser::parseDirectiveSegmentEnd>(
"ends");
172 addDirectiveHandler<&COFFMasmParser::parseDirectiveSegment>(
"segment");
175 addDirectiveHandler<&COFFMasmParser::parseSectionDirectiveCode>(
".code");
177 addDirectiveHandler<&COFFMasmParser::parseSectionDirectiveInitializedData>(
180 &COFFMasmParser::parseSectionDirectiveUninitializedData>(
".data?");
184 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".model");
199 bool parseSectionDirectiveCode(StringRef, SMLoc) {
205 bool parseSectionDirectiveInitializedData(StringRef, SMLoc) {
211 bool parseSectionDirectiveUninitializedData(StringRef, SMLoc) {
218 SmallVector<StringRef, 1> CurrentProcedures;
222 COFFMasmParser() =
default;
228 unsigned Characteristics) {
229 return parseSectionSwitch(SectionName, Characteristics,
"",
233bool COFFMasmParser::parseSectionSwitch(StringRef SectionName,
234 unsigned Characteristics,
235 StringRef COMDATSymName,
239 return TokError(
"unexpected token in section switching directive");
243 COMDATSymName,
Type);
244 Section->setAlignment(Alignment);
245 getStreamer().switchSection(Section);
250bool COFFMasmParser::parseDirectiveSegment(StringRef Directive, SMLoc Loc) {
251 StringRef SegmentName;
253 return TokError(
"expected identifier in directive");
254 SegmentName = getTok().getIdentifier();
261 if (SegmentName ==
"_TEXT" || SegmentName.
starts_with(
"_TEXT$")) {
262 if (SegmentName.
size() == 5) {
266 (
".text$" + SegmentName.
substr(6)).toStringRef(SectionNameVector);
273 int64_t Alignment = 16;
275 bool DefaultCharacteristics =
true;
278 bool Readonly =
false;
280 switch (getTok().getKind()) {
285 Class = getTok().getStringContents();
290 SMLoc KeywordLoc = getTok().getLoc();
292 if (getParser().parseIdentifier(Keyword)) {
295 if (
Keyword.equals_insensitive(
"byte")) {
297 }
else if (
Keyword.equals_insensitive(
"word")) {
299 }
else if (
Keyword.equals_insensitive(
"dword")) {
301 }
else if (
Keyword.equals_insensitive(
"para")) {
303 }
else if (
Keyword.equals_insensitive(
"page")) {
305 }
else if (
Keyword.equals_insensitive(
"align")) {
307 getParser().parseIntToken(Alignment,
308 "Expected integer alignment") ||
310 return Error(getTok().getLoc(),
311 "Expected (n) following ALIGN in SEGMENT directive");
314 return Error(KeywordLoc,
315 "ALIGN argument must be a power of 2 from 1 to 8192");
317 }
else if (
Keyword.equals_insensitive(
"alias")) {
322 "Expected (string) following ALIAS in SEGMENT directive");
328 "Expected (string) following ALIAS in SEGMENT directive");
329 }
else if (
Keyword.equals_insensitive(
"readonly")) {
332 unsigned Characteristic =
333 StringSwitch<unsigned>(Keyword)
343 if (Characteristic ==
static_cast<unsigned>(-1)) {
344 return Error(KeywordLoc,
345 "Expected characteristic in SEGMENT directive; found '" +
348 Flags |= Characteristic;
349 DefaultCharacteristics =
false;
355 SectionKind
Kind = StringSwitch<SectionKind>(Class)
361 if (DefaultCharacteristics) {
366 if (DefaultCharacteristics) {
372 Flags &= ~COFF::IMAGE_SCN_MEM_WRITE;
377 if (Alignment != 0) {
380 getStreamer().switchSection(Section);
386bool COFFMasmParser::parseDirectiveSegmentEnd(StringRef Directive, SMLoc Loc) {
387 StringRef SegmentName;
389 return TokError(
"expected identifier in directive");
390 SegmentName = getTok().getIdentifier();
399bool COFFMasmParser::parseDirectiveIncludelib(StringRef Directive, SMLoc Loc) {
401 if (getParser().parseIdentifier(
Lib))
402 return TokError(
"expected identifier in includelib directive");
405 getStreamer().pushSection();
406 getStreamer().switchSection(
getContext().getCOFFSection(
408 getStreamer().emitBytes(
"/DEFAULTLIB:");
409 getStreamer().emitBytes(
Lib);
410 getStreamer().emitBytes(
" ");
411 getStreamer().popSection();
417bool COFFMasmParser::parseDirectiveOption(StringRef Directive, SMLoc Loc) {
418 auto parseOption = [&]() ->
bool {
420 if (getParser().parseIdentifier(Option))
421 return TokError(
"expected identifier for option name");
424 if (parseToken(
AsmToken::Colon) || getParser().parseIdentifier(MacroId))
425 return TokError(
"expected :macroId after OPTION PROLOGUE");
431 return TokError(
"OPTION PROLOGUE is currently unsupported");
435 if (parseToken(
AsmToken::Colon) || getParser().parseIdentifier(MacroId))
436 return TokError(
"expected :macroId after OPTION EPILOGUE");
442 return TokError(
"OPTION EPILOGUE is currently unsupported");
444 return TokError(
"OPTION '" + Option +
"' is currently unsupported");
447 if (parseMany(parseOption))
448 return addErrorSuffix(
" in OPTION directive");
457bool COFFMasmParser::parseDirectiveProc(StringRef Directive, SMLoc Loc) {
458 if (!getStreamer().getCurrentFragment())
459 return Error(getTok().getLoc(),
"expected section directive");
463 return Error(Loc,
"expected identifier for procedure");
465 StringRef nextVal = getTok().getString();
466 SMLoc nextLoc = getTok().getLoc();
470 return Error(nextLoc,
"far procedure definitions not yet supported");
473 nextVal = getTok().getString();
474 nextLoc = getTok().getLoc();
479 auto *COFFSym =
static_cast<MCSymbolCOFF *
>(Sym);
480 COFFSym->setExternal(
true);
486 getTok().getString().equals_insensitive(
"frame")) {
489 getStreamer().emitWinCFIStartProc(Sym, Loc);
491 getStreamer().emitLabel(Sym, Loc);
494 CurrentProceduresFramed.push_back(Framed);
497bool COFFMasmParser::parseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
499 SMLoc LabelLoc = getTok().getLoc();
500 if (getParser().parseIdentifier(Label))
501 return Error(LabelLoc,
"expected identifier for procedure end");
503 if (CurrentProcedures.
empty())
504 return Error(Loc,
"endp outside of procedure block");
505 else if (!CurrentProcedures.
back().equals_insensitive(Label))
506 return Error(LabelLoc,
"endp does not match current procedure '" +
507 CurrentProcedures.
back() +
"'");
509 if (CurrentProceduresFramed.back()) {
510 getStreamer().emitWinCFIEndProc(Loc);
513 CurrentProceduresFramed.pop_back();
517bool COFFMasmParser::parseDirectiveAlias(StringRef Directive, SMLoc Loc) {
518 std::string AliasName, ActualName;
520 getParser().parseAngleBracketString(AliasName))
521 return Error(getTok().getLoc(),
"expected <aliasName>");
523 return addErrorSuffix(
" in " + Directive +
" directive");
525 getParser().parseAngleBracketString(ActualName))
526 return Error(getTok().getLoc(),
"expected <actualName>");
531 getStreamer().emitWeakReference(Alias, Actual);
536bool COFFMasmParser::ensureInsideFrame(SMLoc Loc) {
537 if (CurrentProceduresFramed.empty() || !CurrentProceduresFramed.back()) {
539 "Missing Frame in proc, no unwind code will be generated.");
544bool COFFMasmParser::ensureInProlog(SMLoc Loc) {
545 if (ensureInsideFrame(Loc))
547 if (getStreamer().isWinCFIPrologEnded()) {
548 return Error(Loc,
"prolog directive must be used inside a prolog");
553bool COFFMasmParser::ensureInEpilog(SMLoc Loc) {
554 if (ensureInsideFrame(Loc))
556 if (!getStreamer().isInEpilogCFI()) {
557 return Error(Loc,
"epilog directive must be used inside an epilog");
562bool COFFMasmParser::parseSEHDirectiveAllocStack(StringRef ,
564 if (ensureInProlog(Loc))
567 SMLoc SizeLoc = getTok().getLoc();
568 if (getParser().parseAbsoluteExpression(
Size))
569 return Error(SizeLoc,
"expected integer size");
571 return Error(SizeLoc,
"stack size must be non-negative");
573 return Error(SizeLoc,
"stack size must be a multiple of 8");
574 getStreamer().emitWinCFIAllocStack(
static_cast<unsigned>(
Size), Loc);
578bool COFFMasmParser::parseSEHDirectiveFreeStack(StringRef ,
580 if (ensureInEpilog(Loc))
583 SMLoc SizeLoc = getTok().getLoc();
584 if (getParser().parseAbsoluteExpression(
Size))
585 return Error(SizeLoc,
"expected integer size");
587 return Error(SizeLoc,
"stack size must be non-negative");
589 return Error(SizeLoc,
"stack size must be a multiple of 8");
590 getStreamer().emitWinCFIAllocStack(
static_cast<unsigned>(
Size), Loc);
594bool COFFMasmParser::parseSEHDirectiveEndProlog(StringRef ,
596 if (ensureInsideFrame(Loc))
598 getStreamer().emitWinCFIEndProlog(Loc);
602bool COFFMasmParser::parseSEHDirectiveBeginEpilog(StringRef ,
604 if (ensureInsideFrame(Loc))
608 if (!getStreamer().isWinCFIPrologEnded() || getStreamer().isInEpilogCFI()) {
609 return Error(Loc,
".beginepilog must come after .endprolog or .endepilog");
611 getStreamer().emitWinCFIBeginEpilogue(Loc);
615bool COFFMasmParser::parseSEHDirectiveEndEpilog(StringRef ,
617 if (ensureInEpilog(Loc))
619 getStreamer().emitWinCFIEndEpilogue(Loc);
624 return new COFFMasmParser;
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
StringRef getName() const
getName - Get the symbol name.
static SectionKind getText()
static SectionKind getData()
static SectionKind getReadOnly()
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr size_t size() const
Get the string size.
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ IMAGE_SCN_MEM_NOT_PAGED
@ IMAGE_SCN_MEM_NOT_CACHED
@ IMAGE_SCN_CNT_UNINITIALIZED_DATA
@ IMAGE_SCN_MEM_DISCARDABLE
@ IMAGE_SCN_CNT_INITIALIZED_DATA
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
@ SCT_COMPLEX_TYPE_SHIFT
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
LLVM_ABI SimpleSymbol parseSymbol(StringRef SymName)
Get symbol classification by parsing the name of a symbol.
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
LLVM_ABI MCAsmParserExtension * createCOFFMasmParser()
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...