@@ -765,6 +765,19 @@ class MasmParser : public MCAsmParser {
765
765
std::optional<std::string> evaluateBuiltinTextMacro (BuiltinSymbol Symbol,
766
766
SMLoc StartLoc);
767
767
768
+ // Generic (target and platform independent) directive parsing.
769
+ enum BuiltinFunction {
770
+ BI_NO_FUNCTION, // Placeholder
771
+ BI_CATSTR,
772
+ };
773
+
774
+ // / Maps builtin name --> BuiltinFunction enum, for builtins handled by this
775
+ // / class.
776
+ StringMap<BuiltinFunction> BuiltinFunctionMap;
777
+
778
+ bool evaluateBuiltinMacroFunction (BuiltinFunction Function, StringRef Name,
779
+ std::string &Res);
780
+
768
781
// ".ascii", ".asciz", ".string"
769
782
bool parseDirectiveAscii (StringRef IDVal, bool ZeroTerminated);
770
783
@@ -946,7 +959,7 @@ class MasmParser : public MCAsmParser {
946
959
bool parseDirectiveEcho (SMLoc DirectiveLoc);
947
960
948
961
void initializeDirectiveKindMap ();
949
- void initializeBuiltinSymbolMap ();
962
+ void initializeBuiltinSymbolMaps ();
950
963
};
951
964
952
965
} // end anonymous namespace
@@ -986,7 +999,7 @@ MasmParser::MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
986
999
987
1000
initializeDirectiveKindMap ();
988
1001
PlatformParser->Initialize (*this );
989
- initializeBuiltinSymbolMap ();
1002
+ initializeBuiltinSymbolMaps ();
990
1003
991
1004
NumOfMacroInstantiations = 0 ;
992
1005
}
@@ -1071,15 +1084,25 @@ bool MasmParser::expandMacros() {
1071
1084
}
1072
1085
1073
1086
std::optional<std::string> ExpandedValue;
1074
- auto BuiltinIt = BuiltinSymbolMap.find (IDLower);
1075
- if (BuiltinIt != BuiltinSymbolMap.end ()) {
1087
+
1088
+ if (auto BuiltinIt = BuiltinSymbolMap.find (IDLower);
1089
+ BuiltinIt != BuiltinSymbolMap.end ()) {
1076
1090
ExpandedValue =
1077
1091
evaluateBuiltinTextMacro (BuiltinIt->getValue (), Tok.getLoc ());
1078
- } else {
1079
- auto VarIt = Variables.find (IDLower);
1080
- if (VarIt != Variables.end () && VarIt->getValue ().IsText ) {
1081
- ExpandedValue = VarIt->getValue ().TextValue ;
1092
+ } else if (auto BuiltinFuncIt = BuiltinFunctionMap.find (IDLower);
1093
+ BuiltinFuncIt != BuiltinFunctionMap.end ()) {
1094
+ StringRef Name;
1095
+ if (parseIdentifier (Name)) {
1096
+ return true ;
1097
+ }
1098
+ std::string Res;
1099
+ if (evaluateBuiltinMacroFunction (BuiltinFuncIt->getValue (), Name, Res)) {
1100
+ return true ;
1082
1101
}
1102
+ ExpandedValue = Res;
1103
+ } else if (auto VarIt = Variables.find (IDLower);
1104
+ VarIt != Variables.end () && VarIt->getValue ().IsText ) {
1105
+ ExpandedValue = VarIt->getValue ().TextValue ;
1083
1106
}
1084
1107
1085
1108
if (!ExpandedValue)
@@ -3104,6 +3127,18 @@ bool MasmParser::parseTextItem(std::string &Data) {
3104
3127
continue ;
3105
3128
}
3106
3129
3130
+ // Try to resolve as a built-in macro function
3131
+ auto BuiltinFuncIt = BuiltinFunctionMap.find (ID.lower ());
3132
+ if (BuiltinFuncIt != BuiltinFunctionMap.end ()) {
3133
+ Data.clear ();
3134
+ if (evaluateBuiltinMacroFunction (BuiltinFuncIt->getValue (), ID, Data)) {
3135
+ return true ;
3136
+ }
3137
+ ID = StringRef (Data);
3138
+ Expanded = true ;
3139
+ continue ;
3140
+ }
3141
+
3107
3142
// Try to resolve as a variable text macro
3108
3143
auto VarIt = Variables.find (ID.lower ());
3109
3144
if (VarIt != Variables.end ()) {
@@ -6110,7 +6145,7 @@ bool MasmParser::parseMSInlineAsm(
6110
6145
return false ;
6111
6146
}
6112
6147
6113
- void MasmParser::initializeBuiltinSymbolMap () {
6148
+ void MasmParser::initializeBuiltinSymbolMaps () {
6114
6149
// Numeric built-ins (supported in all versions)
6115
6150
BuiltinSymbolMap[" @version" ] = BI_VERSION;
6116
6151
BuiltinSymbolMap[" @line" ] = BI_LINE;
@@ -6122,6 +6157,9 @@ void MasmParser::initializeBuiltinSymbolMap() {
6122
6157
BuiltinSymbolMap[" @filename" ] = BI_FILENAME;
6123
6158
BuiltinSymbolMap[" @curseg" ] = BI_CURSEG;
6124
6159
6160
+ // Function built-ins (supported in all versions)
6161
+ BuiltinFunctionMap[" @catstr" ] = BI_CATSTR;
6162
+
6125
6163
// Some built-ins exist only for MASM32 (32-bit x86)
6126
6164
if (getContext ().getSubtargetInfo ()->getTargetTriple ().getArch () ==
6127
6165
Triple::x86) {
@@ -6195,6 +6233,48 @@ MasmParser::evaluateBuiltinTextMacro(BuiltinSymbol Symbol, SMLoc StartLoc) {
6195
6233
llvm_unreachable (" unhandled built-in symbol" );
6196
6234
}
6197
6235
6236
+ bool MasmParser::evaluateBuiltinMacroFunction (BuiltinFunction Function,
6237
+ StringRef Name,
6238
+ std::string &Res) {
6239
+ if (parseToken (AsmToken::LParen, " invoking macro function '" + Name +
6240
+ " ' requires arguments in parentheses" )) {
6241
+ return true ;
6242
+ }
6243
+
6244
+ MCAsmMacroParameters P;
6245
+ switch (Function) {
6246
+ default :
6247
+ return true ;
6248
+ case BI_CATSTR:
6249
+ break ;
6250
+ }
6251
+ MCAsmMacro M (Name, " " , P, {}, true );
6252
+
6253
+ MCAsmMacroArguments A;
6254
+ if (parseMacroArguments (&M, A, AsmToken::RParen) || parseRParen ()) {
6255
+ return true ;
6256
+ }
6257
+
6258
+ switch (Function) {
6259
+ default :
6260
+ llvm_unreachable (" unhandled built-in function" );
6261
+ case BI_CATSTR: {
6262
+ for (const MCAsmMacroArgument &Arg : A) {
6263
+ for (const AsmToken &Tok : Arg) {
6264
+ if (Tok.is (AsmToken::String)) {
6265
+ Res.append (Tok.getStringContents ());
6266
+ } else {
6267
+ Res.append (Tok.getString ());
6268
+ }
6269
+ }
6270
+ }
6271
+ return false ;
6272
+ }
6273
+ }
6274
+ llvm_unreachable (" unhandled built-in function" );
6275
+ return true ;
6276
+ }
6277
+
6198
6278
// / Create an MCAsmParser instance.
6199
6279
MCAsmParser *llvm::createMCMasmParser (SourceMgr &SM, MCContext &C,
6200
6280
MCStreamer &Out, const MCAsmInfo &MAI,
0 commit comments