@@ -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)
@@ -3199,6 +3222,18 @@ bool MasmParser::parseTextItem(std::string &Data) {
31993222 continue ;
32003223 }
32013224
3225+ // Try to resolve as a built-in macro function
3226+ auto BuiltinFuncIt = BuiltinFunctionMap.find (ID.lower ());
3227+ if (BuiltinFuncIt != BuiltinFunctionMap.end ()) {
3228+ Data.clear ();
3229+ if (evaluateBuiltinMacroFunction (BuiltinFuncIt->getValue (), ID, Data)) {
3230+ return true ;
3231+ }
3232+ ID = StringRef (Data);
3233+ Expanded = true ;
3234+ continue ;
3235+ }
3236+
32023237 // Try to resolve as a variable text macro
32033238 auto VarIt = Variables.find (ID.lower ());
32043239 if (VarIt != Variables.end ()) {
@@ -6206,7 +6241,7 @@ bool MasmParser::parseMSInlineAsm(
62066241 return false ;
62076242}
62086243
6209- void MasmParser::initializeBuiltinSymbolMap () {
6244+ void MasmParser::initializeBuiltinSymbolMaps () {
62106245 // Numeric built-ins (supported in all versions)
62116246 BuiltinSymbolMap[" @version" ] = BI_VERSION;
62126247 BuiltinSymbolMap[" @line" ] = BI_LINE;
@@ -6218,6 +6253,9 @@ void MasmParser::initializeBuiltinSymbolMap() {
62186253 BuiltinSymbolMap[" @filename" ] = BI_FILENAME;
62196254 BuiltinSymbolMap[" @curseg" ] = BI_CURSEG;
62206255
6256+ // Function built-ins (supported in all versions)
6257+ BuiltinFunctionMap[" @catstr" ] = BI_CATSTR;
6258+
62216259 // Some built-ins exist only for MASM32 (32-bit x86)
62226260 if (getContext ().getSubtargetInfo ()->getTargetTriple ().getArch () ==
62236261 Triple::x86) {
@@ -6291,6 +6329,48 @@ MasmParser::evaluateBuiltinTextMacro(BuiltinSymbol Symbol, SMLoc StartLoc) {
62916329 llvm_unreachable (" unhandled built-in symbol" );
62926330}
62936331
6332+ bool MasmParser::evaluateBuiltinMacroFunction (BuiltinFunction Function,
6333+ StringRef Name,
6334+ std::string &Res) {
6335+ if (parseToken (AsmToken::LParen, " invoking macro function '" + Name +
6336+ " ' requires arguments in parentheses" )) {
6337+ return true ;
6338+ }
6339+
6340+ MCAsmMacroParameters P;
6341+ switch (Function) {
6342+ default :
6343+ return true ;
6344+ case BI_CATSTR:
6345+ break ;
6346+ }
6347+ MCAsmMacro M (Name, " " , P, {}, true );
6348+
6349+ MCAsmMacroArguments A;
6350+ if (parseMacroArguments (&M, A, AsmToken::RParen) || parseRParen ()) {
6351+ return true ;
6352+ }
6353+
6354+ switch (Function) {
6355+ default :
6356+ llvm_unreachable (" unhandled built-in function" );
6357+ case BI_CATSTR: {
6358+ for (const MCAsmMacroArgument &Arg : A) {
6359+ for (const AsmToken &Tok : Arg) {
6360+ if (Tok.is (AsmToken::String)) {
6361+ Res.append (Tok.getStringContents ());
6362+ } else {
6363+ Res.append (Tok.getString ());
6364+ }
6365+ }
6366+ }
6367+ return false ;
6368+ }
6369+ }
6370+ llvm_unreachable (" unhandled built-in function" );
6371+ return true ;
6372+ }
6373+
62946374// / Create an MCAsmParser instance.
62956375MCAsmParser *llvm::createMCMasmParser (SourceMgr &SM, MCContext &C,
62966376 MCStreamer &Out, const MCAsmInfo &MAI,
0 commit comments