From: Rafael Espindola Date: Sat, 16 Jun 2012 18:03:25 +0000 (+0000) Subject: Implement irpc. Extracted from a patch by the PaX team. I just added the test. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=fc9216eb5a437719b3a53d88d79833a8abc93fee;p=oota-llvm.git 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 --- diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index f2618e190af..744514af6c5 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 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 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 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"); diff --git a/test/MC/AsmParser/macro-irpc.s b/test/MC/AsmParser/macro-irpc.s new file mode 100644 index 00000000000..ea5efbfb245 --- /dev/null +++ b/test/MC/AsmParser/macro-irpc.s @@ -0,0 +1,9 @@ +// RUN: llvm-mc -triple x86_64-unknown-unknown %s | FileCheck %s + +.irpc foo,123 + .long \foo +.endr + +// CHECK: long 1 +// CHECK: long 2 +// CHECK: long 3