Implement irpc. Extracted from a patch by the PaX team. I just added the test.

llvm-svn: 158604
This commit is contained in:
Rafael Espindola 2012-06-16 18:03:25 +00:00
parent 390edb0d91
commit f70bea93e2
2 changed files with 66 additions and 0 deletions

View File

@ -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");

View File

@ -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