diff options
Diffstat (limited to 'lib/MC/MCParser')
| -rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 87 | ||||
| -rw-r--r-- | lib/MC/MCParser/DarwinAsmParser.cpp | 41 |
2 files changed, 89 insertions, 39 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())) diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp index 5662fea..18033d0 100644 --- a/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/lib/MC/MCParser/DarwinAsmParser.cpp @@ -50,6 +50,9 @@ public: AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump"); AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load"); AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section"); + AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(".pushsection"); + AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(".popsection"); + AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous"); AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>( ".secure_log_unique"); AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>( @@ -112,6 +115,9 @@ public: bool ParseDirectiveDumpOrLoad(StringRef, SMLoc); bool ParseDirectiveLsym(StringRef, SMLoc); bool ParseDirectiveSection(StringRef, SMLoc); + bool ParseDirectivePushSection(StringRef, SMLoc); + bool ParseDirectivePopSection(StringRef, SMLoc); + bool ParseDirectivePrevious(StringRef, SMLoc); bool ParseDirectiveSecureLogReset(StringRef, SMLoc); bool ParseDirectiveSecureLogUnique(StringRef, SMLoc); bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc); @@ -297,7 +303,7 @@ public: }; -} +} // end anonymous namespace bool DarwinAsmParser::ParseSectionSwitch(const char *Segment, const char *Section, @@ -457,6 +463,37 @@ bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) { return false; } +/// ParseDirectivePushSection: +/// ::= .pushsection identifier (',' identifier)* +bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) { + getStreamer().PushSection(); + + if (ParseDirectiveSection(S, Loc)) { + getStreamer().PopSection(); + return true; + } + + return false; +} + +/// ParseDirectivePopSection: +/// ::= .popsection +bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) { + if (!getStreamer().PopSection()) + return TokError(".popsection without corresponding .pushsection"); + return false; +} + +/// ParseDirectivePrevious: +/// ::= .previous +bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { + const MCSection *PreviousSection = getStreamer().getPreviousSection(); + if (PreviousSection == NULL) + return TokError(".previous without corresponding .section"); + getStreamer().SwitchSection(PreviousSection); + return false; +} + /// ParseDirectiveSecureLogUnique /// ::= .secure_log_unique ... message ... bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { @@ -707,4 +744,4 @@ MCAsmParserExtension *createDarwinAsmParser() { return new DarwinAsmParser; } -} +} // end llvm namespace |
