diff options
Diffstat (limited to 'lib/MC/MCParser/AsmParser.cpp')
| -rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 87 |
1 files changed, 50 insertions, 37 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 2daad0a..240c10b 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -46,14 +46,17 @@ namespace { /// \brief Helper class for tracking macro definitions. typedef std::vector<AsmToken> MacroArgument; +typedef std::vector<MacroArgument> MacroArguments; +typedef StringRef MacroParameter; +typedef std::vector<MacroParameter> MacroParameters; struct Macro { StringRef Name; StringRef Body; - std::vector<StringRef> Parameters; + MacroParameters Parameters; public: - Macro(StringRef N, StringRef B, const std::vector<StringRef> &P) : + Macro(StringRef N, StringRef B, const MacroParameters &P) : Name(N), Body(B), Parameters(P) {} }; @@ -181,8 +184,8 @@ private: bool HandleMacroEntry(StringRef Name, SMLoc NameLoc, const Macro *M); bool expandMacro(raw_svector_ostream &OS, StringRef Body, - const std::vector<StringRef> &Parameters, - const std::vector<MacroArgument> &A, + const MacroParameters &Parameters, + const MacroArguments &A, const SMLoc &L); void HandleMacroExit(); @@ -207,7 +210,7 @@ private: void EatToEndOfStatement(); bool ParseMacroArgument(MacroArgument &MA); - bool ParseMacroArguments(const Macro *M, std::vector<MacroArgument> &A); + bool ParseMacroArguments(const Macro *M, MacroArguments &A); /// \brief Parse up to the end of statement and a return the contents from the /// current token until the end of the statement; the current token on exit @@ -1451,9 +1454,17 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { NewDiag.print(0, OS); } +// FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The +// difference being that that function accepts '@' as part of identifiers and +// we can't do that. AsmLexer.cpp should probably be changed to handle +// '@' as a special case when needed. +static bool isIdentifierChar(char c) { + return isalnum(c) || c == '_' || c == '$' || c == '.'; +} + bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, - const std::vector<StringRef> &Parameters, - const std::vector<MacroArgument> &A, + const MacroParameters &Parameters, + const MacroArguments &A, const SMLoc &L) { unsigned NParameters = Parameters.size(); if (NParameters != 0 && NParameters != A.size()) @@ -1515,7 +1526,7 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, Pos += 2; } else { unsigned I = Pos + 1; - while (isalnum(Body[I]) && I + 1 != End) + while (isIdentifierChar(Body[I]) && I + 1 != End) ++I; const char *Begin = Body.data() + Pos +1; @@ -1555,8 +1566,6 @@ bool AsmParser::ParseMacroArgument(MacroArgument &MA) { unsigned ParenLevel = 0; for (;;) { - SMLoc LastTokenLoc; - if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) return TokError("unexpected token in macro instantiation"); @@ -1578,13 +1587,12 @@ bool AsmParser::ParseMacroArgument(MacroArgument &MA) { Lex(); } if (ParenLevel != 0) - return TokError("unbalanced parenthesises in macro argument"); + return TokError("unbalanced parentheses in macro argument"); return false; } // Parse the macro instantiation arguments. -bool AsmParser::ParseMacroArguments(const Macro *M, - std::vector<MacroArgument> &A) { +bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) { const unsigned NParameters = M ? M->Parameters.size() : 0; // Parse two kinds of macro invocations: @@ -1597,8 +1605,8 @@ bool AsmParser::ParseMacroArguments(const Macro *M, if (ParseMacroArgument(MA)) return true; - if (!MA.empty()) - A.push_back(MA); + A.push_back(MA); + if (Lexer.is(AsmToken::EndOfStatement)) return false; @@ -1615,17 +1623,23 @@ bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc, if (ActiveMacros.size() == 20) return TokError("macros cannot be nested more than 20 levels deep"); - std::vector<MacroArgument> MacroArguments; - if (ParseMacroArguments(M, MacroArguments)) + MacroArguments A; + 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; StringRef Body = M->Body; raw_svector_ostream OS(Buf); - if (expandMacro(OS, Body, M->Parameters, MacroArguments, getTok().getLoc())) + if (expandMacro(OS, Body, M->Parameters, A, getTok().getLoc())) return true; // We include the .endmacro in the buffer as our queue to exit the macro @@ -3065,14 +3079,14 @@ bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive, SMLoc DirectiveLoc) { StringRef Name; if (getParser().ParseIdentifier(Name)) - return TokError("expected identifier in directive"); + return TokError("expected identifier in '.macro' directive"); - std::vector<StringRef> Parameters; + MacroParameters Parameters; if (getLexer().isNot(AsmToken::EndOfStatement)) { - for(;;) { - StringRef Parameter; + for (;;) { + MacroParameter Parameter; if (getParser().ParseIdentifier(Parameter)) - return TokError("expected identifier in directive"); + return TokError("expected identifier in '.macro' directive"); Parameters.push_back(Parameter); if (getLexer().isNot(AsmToken::Comma)) @@ -3126,7 +3140,7 @@ bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive, /// ::= .endm /// ::= .endmacro bool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive, - SMLoc DirectiveLoc) { + SMLoc DirectiveLoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '" + Directive + "' directive"); @@ -3224,7 +3238,7 @@ Macro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) { // We Are Anonymous. StringRef Name; - std::vector<StringRef> Parameters; + MacroParameters Parameters; return new Macro(Name, Body, Parameters); } @@ -3270,8 +3284,8 @@ bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) { // Macro instantiation is lexical, unfortunately. We construct a new buffer // to hold the macro body with substitutions. SmallString<256> Buf; - std::vector<StringRef> Parameters; - const std::vector<MacroArgument> A; + MacroParameters Parameters; + MacroArguments A; raw_svector_ostream OS(Buf); while (Count--) { if (expandMacro(OS, M->Body, Parameters, A, getTok().getLoc())) @@ -3285,8 +3299,8 @@ bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) { /// ParseDirectiveIrp /// ::= .irp symbol,values bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) { - std::vector<StringRef> Parameters; - StringRef Parameter; + MacroParameters Parameters; + MacroParameter Parameter; if (ParseIdentifier(Parameter)) return TokError("expected identifier in '.irp' directive"); @@ -3298,7 +3312,7 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) { Lex(); - std::vector<MacroArgument> A; + MacroArguments A; if (ParseMacroArguments(0, A)) return true; @@ -3315,9 +3329,8 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) { SmallString<256> Buf; raw_svector_ostream OS(Buf); - for (std::vector<MacroArgument>::iterator i = A.begin(), e = A.end(); i != e; - ++i) { - std::vector<MacroArgument> Args; + for (MacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) { + MacroArguments Args; Args.push_back(*i); if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc())) @@ -3332,8 +3345,8 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) { /// ParseDirectiveIrpc /// ::= .irpc symbol,values bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { - std::vector<StringRef> Parameters; - StringRef Parameter; + MacroParameters Parameters; + MacroParameter Parameter; if (ParseIdentifier(Parameter)) return TokError("expected identifier in '.irpc' directive"); @@ -3345,7 +3358,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { Lex(); - std::vector<MacroArgument> A; + MacroArguments A; if (ParseMacroArguments(0, A)) return true; @@ -3371,7 +3384,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { MacroArgument Arg; Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I+1))); - std::vector<MacroArgument> Args; + MacroArguments Args; Args.push_back(Arg); if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc())) |
