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 parseSEHDirectiveEndProlog(StringRef, SMLoc);
54 bool IgnoreDirective(StringRef, SMLoc) {
61 void Initialize(MCAsmParser &Parser)
override {
66 addDirectiveHandler<&COFFMasmParser::parseSEHDirectiveAllocStack>(
68 addDirectiveHandler<&COFFMasmParser::parseSEHDirectiveEndProlog>(
97 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".cref");
98 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".list");
99 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listall");
100 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listif");
101 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listmacro");
102 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".listmacroall");
103 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nocref");
104 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolist");
105 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolistif");
106 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".nolistmacro");
107 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"page");
108 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"subtitle");
109 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".tfcond");
110 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
"title");
116 addDirectiveHandler<&COFFMasmParser::parseDirectiveAlias>(
"alias");
119 addDirectiveHandler<&COFFMasmParser::parseDirectiveIncludelib>(
121 addDirectiveHandler<&COFFMasmParser::parseDirectiveOption>(
"option");
127 addDirectiveHandler<&COFFMasmParser::parseDirectiveEndProc>(
"endp");
129 addDirectiveHandler<&COFFMasmParser::parseDirectiveProc>(
"proc");
133 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".386");
134 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".386p");
135 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".387");
136 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".486");
137 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".486p");
138 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".586");
139 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".586p");
140 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".686");
141 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".686p");
142 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".k3d");
143 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".mmx");
144 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".xmm");
154 addDirectiveHandler<&COFFMasmParser::parseDirectiveSegmentEnd>(
"ends");
156 addDirectiveHandler<&COFFMasmParser::parseDirectiveSegment>(
"segment");
159 addDirectiveHandler<&COFFMasmParser::parseSectionDirectiveCode>(
".code");
161 addDirectiveHandler<&COFFMasmParser::parseSectionDirectiveInitializedData>(
164 &COFFMasmParser::parseSectionDirectiveUninitializedData>(
".data?");
168 addDirectiveHandler<&COFFMasmParser::IgnoreDirective>(
".model");
183 bool parseSectionDirectiveCode(StringRef, SMLoc) {
189 bool parseSectionDirectiveInitializedData(StringRef, SMLoc) {
195 bool parseSectionDirectiveUninitializedData(StringRef, SMLoc) {
202 SmallVector<StringRef, 1> CurrentProcedures;
206 COFFMasmParser() =
default;
212 unsigned Characteristics) {
213 return parseSectionSwitch(SectionName, Characteristics,
"",
217bool COFFMasmParser::parseSectionSwitch(StringRef SectionName,
218 unsigned Characteristics,
219 StringRef COMDATSymName,
223 return TokError(
"unexpected token in section switching directive");
227 COMDATSymName,
Type);
228 Section->setAlignment(Alignment);
229 getStreamer().switchSection(Section);
234bool COFFMasmParser::parseDirectiveSegment(StringRef Directive, SMLoc Loc) {
235 StringRef SegmentName;
237 return TokError(
"expected identifier in directive");
238 SegmentName = getTok().getIdentifier();
245 if (SegmentName ==
"_TEXT" || SegmentName.
starts_with(
"_TEXT$")) {
246 if (SegmentName.
size() == 5) {
250 (
".text$" + SegmentName.
substr(6)).toStringRef(SectionNameVector);
257 int64_t Alignment = 16;
259 bool DefaultCharacteristics =
true;
262 bool Readonly =
false;
264 switch (getTok().getKind()) {
269 Class = getTok().getStringContents();
274 SMLoc KeywordLoc = getTok().getLoc();
276 if (getParser().parseIdentifier(Keyword)) {
279 if (
Keyword.equals_insensitive(
"byte")) {
281 }
else if (
Keyword.equals_insensitive(
"word")) {
283 }
else if (
Keyword.equals_insensitive(
"dword")) {
285 }
else if (
Keyword.equals_insensitive(
"para")) {
287 }
else if (
Keyword.equals_insensitive(
"page")) {
289 }
else if (
Keyword.equals_insensitive(
"align")) {
291 getParser().parseIntToken(Alignment,
292 "Expected integer alignment") ||
294 return Error(getTok().getLoc(),
295 "Expected (n) following ALIGN in SEGMENT directive");
298 return Error(KeywordLoc,
299 "ALIGN argument must be a power of 2 from 1 to 8192");
301 }
else if (
Keyword.equals_insensitive(
"alias")) {
306 "Expected (string) following ALIAS in SEGMENT directive");
312 "Expected (string) following ALIAS in SEGMENT directive");
313 }
else if (
Keyword.equals_insensitive(
"readonly")) {
316 unsigned Characteristic =
317 StringSwitch<unsigned>(Keyword)
327 if (Characteristic ==
static_cast<unsigned>(-1)) {
328 return Error(KeywordLoc,
329 "Expected characteristic in SEGMENT directive; found '" +
332 Flags |= Characteristic;
333 DefaultCharacteristics =
false;
339 SectionKind
Kind = StringSwitch<SectionKind>(Class)
345 if (DefaultCharacteristics) {
350 if (DefaultCharacteristics) {
356 Flags &= ~COFF::IMAGE_SCN_MEM_WRITE;
361 if (Alignment != 0) {
364 getStreamer().switchSection(Section);
370bool COFFMasmParser::parseDirectiveSegmentEnd(StringRef Directive, SMLoc Loc) {
371 StringRef SegmentName;
373 return TokError(
"expected identifier in directive");
374 SegmentName = getTok().getIdentifier();
383bool COFFMasmParser::parseDirectiveIncludelib(StringRef Directive, SMLoc Loc) {
385 if (getParser().parseIdentifier(
Lib))
386 return TokError(
"expected identifier in includelib directive");
389 getStreamer().pushSection();
390 getStreamer().switchSection(
getContext().getCOFFSection(
392 getStreamer().emitBytes(
"/DEFAULTLIB:");
393 getStreamer().emitBytes(
Lib);
394 getStreamer().emitBytes(
" ");
395 getStreamer().popSection();
401bool COFFMasmParser::parseDirectiveOption(StringRef Directive, SMLoc Loc) {
402 auto parseOption = [&]() ->
bool {
404 if (getParser().parseIdentifier(Option))
405 return TokError(
"expected identifier for option name");
406 if (
Option.equals_insensitive(
"prologue")) {
408 if (parseToken(
AsmToken::Colon) || getParser().parseIdentifier(MacroId))
409 return TokError(
"expected :macroId after OPTION PROLOGUE");
415 return TokError(
"OPTION PROLOGUE is currently unsupported");
417 if (
Option.equals_insensitive(
"epilogue")) {
419 if (parseToken(
AsmToken::Colon) || getParser().parseIdentifier(MacroId))
420 return TokError(
"expected :macroId after OPTION EPILOGUE");
426 return TokError(
"OPTION EPILOGUE is currently unsupported");
428 return TokError(
"OPTION '" + Option +
"' is currently unsupported");
431 if (parseMany(parseOption))
432 return addErrorSuffix(
" in OPTION directive");
441bool COFFMasmParser::parseDirectiveProc(StringRef Directive, SMLoc Loc) {
442 if (!getStreamer().getCurrentFragment())
443 return Error(getTok().getLoc(),
"expected section directive");
447 return Error(Loc,
"expected identifier for procedure");
449 StringRef nextVal = getTok().getString();
450 SMLoc nextLoc = getTok().getLoc();
454 return Error(nextLoc,
"far procedure definitions not yet supported");
457 nextVal = getTok().getString();
458 nextLoc = getTok().getLoc();
463 auto *COFFSym =
static_cast<MCSymbolCOFF *
>(Sym);
464 COFFSym->setExternal(
true);
470 getTok().getString().equals_insensitive(
"frame")) {
473 getStreamer().emitWinCFIStartProc(Sym, Loc);
475 getStreamer().emitLabel(Sym, Loc);
478 CurrentProceduresFramed.push_back(Framed);
481bool COFFMasmParser::parseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
483 SMLoc LabelLoc = getTok().getLoc();
484 if (getParser().parseIdentifier(Label))
485 return Error(LabelLoc,
"expected identifier for procedure end");
487 if (CurrentProcedures.
empty())
488 return Error(Loc,
"endp outside of procedure block");
489 else if (!CurrentProcedures.
back().equals_insensitive(Label))
490 return Error(LabelLoc,
"endp does not match current procedure '" +
491 CurrentProcedures.
back() +
"'");
493 if (CurrentProceduresFramed.back()) {
494 getStreamer().emitWinCFIEndProc(Loc);
497 CurrentProceduresFramed.pop_back();
501bool COFFMasmParser::parseDirectiveAlias(StringRef Directive, SMLoc Loc) {
502 std::string AliasName, ActualName;
504 getParser().parseAngleBracketString(AliasName))
505 return Error(getTok().getLoc(),
"expected <aliasName>");
507 return addErrorSuffix(
" in " + Directive +
" directive");
509 getParser().parseAngleBracketString(ActualName))
510 return Error(getTok().getLoc(),
"expected <actualName>");
515 getStreamer().emitWeakReference(Alias, Actual);
520bool COFFMasmParser::parseSEHDirectiveAllocStack(StringRef Directive,
523 SMLoc SizeLoc = getTok().getLoc();
524 if (getParser().parseAbsoluteExpression(
Size))
525 return Error(SizeLoc,
"expected integer size");
527 return Error(SizeLoc,
"stack size must be a multiple of 8");
528 getStreamer().emitWinCFIAllocStack(
static_cast<unsigned>(
Size), Loc);
532bool COFFMasmParser::parseSEHDirectiveEndProlog(StringRef Directive,
534 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...