31 template <
bool (COFFMasmParser::*HandlerMethod)(StringRef, SMLoc)>
34 std::make_pair(
this, HandleDirective<COFFMasmParser, HandlerMethod>);
68 addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveAllocStack>(
70 addDirectiveHandler<&COFFMasmParser::ParseSEHDirectiveEndProlog>(
99 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".cref");
100 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".list");
101 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listall");
102 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listif");
103 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listmacro");
104 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listmacroall");
105 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nocref");
106 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolist");
107 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolistif");
108 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolistmacro");
109 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"page");
110 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"subtitle");
111 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".tfcond");
112 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"title");
118 addDirectiveHandler<&COFFMasmParser::ParseDirectiveAlias>(
"alias");
121 addDirectiveHandler<&COFFMasmParser::ParseDirectiveIncludelib>(
123 addDirectiveHandler<&COFFMasmParser::ParseDirectiveOption>(
"option");
129 addDirectiveHandler<&COFFMasmParser::ParseDirectiveEndProc>(
"endp");
131 addDirectiveHandler<&COFFMasmParser::ParseDirectiveProc>(
"proc");
135 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".386");
136 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".386p");
137 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".387");
138 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".486");
139 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".486p");
140 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".586");
141 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".586p");
142 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".686");
143 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".686p");
144 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".k3d");
145 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".mmx");
146 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".xmm");
156 addDirectiveHandler<&COFFMasmParser::ParseDirectiveSegmentEnd>(
"ends");
158 addDirectiveHandler<&COFFMasmParser::ParseDirectiveSegment>(
"segment");
161 addDirectiveHandler<&COFFMasmParser::ParseSectionDirectiveCode>(
".code");
164 &COFFMasmParser::ParseSectionDirectiveInitializedData>(
".data");
166 &COFFMasmParser::ParseSectionDirectiveUninitializedData>(
".data?");
170 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".model");
208 COFFMasmParser() =
default;
225 return TokError(
"unexpected token in section switching directive");
229 COMDATSymName,
Type);
230 Section->setAlignment(Alignment);
231 getStreamer().switchSection(Section);
239 return TokError(
"expected identifier in directive");
240 SegmentName = getTok().getIdentifier();
247 if (SegmentName ==
"_TEXT" || SegmentName.
starts_with(
"_TEXT$")) {
248 if (SegmentName.
size() == 5) {
259 int64_t Alignment = 16;
261 bool DefaultCharacteristics =
true;
264 bool Readonly =
false;
266 switch (getTok().getKind()) {
271 Class = getTok().getStringContents();
276 SMLoc KeywordLoc = getTok().getLoc();
278 if (getParser().parseIdentifier(Keyword)) {
281 if (
Keyword.equals_insensitive(
"byte")) {
283 }
else if (
Keyword.equals_insensitive(
"word")) {
285 }
else if (
Keyword.equals_insensitive(
"dword")) {
287 }
else if (
Keyword.equals_insensitive(
"para")) {
289 }
else if (
Keyword.equals_insensitive(
"page")) {
291 }
else if (
Keyword.equals_insensitive(
"align")) {
293 getParser().parseIntToken(Alignment,
294 "Expected integer alignment") ||
296 return Error(getTok().getLoc(),
297 "Expected (n) following ALIGN in SEGMENT directive");
300 return Error(KeywordLoc,
301 "ALIGN argument must be a power of 2 from 1 to 8192");
303 }
else if (
Keyword.equals_insensitive(
"alias")) {
308 "Expected (string) following ALIAS in SEGMENT directive");
314 "Expected (string) following ALIAS in SEGMENT directive");
315 }
else if (
Keyword.equals_insensitive(
"readonly")) {
318 unsigned Characteristic =
329 if (Characteristic ==
static_cast<unsigned>(-1)) {
330 return Error(KeywordLoc,
331 "Expected characteristic in SEGMENT directive; found '" +
334 Flags |= Characteristic;
335 DefaultCharacteristics =
false;
347 if (DefaultCharacteristics) {
352 if (DefaultCharacteristics) {
358 Flags &= ~COFF::IMAGE_SCN_MEM_WRITE;
363 if (Alignment != 0) {
366 getStreamer().switchSection(Section);
375 return TokError(
"expected identifier in directive");
376 SegmentName = getTok().getIdentifier();
387 if (getParser().parseIdentifier(
Lib))
388 return TokError(
"expected identifier in includelib directive");
391 getStreamer().pushSection();
392 getStreamer().switchSection(getContext().getCOFFSection(
394 getStreamer().emitBytes(
"/DEFAULTLIB:");
395 getStreamer().emitBytes(
Lib);
396 getStreamer().emitBytes(
" ");
397 getStreamer().popSection();
404 auto parseOption = [&]() ->
bool {
406 if (getParser().parseIdentifier(Option))
407 return TokError(
"expected identifier for option name");
408 if (
Option.equals_insensitive(
"prologue")) {
410 if (parseToken(
AsmToken::Colon) || getParser().parseIdentifier(MacroId))
411 return TokError(
"expected :macroId after OPTION PROLOGUE");
417 return TokError(
"OPTION PROLOGUE is currently unsupported");
419 if (
Option.equals_insensitive(
"epilogue")) {
421 if (parseToken(
AsmToken::Colon) || getParser().parseIdentifier(MacroId))
422 return TokError(
"expected :macroId after OPTION EPILOGUE");
428 return TokError(
"OPTION EPILOGUE is currently unsupported");
430 return TokError(
"OPTION '" + Option +
"' is currently unsupported");
433 if (parseMany(parseOption))
434 return addErrorSuffix(
" in OPTION directive");
445 if (getParser().parseIdentifier(Label))
446 return Error(Loc,
"expected identifier for procedure");
448 StringRef nextVal = getTok().getString();
449 SMLoc nextLoc = getTok().getLoc();
453 return Error(nextLoc,
"far procedure definitions not yet supported");
456 nextVal = getTok().getString();
457 nextLoc = getTok().getLoc();
460 MCSymbolCOFF *
Sym = cast<MCSymbolCOFF>(getContext().getOrCreateSymbol(Label));
463 Sym->setExternal(
true);
468 getTok().getString().equals_insensitive(
"frame")) {
471 getStreamer().emitWinCFIStartProc(
Sym, Loc);
473 getStreamer().emitLabel(
Sym, Loc);
475 CurrentProcedures.push_back(Label);
476 CurrentProceduresFramed.push_back(Framed);
481 SMLoc LabelLoc = getTok().getLoc();
482 if (getParser().parseIdentifier(Label))
483 return Error(LabelLoc,
"expected identifier for procedure end");
485 if (CurrentProcedures.empty())
486 return Error(Loc,
"endp outside of procedure block");
487 else if (!CurrentProcedures.back().equals_insensitive(Label))
488 return Error(LabelLoc,
"endp does not match current procedure '" +
489 CurrentProcedures.back() +
"'");
491 if (CurrentProceduresFramed.back()) {
492 getStreamer().emitWinCFIEndProc(Loc);
494 CurrentProcedures.pop_back();
495 CurrentProceduresFramed.pop_back();
500 std::string AliasName, ActualName;
502 getParser().parseAngleBracketString(AliasName))
503 return Error(getTok().getLoc(),
"expected <aliasName>");
505 return addErrorSuffix(
" in " +
Directive +
" directive");
507 getParser().parseAngleBracketString(ActualName))
508 return Error(getTok().getLoc(),
"expected <actualName>");
510 MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
511 MCSymbol *Actual = getContext().getOrCreateSymbol(ActualName);
513 getStreamer().emitWeakReference(Alias, Actual);
521 SMLoc SizeLoc = getTok().getLoc();
522 if (getParser().parseAbsoluteExpression(
Size))
523 return Error(SizeLoc,
"expected integer size");
525 return Error(SizeLoc,
"stack size must be a multiple of 8");
526 getStreamer().emitWinCFIAllocStack(
static_cast<unsigned>(
Size), Loc);
532 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 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).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr size_t size() const
size - Get the string size.
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.