Skip to content

Commit 2bcee43

Browse files
committed
[ms] [llvm-ml] Add support for @catstr built-in function symbol
MASM supports some built-in functions, including @catstr to concatenate arbitrary string arguments.
1 parent d48a36f commit 2bcee43

File tree

2 files changed

+98
-12
lines changed

2 files changed

+98
-12
lines changed

llvm/lib/MC/MCParser/MasmParser.cpp

Lines changed: 89 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,19 @@ class MasmParser : public MCAsmParser {
778778
std::optional<std::string> evaluateBuiltinTextMacro(BuiltinSymbol Symbol,
779779
SMLoc StartLoc);
780780

781+
// Generic (target and platform independent) directive parsing.
782+
enum BuiltinFunction {
783+
BI_NO_FUNCTION, // Placeholder
784+
BI_CATSTR,
785+
};
786+
787+
/// Maps builtin name --> BuiltinFunction enum, for builtins handled by this
788+
/// class.
789+
StringMap<BuiltinFunction> BuiltinFunctionMap;
790+
791+
bool evaluateBuiltinMacroFunction(BuiltinFunction Function, StringRef Name,
792+
std::string &Res);
793+
781794
// ".ascii", ".asciz", ".string"
782795
bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
783796

@@ -959,7 +972,7 @@ class MasmParser : public MCAsmParser {
959972
bool parseDirectiveEcho(SMLoc DirectiveLoc);
960973

961974
void initializeDirectiveKindMap();
962-
void initializeBuiltinSymbolMap();
975+
void initializeBuiltinSymbolMaps();
963976
};
964977

965978
} // end anonymous namespace
@@ -999,7 +1012,7 @@ MasmParser::MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
9991012

10001013
initializeDirectiveKindMap();
10011014
PlatformParser->Initialize(*this);
1002-
initializeBuiltinSymbolMap();
1015+
initializeBuiltinSymbolMaps();
10031016

10041017
NumOfMacroInstantiations = 0;
10051018
}
@@ -1084,15 +1097,25 @@ bool MasmParser::expandMacros() {
10841097
}
10851098

10861099
std::optional<std::string> ExpandedValue;
1087-
auto BuiltinIt = BuiltinSymbolMap.find(IDLower);
1088-
if (BuiltinIt != BuiltinSymbolMap.end()) {
1100+
1101+
if (auto BuiltinIt = BuiltinSymbolMap.find(IDLower);
1102+
BuiltinIt != BuiltinSymbolMap.end()) {
10891103
ExpandedValue =
10901104
evaluateBuiltinTextMacro(BuiltinIt->getValue(), Tok.getLoc());
1091-
} else {
1092-
auto VarIt = Variables.find(IDLower);
1093-
if (VarIt != Variables.end() && VarIt->getValue().IsText) {
1094-
ExpandedValue = VarIt->getValue().TextValue;
1105+
} else if (auto BuiltinFuncIt = BuiltinFunctionMap.find(IDLower);
1106+
BuiltinFuncIt != BuiltinFunctionMap.end()) {
1107+
StringRef Name;
1108+
if (parseIdentifier(Name)) {
1109+
return true;
1110+
}
1111+
std::string Res;
1112+
if (evaluateBuiltinMacroFunction(BuiltinFuncIt->getValue(), Name, Res)) {
1113+
return true;
10951114
}
1115+
ExpandedValue = Res;
1116+
} else if (auto VarIt = Variables.find(IDLower);
1117+
VarIt != Variables.end() && VarIt->getValue().IsText) {
1118+
ExpandedValue = VarIt->getValue().TextValue;
10961119
}
10971120

10981121
if (!ExpandedValue)
@@ -3197,6 +3220,18 @@ bool MasmParser::parseTextItem(std::string &Data) {
31973220
continue;
31983221
}
31993222

3223+
// Try to resolve as a built-in macro function
3224+
auto BuiltinFuncIt = BuiltinFunctionMap.find(ID.lower());
3225+
if (BuiltinFuncIt != BuiltinFunctionMap.end()) {
3226+
Data.clear();
3227+
if (evaluateBuiltinMacroFunction(BuiltinFuncIt->getValue(), ID, Data)) {
3228+
return true;
3229+
}
3230+
ID = StringRef(Data);
3231+
Expanded = true;
3232+
continue;
3233+
}
3234+
32003235
// Try to resolve as a variable text macro
32013236
auto VarIt = Variables.find(ID.lower());
32023237
if (VarIt != Variables.end()) {
@@ -6204,7 +6239,7 @@ bool MasmParser::parseMSInlineAsm(
62046239
return false;
62056240
}
62066241

6207-
void MasmParser::initializeBuiltinSymbolMap() {
6242+
void MasmParser::initializeBuiltinSymbolMaps() {
62086243
// Numeric built-ins (supported in all versions)
62096244
BuiltinSymbolMap["@version"] = BI_VERSION;
62106245
BuiltinSymbolMap["@line"] = BI_LINE;
@@ -6216,6 +6251,9 @@ void MasmParser::initializeBuiltinSymbolMap() {
62166251
BuiltinSymbolMap["@filename"] = BI_FILENAME;
62176252
BuiltinSymbolMap["@curseg"] = BI_CURSEG;
62186253

6254+
// Function built-ins (supported in all versions)
6255+
BuiltinFunctionMap["@catstr"] = BI_CATSTR;
6256+
62196257
// Some built-ins exist only for MASM32 (32-bit x86)
62206258
if (getContext().getSubtargetInfo()->getTargetTriple().getArch() ==
62216259
Triple::x86) {
@@ -6289,6 +6327,48 @@ MasmParser::evaluateBuiltinTextMacro(BuiltinSymbol Symbol, SMLoc StartLoc) {
62896327
llvm_unreachable("unhandled built-in symbol");
62906328
}
62916329

6330+
bool MasmParser::evaluateBuiltinMacroFunction(BuiltinFunction Function,
6331+
StringRef Name,
6332+
std::string &Res) {
6333+
if (parseToken(AsmToken::LParen, "invoking macro function '" + Name +
6334+
"' requires arguments in parentheses")) {
6335+
return true;
6336+
}
6337+
6338+
MCAsmMacroParameters P;
6339+
switch (Function) {
6340+
default:
6341+
return true;
6342+
case BI_CATSTR:
6343+
break;
6344+
}
6345+
MCAsmMacro M(Name, "", P, {}, true);
6346+
6347+
MCAsmMacroArguments A;
6348+
if (parseMacroArguments(&M, A, AsmToken::RParen) || parseRParen()) {
6349+
return true;
6350+
}
6351+
6352+
switch (Function) {
6353+
default:
6354+
llvm_unreachable("unhandled built-in function");
6355+
case BI_CATSTR: {
6356+
for (const MCAsmMacroArgument &Arg : A) {
6357+
for (const AsmToken &Tok : Arg) {
6358+
if (Tok.is(AsmToken::String)) {
6359+
Res.append(Tok.getStringContents());
6360+
} else {
6361+
Res.append(Tok.getString());
6362+
}
6363+
}
6364+
}
6365+
return false;
6366+
}
6367+
}
6368+
llvm_unreachable("unhandled built-in function");
6369+
return true;
6370+
}
6371+
62926372
/// Create an MCAsmParser instance.
62936373
MCAsmParser *llvm::createMCMasmParser(SourceMgr &SM, MCContext &C,
62946374
MCStreamer &Out, const MCAsmInfo &MAI,

llvm/test/tools/llvm-ml/macro_function.asm

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,20 @@ expr_recursive_test PROC
103103
ret
104104
expr_recursive_test ENDP
105105

106+
expand_as_directive_test @CatStr(P, RO, C)
107+
; CHECK-LABEL: expand_as_directive_test:
108+
109+
ret
110+
expand_as_directive_test ENDP
111+
106112
custom_strcat MACRO arg1, arg2
107113
EXITM <arg1&arg2>
108114
ENDM
109115

110-
expand_as_directive_test custom_strcat(P, ROC)
111-
; CHECK-LABEL: expand_as_directive_test:
116+
expand_as_directive_custom_test custom_strcat(P, ROC)
117+
; CHECK-LABEL: expand_as_directive_custom_test:
112118

113119
ret
114-
expand_as_directive_test ENDP
120+
expand_as_directive_custom_test ENDP
115121

116122
end

0 commit comments

Comments
 (0)