31 template <
bool (COFFMasmParser::*HandlerMethod)(StringRef, SMLoc)>
34 std::make_pair(
this, HandleDirective<COFFMasmParser, HandlerMethod>);
69 addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveAllocStack>(
71 addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveEndProlog>(
100 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".cref");
101 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".list");
102 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listall");
103 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listif");
104 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listmacro");
105 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listmacroall");
106 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nocref");
107 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolist");
108 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolistif");
109 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolistmacro");
110 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"page");
111 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"subtitle");
112 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".tfcond");
113 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"title");
119 addDirectiveHandler<&COFFMasmParser::ParseDirectiveAlias>(
"alias");
122 addDirectiveHandler<&COFFMasmParser::ParseDirectiveIncludelib>(
124 addDirectiveHandler<&COFFMasmParser::ParseDirectiveOption>(
"option");
130 addDirectiveHandler<&COFFMasmParser::ParseDirectiveEndProc>(
"endp");
132 addDirectiveHandler<&COFFMasmParser::ParseDirectiveProc>(
"proc");
136 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".386");
137 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".386p");
138 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".387");
139 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".486");
140 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".486p");
141 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".586");
142 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".586p");
143 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".686");
144 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".686p");
145 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".k3d");
146 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".mmx");
147 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".xmm");
157 addDirectiveHandler<&COFFMasmParser::ParseDirectiveSegmentEnd>(
"ends");
159 addDirectiveHandler<&COFFMasmParser::ParseDirectiveSegment>(
"segment");
162 addDirectiveHandler<&COFFMasmParser::ParseSectionDirectiveCode>(
".code");
165 &COFFMasmParser::ParseSectionDirectiveInitializedData>(
".data");
167 &COFFMasmParser::ParseSectionDirectiveUninitializedData>(
".data?");
171 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".model");
187 return ParseSectionSwitch(
".text",
195 return ParseSectionSwitch(
".data",
203 return ParseSectionSwitch(
".bss",
215 COFFMasmParser() =
default;
227bool COFFMasmParser::ParseSectionSwitch(
231 return TokError(
"unexpected token in section switching directive");
235 Kind, COMDATSymName,
Type);
236 Section->setAlignment(Alignment);
237 getStreamer().switchSection(Section);
245 return TokError(
"expected identifier in directive");
246 SegmentName = getTok().getIdentifier();
253 if (SegmentName ==
"_TEXT" || SegmentName.
startswith(
"_TEXT$")) {
254 if (SegmentName.
size() == 5) {
265 int64_t Alignment = 16;
267 bool DefaultCharacteristics =
true;
270 bool Readonly =
false;
272 switch (getTok().getKind()) {
277 Class = getTok().getStringContents();
282 SMLoc KeywordLoc = getTok().getLoc();
284 if (getParser().parseIdentifier(Keyword)) {
287 if (
Keyword.equals_insensitive(
"byte")) {
289 }
else if (
Keyword.equals_insensitive(
"word")) {
291 }
else if (
Keyword.equals_insensitive(
"dword")) {
293 }
else if (
Keyword.equals_insensitive(
"para")) {
295 }
else if (
Keyword.equals_insensitive(
"page")) {
297 }
else if (
Keyword.equals_insensitive(
"align")) {
299 getParser().parseIntToken(Alignment,
300 "Expected integer alignment") ||
302 return Error(getTok().getLoc(),
303 "Expected (n) following ALIGN in SEGMENT directive");
306 return Error(KeywordLoc,
307 "ALIGN argument must be a power of 2 from 1 to 8192");
309 }
else if (
Keyword.equals_insensitive(
"alias")) {
314 "Expected (string) following ALIAS in SEGMENT directive");
320 "Expected (string) following ALIAS in SEGMENT directive");
321 }
else if (
Keyword.equals_insensitive(
"readonly")) {
324 unsigned Characteristic =
335 if (Characteristic ==
static_cast<unsigned>(-1)) {
336 return Error(KeywordLoc,
337 "Expected characteristic in SEGMENT directive; found '" +
340 Flags |= Characteristic;
341 DefaultCharacteristics =
false;
353 if (DefaultCharacteristics) {
358 if (DefaultCharacteristics) {
364 Flags &= ~COFF::IMAGE_SCN_MEM_WRITE;
369 if (Alignment != 0) {
372 getStreamer().switchSection(Section);
381 return TokError(
"expected identifier in directive");
382 SegmentName = getTok().getIdentifier();
393 if (getParser().parseIdentifier(
Lib))
394 return TokError(
"expected identifier in includelib directive");
398 getStreamer().pushSection();
399 getStreamer().switchSection(getContext().getCOFFSection(
401 getStreamer().emitBytes(
"/DEFAULTLIB:");
402 getStreamer().emitBytes(
Lib);
403 getStreamer().emitBytes(
" ");
404 getStreamer().popSection();
411 auto parseOption = [&]() ->
bool {
413 if (getParser().parseIdentifier(Option))
414 return TokError(
"expected identifier for option name");
415 if (
Option.equals_insensitive(
"prologue")) {
417 if (parseToken(
AsmToken::Colon) || getParser().parseIdentifier(MacroId))
418 return TokError(
"expected :macroId after OPTION PROLOGUE");
424 return TokError(
"OPTION PROLOGUE is currently unsupported");
426 if (
Option.equals_insensitive(
"epilogue")) {
428 if (parseToken(
AsmToken::Colon) || getParser().parseIdentifier(MacroId))
429 return TokError(
"expected :macroId after OPTION EPILOGUE");
435 return TokError(
"OPTION EPILOGUE is currently unsupported");
437 return TokError(
"OPTION '" + Option +
"' is currently unsupported");
440 if (parseMany(parseOption))
441 return addErrorSuffix(
" in OPTION directive");
452 if (getParser().parseIdentifier(Label))
453 return Error(Loc,
"expected identifier for procedure");
455 StringRef nextVal = getTok().getString();
456 SMLoc nextLoc = getTok().getLoc();
460 return Error(nextLoc,
"far procedure definitions not yet supported");
463 nextVal = getTok().getString();
464 nextLoc = getTok().getLoc();
467 MCSymbolCOFF *
Sym = cast<MCSymbolCOFF>(getContext().getOrCreateSymbol(Label));
470 Sym->setExternal(
true);
475 getTok().getString().equals_insensitive(
"frame")) {
478 getStreamer().emitWinCFIStartProc(
Sym, Loc);
480 getStreamer().emitLabel(
Sym, Loc);
482 CurrentProcedures.push_back(Label);
483 CurrentProceduresFramed.push_back(Framed);
488 SMLoc LabelLoc = getTok().getLoc();
489 if (getParser().parseIdentifier(Label))
490 return Error(LabelLoc,
"expected identifier for procedure end");
492 if (CurrentProcedures.empty())
493 return Error(Loc,
"endp outside of procedure block");
494 else if (!CurrentProcedures.back().equals_insensitive(Label))
495 return Error(LabelLoc,
"endp does not match current procedure '" +
496 CurrentProcedures.back() +
"'");
498 if (CurrentProceduresFramed.back()) {
499 getStreamer().emitWinCFIEndProc(Loc);
501 CurrentProcedures.pop_back();
502 CurrentProceduresFramed.pop_back();
507 std::string AliasName, ActualName;
509 getParser().parseAngleBracketString(AliasName))
510 return Error(getTok().getLoc(),
"expected <aliasName>");
512 return addErrorSuffix(
" in " +
Directive +
" directive");
514 getParser().parseAngleBracketString(ActualName))
515 return Error(getTok().getLoc(),
"expected <actualName>");
517 MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
518 MCSymbol *Actual = getContext().getOrCreateSymbol(ActualName);
520 getStreamer().emitWeakReference(Alias, Actual);
528 SMLoc SizeLoc = getTok().getLoc();
529 if (getParser().parseAbsoluteExpression(
Size))
530 return Error(SizeLoc,
"expected integer size");
532 return Error(SizeLoc,
"stack size must be a multiple of 8");
533 getStreamer().emitWinCFIAllocStack(
static_cast<unsigned>(
Size), Loc);
539 getStreamer().emitWinCFIEndProlog(Loc);
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
COFFYAML::WeakExternalCharacteristics Characteristics
Lightweight error class with error context and mandatory checking.
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.
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
virtual void addDirectiveHandler(StringRef Directive, ExtensionDirectiveHandler Handler)=0
Instances of this class represent a uniqued identifier for a section in the current translation unit.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Represents a location in source code.
SectionKind - This is a simple POD value that classifies the properties of a section.
static SectionKind getText()
static SectionKind getData()
static SectionKind getBSS()
static SectionKind getReadOnly()
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - 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).
constexpr size_t size() const
size - Get the string size.
bool startswith(StringRef Prefix) const
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
A switch()-like statement whose cases are string literals.
StringSwitch & CaseLower(StringLiteral S, T Value)
The instances of the Type class are immutable: once they are created, they are never changed.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ 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))
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
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.)
MCAsmParserExtension * createCOFFMasmParser()
This struct is a compact representation of a valid (non-zero power of two) alignment.