diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-06-16 18:03:25 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-06-16 18:03:25 +0000 |
commit | fc9216eb5a437719b3a53d88d79833a8abc93fee (patch) | |
tree | af19c4f8f1c8b9353766c079f52546e7873efe68 /lib/MC | |
parent | 19e5015e5fbacbe1026e2d76d571b591003b4fea (diff) |
Implement irpc. Extracted from a patch by the PaX team. I just added the test.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158604 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index f2618e190a..744514af6c 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -277,6 +277,7 @@ private: raw_svector_ostream &OS); bool ParseDirectiveRept(SMLoc DirectiveLoc); // ".rept" bool ParseDirectiveIrp(SMLoc DirectiveLoc); // ".irp" + bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc" bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr" }; @@ -1280,6 +1281,8 @@ bool AsmParser::ParseStatement() { return ParseDirectiveRept(IDLoc); if (IDVal == ".irp") return ParseDirectiveIrp(IDLoc); + if (IDVal == ".irpc") + return ParseDirectiveIrpc(IDLoc); if (IDVal == ".endr") return ParseDirectiveEndr(IDLoc); @@ -3324,6 +3327,60 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) { return false; } +/// ParseDirectiveIrpc +/// ::= .irpc symbol,values +bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { + std::vector<StringRef> Parameters; + StringRef Parameter; + + if (ParseIdentifier(Parameter)) + return TokError("expected identifier in '.irpc' directive"); + + Parameters.push_back(Parameter); + + if (Lexer.isNot(AsmToken::Comma)) + return TokError("expected comma in '.irpc' directive"); + + Lex(); + + std::vector<MacroArgument> A; + if (ParseMacroArguments(0, A)) + return true; + + if (A.size() != 1 || A.front().size() != 1) + return TokError("unexpected token in '.irpc' directive"); + + // Eat the end of statement. + Lex(); + + // Lex the irpc definition. + Macro *M = ParseMacroLikeBody(DirectiveLoc); + if (!M) + return true; + + // Macro instantiation is lexical, unfortunately. We construct a new buffer + // to hold the macro body with substitutions. + SmallString<256> Buf; + raw_svector_ostream OS(Buf); + + StringRef Values = A.front().front().getString(); + std::size_t I, End = Values.size(); + for (I = 0; I < End; ++I) { + MacroArgument Arg; + Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I+1))); + + std::vector<MacroArgument> Args; + Args.push_back(Arg); + + if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc())) + return true; + } + + InstantiateMacroLikeBody(M, DirectiveLoc, OS); + + return false; +} + bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) { if (ActiveMacros.empty()) return TokError("unexpected '.endr' directive, no current .rept"); |