Skip to content

Commit e70f376

Browse files
committed
[MCParser] Simplify macro-like body expansion
Make it easy to support argument expansion in the altmacro mode.
1 parent 1ed84a8 commit e70f376

File tree

1 file changed

+73
-106
lines changed

1 file changed

+73
-106
lines changed

llvm/lib/MC/MCParser/AsmParser.cpp

Lines changed: 73 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -2505,129 +2505,96 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, MCAsmMacro &Macro,
25052505
// A macro without parameters is handled differently on Darwin:
25062506
// gas accepts no arguments and does no substitutions
25072507
StringRef Body = Macro.Body;
2508-
while (!Body.empty()) {
2509-
// Scan for the next substitution.
2510-
std::size_t End = Body.size(), Pos = 0;
2511-
for (; Pos != End; ++Pos) {
2512-
// Check for a substitution or escape.
2513-
if (IsDarwin && !NParameters) {
2514-
// This macro has no parameters, look for $0, $1, etc.
2515-
if (Body[Pos] != '$' || Pos + 1 == End)
2516-
continue;
2508+
size_t I = 0, End = Body.size();
2509+
while (I != End) {
2510+
if (Body[I] == '\\' && I + 1 != End) {
2511+
// Check for \@ and \+ pseudo variables.
2512+
if (EnableAtPseudoVariable && Body[I + 1] == '@') {
2513+
OS << NumOfMacroInstantiations;
2514+
I += 2;
2515+
continue;
2516+
}
2517+
if (Body[I + 1] == '+') {
2518+
OS << Macro.Count;
2519+
I += 2;
2520+
continue;
2521+
}
2522+
if (Body[I + 1] == '(' && Body[I + 2] == ')') {
2523+
I += 3;
2524+
continue;
2525+
}
25172526

2518-
char Next = Body[Pos + 1];
2519-
if (Next == '$' || Next == 'n' ||
2520-
isdigit(static_cast<unsigned char>(Next)))
2527+
size_t Pos = ++I;
2528+
while (I != End && isIdentifierChar(Body[I]))
2529+
++I;
2530+
StringRef Argument(Body.data() + Pos, I - Pos);
2531+
unsigned Index = 0;
2532+
for (; Index < NParameters; ++Index)
2533+
if (Parameters[Index].Name == Argument)
25212534
break;
2535+
if (Index == NParameters) {
2536+
OS << '\\' << Argument;
25222537
} else {
2523-
// This macro has parameters, look for \foo, \bar, etc.
2524-
if (Body[Pos] == '\\' && Pos + 1 != End)
2525-
break;
2538+
bool VarargParameter = HasVararg && Index == (NParameters - 1);
2539+
for (const AsmToken &Token : A[Index]) {
2540+
// For altmacro mode, you can write '%expr'.
2541+
// The prefix '%' evaluates the expression 'expr'
2542+
// and uses the result as a string (e.g. replace %(1+2) with the
2543+
// string "3").
2544+
// Here, we identify the integer token which is the result of the
2545+
// absolute expression evaluation and replace it with its string
2546+
// representation.
2547+
if (AltMacroMode && Token.getString().front() == '%' &&
2548+
Token.is(AsmToken::Integer))
2549+
// Emit an integer value to the buffer.
2550+
OS << Token.getIntVal();
2551+
// Only Token that was validated as a string and begins with '<'
2552+
// is considered altMacroString!!!
2553+
else if (AltMacroMode && Token.getString().front() == '<' &&
2554+
Token.is(AsmToken::String)) {
2555+
OS << angleBracketString(Token.getStringContents());
2556+
}
2557+
// We expect no quotes around the string's contents when
2558+
// parsing for varargs.
2559+
else if (Token.isNot(AsmToken::String) || VarargParameter)
2560+
OS << Token.getString();
2561+
else
2562+
OS << Token.getStringContents();
2563+
}
25262564
}
2565+
continue;
25272566
}
25282567

2529-
// Add the prefix.
2530-
OS << Body.slice(0, Pos);
2531-
2532-
// Check if we reached the end.
2533-
if (Pos == End)
2534-
break;
2535-
2536-
if (IsDarwin && !NParameters) {
2537-
switch (Body[Pos + 1]) {
2568+
if (Body[I] == '$' && I + 1 != End && IsDarwin && !NParameters) {
2569+
// This macro has no parameters, look for $0, $1, etc.
2570+
switch (Body[I + 1]) {
25382571
// $$ => $
25392572
case '$':
25402573
OS << '$';
2541-
break;
2542-
2574+
I += 2;
2575+
continue;
25432576
// $n => number of arguments
25442577
case 'n':
25452578
OS << A.size();
2546-
break;
2547-
2548-
// $[0-9] => argument
2579+
I += 2;
2580+
continue;
25492581
default: {
2550-
// Missing arguments are ignored.
2551-
unsigned Index = Body[Pos + 1] - '0';
2552-
if (Index >= A.size())
2582+
if (!isDigit(Body[I + 1]))
25532583
break;
2554-
2555-
// Otherwise substitute with the token values, with spaces eliminated.
2556-
for (const AsmToken &Token : A[Index])
2557-
OS << Token.getString();
2558-
break;
2559-
}
2560-
}
2561-
Pos += 2;
2562-
} else {
2563-
// Check for \@ and \+ pseudo variables.
2564-
unsigned I = Pos + 1;
2565-
if (I + 1 != End) {
2566-
if (EnableAtPseudoVariable && Body[I] == '@') {
2567-
++I;
2568-
} else if (Body[I] == '+') {
2569-
++I;
2570-
} else {
2571-
while (isIdentifierChar(Body[I]) && I + 1 != End)
2572-
++I;
2573-
}
2574-
}
2575-
2576-
const char *Begin = Body.data() + Pos + 1;
2577-
StringRef Argument(Begin, I - (Pos + 1));
2578-
unsigned Index = 0;
2579-
2580-
if (Argument == "@") {
2581-
OS << NumOfMacroInstantiations;
2582-
Pos += 2;
2583-
} else if (Argument == "+") {
2584-
OS << Macro.Count;
2585-
Pos += 2;
2586-
} else {
2587-
for (; Index < NParameters; ++Index)
2588-
if (Parameters[Index].Name == Argument)
2589-
break;
2590-
2591-
if (Index == NParameters) {
2592-
if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
2593-
Pos += 3;
2594-
else {
2595-
OS << '\\' << Argument;
2596-
Pos = I;
2597-
}
2598-
} else {
2599-
bool VarargParameter = HasVararg && Index == (NParameters - 1);
2584+
// $[0-9] => argument
2585+
// Missing arguments are ignored.
2586+
unsigned Index = Body[I + 1] - '0';
2587+
if (Index < A.size())
26002588
for (const AsmToken &Token : A[Index])
2601-
// For altmacro mode, you can write '%expr'.
2602-
// The prefix '%' evaluates the expression 'expr'
2603-
// and uses the result as a string (e.g. replace %(1+2) with the
2604-
// string "3").
2605-
// Here, we identify the integer token which is the result of the
2606-
// absolute expression evaluation and replace it with its string
2607-
// representation.
2608-
if (AltMacroMode && Token.getString().front() == '%' &&
2609-
Token.is(AsmToken::Integer))
2610-
// Emit an integer value to the buffer.
2611-
OS << Token.getIntVal();
2612-
// Only Token that was validated as a string and begins with '<'
2613-
// is considered altMacroString!!!
2614-
else if (AltMacroMode && Token.getString().front() == '<' &&
2615-
Token.is(AsmToken::String)) {
2616-
OS << angleBracketString(Token.getStringContents());
2617-
}
2618-
// We expect no quotes around the string's contents when
2619-
// parsing for varargs.
2620-
else if (Token.isNot(AsmToken::String) || VarargParameter)
2621-
OS << Token.getString();
2622-
else
2623-
OS << Token.getStringContents();
2624-
2625-
Pos += 1 + Argument.size();
2626-
}
2589+
OS << Token.getString();
2590+
I += 2;
2591+
continue;
2592+
}
26272593
}
26282594
}
2629-
// Update the scan point.
2630-
Body = Body.substr(Pos);
2595+
2596+
OS << Body[I];
2597+
++I;
26312598
}
26322599

26332600
++Macro.Count;

0 commit comments

Comments
 (0)