30 template <
bool (COFFMasmParser::*HandlerMethod)(StringRef, SMLoc)>
31 void addDirectiveHandler(StringRef Directive) {
33 std::make_pair(
this, HandleDirective<COFFMasmParser, HandlerMethod>);
34 getParser().addDirectiveHandler(Directive, Handler);
37 bool parseSectionSwitch(StringRef SectionName,
unsigned Characteristics);
39 bool parseSectionSwitch(StringRef SectionName,
unsigned Characteristics,
43 bool parseDirectiveProc(StringRef, SMLoc);
44 bool parseDirectiveEndProc(StringRef, SMLoc);
45 bool parseDirectiveSegment(StringRef, SMLoc);
46 bool parseDirectiveSegmentEnd(StringRef, SMLoc);
47 bool parseDirectiveIncludelib(StringRef, SMLoc);
48 bool parseDirectiveOption(StringRef, SMLoc);
50 bool parseDirectiveAlias(StringRef, SMLoc);
52 bool parseSEHDirectiveAllocStack(StringRef, SMLoc);
53 bool parseSEHDirectiveEndProlog(StringRef, SMLoc);
55 bool IgnoreDirective(StringRef, SMLoc) {
62 void Initialize(MCAsmParser &Parser)
override {
67 addDirectiveHandler<&COFFMasmParser::parseSEHDirectiveAllocStack>(
69 addDirectiveHandler<&COFFMasmParser::parseSEHDirectiveEndProlog>(
98 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".cref");
99 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".list");
100 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listall");
101 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listif");
102 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listmacro");
103 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listmacroall");
104 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nocref");
105 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolist");
106 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolistif");
107 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolistmacro");
108 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"page");
109 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"subtitle");
110 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".tfcond");
111 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"title");
117 addDirectiveHandler<&COFFMasmParser::parseDirectiveAlias>(
"alias");
120 addDirectiveHandler<&COFFMasmParser::parseDirectiveIncludelib>(
122 addDirectiveHandler<&COFFMasmParser::parseDirectiveOption>(
"option");
128 addDirectiveHandler<&COFFMasmParser::parseDirectiveEndProc>(
"endp");
130 addDirectiveHandler<&COFFMasmParser::parseDirectiveProc>(
"proc");
134 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".386");
135 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".386p");
136 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".387");
137 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".486");
138 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".486p");
139 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".586");
140 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".586p");
141 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".686");
142 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".686p");
143 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".k3d");
144 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".mmx");
145 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".xmm");
155 addDirectiveHandler<&COFFMasmParser::parseDirectiveSegmentEnd>(
"ends");
157 addDirectiveHandler<&COFFMasmParser::parseDirectiveSegment>(
"segment");
160 addDirectiveHandler<&COFFMasmParser::parseSectionDirectiveCode>(
".code");
162 addDirectiveHandler<&COFFMasmParser::parseSectionDirectiveInitializedData>(
165 &COFFMasmParser::parseSectionDirectiveUninitializedData>(
".data?");
169 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".model");
184 bool parseSectionDirectiveCode(StringRef, SMLoc) {
190 bool parseSectionDirectiveInitializedData(StringRef, SMLoc) {
196 bool parseSectionDirectiveUninitializedData(StringRef, SMLoc) {
203 SmallVector<StringRef, 1> CurrentProcedures;
207 COFFMasmParser() =
default;
213 unsigned Characteristics) {
214 return parseSectionSwitch(SectionName, Characteristics,
"",
218bool COFFMasmParser::parseSectionSwitch(StringRef SectionName,
219 unsigned Characteristics,
220 StringRef COMDATSymName,
224 return TokError(
"unexpected token in section switching directive");
228 COMDATSymName,
Type);
229 Section->setAlignment(Alignment);
230 getStreamer().switchSection(Section);
235bool COFFMasmParser::parseDirectiveSegment(StringRef Directive, SMLoc Loc) {
236 StringRef SegmentName;
238 return TokError(
"expected identifier in directive");
239 SegmentName = getTok().getIdentifier();
246 if (SegmentName ==
"_TEXT" || SegmentName.
starts_with(
"_TEXT$")) {
247 if (SegmentName.
size() == 5) {
251 (
".text$" + SegmentName.
substr(6)).toStringRef(SectionNameVector);
258 int64_t Alignment = 16;
260 bool DefaultCharacteristics =
true;
263 bool Readonly =
false;
265 switch (getTok().getKind()) {
270 Class = getTok().getStringContents();
275 SMLoc KeywordLoc = getTok().getLoc();
277 if (getParser().parseIdentifier(Keyword)) {
280 if (
Keyword.equals_insensitive(
"byte")) {
282 }
else if (
Keyword.equals_insensitive(
"word")) {
284 }
else if (
Keyword.equals_insensitive(
"dword")) {
286 }
else if (
Keyword.equals_insensitive(
"para")) {
288 }
else if (
Keyword.equals_insensitive(
"page")) {
290 }
else if (
Keyword.equals_insensitive(
"align")) {
292 getParser().parseIntToken(Alignment,
293 "Expected integer alignment") ||
295 return Error(getTok().getLoc(),
296 "Expected (n) following ALIGN in SEGMENT directive");
299 return Error(KeywordLoc,
300 "ALIGN argument must be a power of 2 from 1 to 8192");
302 }
else if (
Keyword.equals_insensitive(
"alias")) {
307 "Expected (string) following ALIAS in SEGMENT directive");
313 "Expected (string) following ALIAS in SEGMENT directive");
314 }
else if (
Keyword.equals_insensitive(
"readonly")) {
317 unsigned Characteristic =
318 StringSwitch<unsigned>(Keyword)
328 if (Characteristic ==
static_cast<unsigned>(-1)) {
329 return Error(KeywordLoc,
330 "Expected characteristic in SEGMENT directive; found '" +
333 Flags |= Characteristic;
334 DefaultCharacteristics =
false;
340 SectionKind
Kind = StringSwitch<SectionKind>(Class)
346 if (DefaultCharacteristics) {
351 if (DefaultCharacteristics) {
357 Flags &= ~COFF::IMAGE_SCN_MEM_WRITE;
362 if (Alignment != 0) {
365 getStreamer().switchSection(Section);
371bool COFFMasmParser::parseDirectiveSegmentEnd(StringRef Directive, SMLoc Loc) {
372 StringRef SegmentName;
374 return TokError(
"expected identifier in directive");
375 SegmentName = getTok().getIdentifier();
384bool COFFMasmParser::parseDirectiveIncludelib(StringRef Directive, SMLoc Loc) {
386 if (getParser().parseIdentifier(
Lib))
387 return TokError(
"expected identifier in includelib directive");
390 getStreamer().pushSection();
391 getStreamer().switchSection(
getContext().getCOFFSection(
393 getStreamer().emitBytes(
"/DEFAULTLIB:");
394 getStreamer().emitBytes(
Lib);
395 getStreamer().emitBytes(
" ");
396 getStreamer().popSection();
402bool COFFMasmParser::parseDirectiveOption(StringRef Directive, SMLoc Loc) {
403 auto parseOption = [&]() ->
bool {
405 if (getParser().parseIdentifier(Option))
406 return TokError(
"expected identifier for option name");
407 if (
Option.equals_insensitive(
"prologue")) {
409 if (parseToken(
AsmToken::Colon) || getParser().parseIdentifier(MacroId))
410 return TokError(
"expected :macroId after OPTION PROLOGUE");
416 return TokError(
"OPTION PROLOGUE is currently unsupported");
418 if (
Option.equals_insensitive(
"epilogue")) {
420 if (parseToken(
AsmToken::Colon) || getParser().parseIdentifier(MacroId))
421 return TokError(
"expected :macroId after OPTION EPILOGUE");
427 return TokError(
"OPTION EPILOGUE is currently unsupported");
429 return TokError(
"OPTION '" + Option +
"' is currently unsupported");
432 if (parseMany(parseOption))
433 return addErrorSuffix(
" in OPTION directive");
442bool COFFMasmParser::parseDirectiveProc(StringRef Directive, SMLoc Loc) {
443 if (!getStreamer().getCurrentFragment())
444 return Error(getTok().getLoc(),
"expected section directive");
448 return Error(Loc,
"expected identifier for procedure");
450 StringRef nextVal = getTok().getString();
451 SMLoc nextLoc = getTok().getLoc();
455 return Error(nextLoc,
"far procedure definitions not yet supported");
458 nextVal = getTok().getString();
459 nextLoc = getTok().getLoc();
464 auto *COFFSym =
static_cast<MCSymbolCOFF *
>(Sym);
465 COFFSym->setExternal(
true);
471 getTok().getString().equals_insensitive(
"frame")) {
474 getStreamer().emitWinCFIStartProc(Sym, Loc);
476 getStreamer().emitLabel(Sym, Loc);
479 CurrentProceduresFramed.push_back(Framed);
482bool COFFMasmParser::parseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
484 SMLoc LabelLoc = getTok().getLoc();
485 if (getParser().parseIdentifier(Label))
486 return Error(LabelLoc,
"expected identifier for procedure end");
488 if (CurrentProcedures.
empty())
489 return Error(Loc,
"endp outside of procedure block");
490 else if (!CurrentProcedures.
back().equals_insensitive(Label))
491 return Error(LabelLoc,
"endp does not match current procedure '" +
492 CurrentProcedures.
back() +
"'");
494 if (CurrentProceduresFramed.back()) {
495 getStreamer().emitWinCFIEndProc(Loc);
498 CurrentProceduresFramed.pop_back();
502bool COFFMasmParser::parseDirectiveAlias(StringRef Directive, SMLoc Loc) {
503 std::string AliasName, ActualName;
505 getParser().parseAngleBracketString(AliasName))
506 return Error(getTok().getLoc(),
"expected <aliasName>");
508 return addErrorSuffix(
" in " + Directive +
" directive");
510 getParser().parseAngleBracketString(ActualName))
511 return Error(getTok().getLoc(),
"expected <actualName>");
516 getStreamer().emitWeakReference(Alias, Actual);
521bool COFFMasmParser::parseSEHDirectiveAllocStack(StringRef Directive,
524 SMLoc SizeLoc = getTok().getLoc();
525 if (getParser().parseAbsoluteExpression(
Size))
526 return Error(SizeLoc,
"expected integer size");
528 return Error(SizeLoc,
"stack size must be a multiple of 8");
529 getStreamer().emitWinCFIAllocStack(
static_cast<unsigned>(
Size), Loc);
533bool COFFMasmParser::parseSEHDirectiveEndProlog(StringRef Directive,
535 getStreamer().emitWinCFIEndProlog(Loc);
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)
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.
#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.)
MCAsmParserExtension * createCOFFMasmParser()
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...