mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 21:32:10 +00:00
MC: Better management of macro arguments
The linux kernel makes uses of a GAS `feature' which substitutes nothing for macro arguments which aren't specified. Proper support for these kind of macro arguments necessitated a cleanup of differences between `GAS' and `Darwin' dialect macro processing. Differential Revision: http://llvm-reviews.chandlerc.com/D2634 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200409 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fb70e11bbc
commit
654247c3ea
@ -287,11 +287,8 @@ private:
|
||||
/// \brief Handle exit from macro instantiation.
|
||||
void handleMacroExit();
|
||||
|
||||
/// \brief Extract AsmTokens for a macro argument. If the argument delimiter
|
||||
/// is initially unknown, set it to AsmToken::Eof. It will be set to the
|
||||
/// correct delimiter by the method.
|
||||
bool parseMacroArgument(MCAsmMacroArgument &MA,
|
||||
AsmToken::TokenKind &ArgumentDelimiter);
|
||||
/// \brief Extract AsmTokens for a macro argument.
|
||||
bool parseMacroArgument(MCAsmMacroArgument &MA);
|
||||
|
||||
/// \brief Parse all macro arguments for a given macro.
|
||||
bool parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A);
|
||||
@ -1879,8 +1876,7 @@ private:
|
||||
};
|
||||
}
|
||||
|
||||
bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
|
||||
AsmToken::TokenKind &ArgumentDelimiter) {
|
||||
bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA) {
|
||||
unsigned ParenLevel = 0;
|
||||
unsigned AddTokens = 0;
|
||||
|
||||
@ -1891,14 +1887,8 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
|
||||
if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
|
||||
return TokError("unexpected token in macro instantiation");
|
||||
|
||||
if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) {
|
||||
// Spaces and commas cannot be mixed to delimit parameters
|
||||
if (ArgumentDelimiter == AsmToken::Eof)
|
||||
ArgumentDelimiter = AsmToken::Comma;
|
||||
else if (ArgumentDelimiter != AsmToken::Comma)
|
||||
return TokError("expected ' ' for macro argument separator");
|
||||
if (ParenLevel == 0 && Lexer.is(AsmToken::Comma))
|
||||
break;
|
||||
}
|
||||
|
||||
if (Lexer.is(AsmToken::Space)) {
|
||||
Lex(); // Eat spaces
|
||||
@ -1906,8 +1896,7 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
|
||||
// Spaces can delimit parameters, but could also be part an expression.
|
||||
// If the token after a space is an operator, add the token and the next
|
||||
// one into this argument
|
||||
if (ArgumentDelimiter == AsmToken::Space ||
|
||||
ArgumentDelimiter == AsmToken::Eof) {
|
||||
if (!IsDarwin) {
|
||||
if (isOperator(Lexer.getKind())) {
|
||||
// Check to see whether the token is used as an operator,
|
||||
// or part of an identifier
|
||||
@ -1917,9 +1906,6 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
|
||||
}
|
||||
|
||||
if (!AddTokens && ParenLevel == 0) {
|
||||
if (ArgumentDelimiter == AsmToken::Eof &&
|
||||
!isOperator(Lexer.getKind()))
|
||||
ArgumentDelimiter = AsmToken::Space;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1952,9 +1938,6 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
|
||||
bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
|
||||
MCAsmMacroArguments &A) {
|
||||
const unsigned NParameters = M ? M->Parameters.size() : 0;
|
||||
// Argument delimiter is initially unknown. It will be set by
|
||||
// parseMacroArgument()
|
||||
AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof;
|
||||
|
||||
// Parse two kinds of macro invocations:
|
||||
// - macros defined without any parameters accept an arbitrary number of them
|
||||
@ -1963,14 +1946,16 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
|
||||
++Parameter) {
|
||||
MCAsmMacroArgument MA;
|
||||
|
||||
if (parseMacroArgument(MA, ArgumentDelimiter))
|
||||
if (parseMacroArgument(MA))
|
||||
return true;
|
||||
|
||||
if (!MA.empty() || !NParameters)
|
||||
if (!MA.empty() || (!NParameters && !Lexer.is(AsmToken::EndOfStatement)))
|
||||
A.push_back(MA);
|
||||
else if (NParameters) {
|
||||
if (!M->Parameters[Parameter].second.empty())
|
||||
A.push_back(M->Parameters[Parameter].second);
|
||||
else
|
||||
A.push_back(MA);
|
||||
}
|
||||
|
||||
// At the end of the statement, fill in remaining arguments that have
|
||||
@ -1978,12 +1963,7 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
|
||||
// required but missing
|
||||
if (Lexer.is(AsmToken::EndOfStatement)) {
|
||||
if (NParameters && Parameter < NParameters - 1) {
|
||||
if (M->Parameters[Parameter + 1].second.empty())
|
||||
return TokError("macro argument '" +
|
||||
Twine(M->Parameters[Parameter + 1].first) +
|
||||
"' is missing");
|
||||
else
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -2021,12 +2001,6 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
|
||||
if (parseMacroArguments(M, A))
|
||||
return true;
|
||||
|
||||
// Remove any trailing empty arguments. Do this after-the-fact as we have
|
||||
// to keep empty arguments in the middle of the list or positionality
|
||||
// gets off. e.g., "foo 1, , 2" vs. "foo 1, 2,"
|
||||
while (!A.empty() && A.back().empty())
|
||||
A.pop_back();
|
||||
|
||||
// Macro instantiation is lexical, unfortunately. We construct a new buffer
|
||||
// to hold the macro body with substitutions.
|
||||
SmallString<256> Buf;
|
||||
@ -3113,28 +3087,21 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
|
||||
return TokError("expected identifier in '.macro' directive");
|
||||
|
||||
MCAsmMacroParameters Parameters;
|
||||
// Argument delimiter is initially unknown. It will be set by
|
||||
// parseMacroArgument()
|
||||
AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof;
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
for (;;) {
|
||||
MCAsmMacroParameter Parameter;
|
||||
if (parseIdentifier(Parameter.first))
|
||||
return TokError("expected identifier in '.macro' directive");
|
||||
while (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||
MCAsmMacroParameter Parameter;
|
||||
if (parseIdentifier(Parameter.first))
|
||||
return TokError("expected identifier in '.macro' directive");
|
||||
|
||||
if (getLexer().is(AsmToken::Equal)) {
|
||||
Lex();
|
||||
if (parseMacroArgument(Parameter.second, ArgumentDelimiter))
|
||||
return true;
|
||||
}
|
||||
|
||||
Parameters.push_back(Parameter);
|
||||
|
||||
if (getLexer().is(AsmToken::Comma))
|
||||
Lex();
|
||||
else if (getLexer().is(AsmToken::EndOfStatement))
|
||||
break;
|
||||
if (getLexer().is(AsmToken::Equal)) {
|
||||
Lex();
|
||||
if (parseMacroArgument(Parameter.second))
|
||||
return true;
|
||||
}
|
||||
|
||||
Parameters.push_back(Parameter);
|
||||
|
||||
if (getLexer().is(AsmToken::Comma))
|
||||
Lex();
|
||||
}
|
||||
|
||||
// Eat the end of statement.
|
||||
|
@ -86,12 +86,8 @@ test8 x - y, z, 1
|
||||
// CHECK: .globl "1 2 3"
|
||||
test9 1, 2,3
|
||||
|
||||
// CHECK: .globl "1,23,"
|
||||
test8 1,2 3
|
||||
// CHECK-ERRORS: error: macro argument '_c' is missing
|
||||
// CHECK-ERRORS-NEXT: test8 1,2 3
|
||||
// CHECK-ERRORS-NEXT: ^
|
||||
|
||||
// CHECK: .globl "12,3,"
|
||||
test8 1 2, 3
|
||||
// CHECK-ERRORS: error: macro argument '_c' is missing
|
||||
// CHECK-ERRORS-NEXT:test8 1 2, 3
|
||||
// CHECK-ERRORS-NEXT: ^
|
||||
|
@ -32,17 +32,21 @@ test2 10
|
||||
// CHECK: .ascii "1 2 3 \003"
|
||||
test3 1, 2, 3
|
||||
|
||||
// FIXME: test3 1, 2 3 should be treated like test 1, 2, 3
|
||||
// CHECK: .ascii "1 2 3 \003"
|
||||
test3 1, 2 3
|
||||
|
||||
// FIXME: remove the n argument from the remaining test3 examples
|
||||
// CHECK: .ascii "1 (23) n \n"
|
||||
test3 1, (2 3), n
|
||||
.macro test3_prime _a _b _c
|
||||
.ascii "\_a \_b \_c"
|
||||
.endm
|
||||
|
||||
// CHECK: .ascii "1 (23) n \n"
|
||||
test3 1 (2 3) n
|
||||
// CHECK: .ascii "1 (23) "
|
||||
test3_prime 1, (2 3)
|
||||
|
||||
// CHECK: .ascii "1 2 n \n"
|
||||
test3 1 2 n
|
||||
// CHECK: .ascii "1 (23) "
|
||||
test3_prime 1 (2 3)
|
||||
|
||||
// CHECK: .ascii "1 2 "
|
||||
test3_prime 1 2
|
||||
|
||||
.macro test5 _a
|
||||
.globl \_a
|
||||
@ -82,12 +86,8 @@ test8 x - y z 1
|
||||
// CHECK: .ascii "1 2 3"
|
||||
test9 1, 2,3
|
||||
|
||||
// CHECK: .ascii "1,2,3"
|
||||
test8 1,2 3
|
||||
// CHECK-ERRORS: error: macro argument '_c' is missing
|
||||
// CHECK-ERRORS-NEXT: test8 1,2 3
|
||||
// CHECK-ERRORS-NEXT: ^
|
||||
|
||||
// CHECK: .ascii "1,2,3"
|
||||
test8 1 2, 3
|
||||
// CHECK-ERRORS: error: expected ' ' for macro argument separator
|
||||
// CHECK-ERRORS-NEXT:test8 1 2, 3
|
||||
// CHECK-ERRORS-NEXT: ^
|
||||
|
Loading…
Reference in New Issue
Block a user