Store output and input operands as well as clobber information in the AsmStmt. Ted, could you please review the serialization/deserialization code?

llvm-svn: 44266
This commit is contained in:
Anders Carlsson 2007-11-22 01:36:19 +00:00
parent 091a059c55
commit 94ea8aab34
9 changed files with 241 additions and 22 deletions

View File

@ -111,6 +111,29 @@ bool Stmt::hasImplicitControlFlow() const {
}
}
AsmStmt::AsmStmt(SourceLocation asmloc,
unsigned numoutputs,
unsigned numinputs,
std::string *names,
StringLiteral **constraints,
Expr **exprs,
StringLiteral *asmstr,
unsigned numclobbers,
StringLiteral **clobbers,
SourceLocation rparenloc)
: Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
, NumOutputs(numoutputs), NumInputs(numinputs)
{
for (unsigned i = 0, e = numinputs + numoutputs; i != e; i++) {
Names.push_back(names[i]);
Exprs.push_back(exprs[i]);
Constraints.push_back(constraints[i]);
}
for (unsigned i = 0; i != numclobbers; i++)
Clobbers.push_back(clobbers[i]);
}
//===----------------------------------------------------------------------===//
// Child Iterators for iterating over subexpressions/substatements
//===----------------------------------------------------------------------===//

View File

@ -328,6 +328,57 @@ void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
Indent() << "asm (";
VisitStringLiteral(Node->getAsmString());
// Outputs
if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
Node->getNumClobbers() != 0)
OS << " : ";
for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
if (i != 0)
OS << ", ";
if (!Node->getOutputName(i).empty()) {
OS << '[';
OS << Node->getOutputName(i);
OS << "] ";
}
VisitStringLiteral(Node->getOutputConstraint(i));
OS << " ";
Visit(Node->getOutputExpr(i));
}
// Inputs
if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
OS << " : ";
for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
if (i != 0)
OS << ", ";
if (!Node->getInputName(i).empty()) {
OS << '[';
OS << Node->getInputName(i);
OS << "] ";
}
VisitStringLiteral(Node->getInputConstraint(i));
OS << " ";
Visit(Node->getInputExpr(i));
}
// Clobbers
if (Node->getNumClobbers() != 0)
OS << " : ";
for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
if (i != 0)
OS << ", ";
VisitStringLiteral(Node->getClobber(i));
}
OS << ");\n";
}

View File

@ -197,8 +197,27 @@ ArraySubscriptExpr* ArraySubscriptExpr::CreateImpl(Deserializer& D) {
void AsmStmt::EmitImpl(Serializer& S) const {
S.Emit(AsmLoc);
getAsmString()->EmitImpl(S);
S.Emit(RParenLoc);
S.EmitInt(NumOutputs);
S.EmitInt(NumInputs);
unsigned size = NumOutputs + NumInputs;
for (unsigned i = 0; i < size; ++i)
S.EmitCStr(Names[i].c_str());
for (unsigned i = 0; i < size; ++i)
Constraints[i]->EmitImpl(S);
for (unsigned i = 0; i < size; ++i)
S.EmitOwnedPtr(Exprs[i]);
S.EmitInt(Clobbers.size());
for (unsigned i = 0, e = Clobbers.size(); i != e; ++i)
Clobbers[i]->EmitImpl(S);
}
AsmStmt* AsmStmt::CreateImpl(Deserializer& D) {
@ -206,7 +225,37 @@ AsmStmt* AsmStmt::CreateImpl(Deserializer& D) {
StringLiteral *AsmStr = StringLiteral::CreateImpl(D);
SourceLocation PLoc = SourceLocation::ReadVal(D);
return new AsmStmt(ALoc, AsmStr, PLoc);
AsmStmt *Stmt = new AsmStmt(ALoc, 0, 0, 0, 0, 0,
AsmStr,
0, 0, PLoc);
Stmt->NumOutputs = D.ReadInt();
Stmt->NumInputs = D.ReadInt();
unsigned size = Stmt->NumOutputs + Stmt->NumInputs;
Stmt->Names.reserve(size);
for (unsigned i = 0; i < size; ++i) {
std::vector<char> data;
D.ReadCStr(data, false);
Stmt->Names.push_back(std::string(&data[0], data.size()));
}
Stmt->Constraints.reserve(size);
for (unsigned i = 0; i < size; ++i)
Stmt->Constraints.push_back(StringLiteral::CreateImpl(D));
Stmt->Exprs.reserve(size);
for (unsigned i = 0; i < size; ++i)
Stmt->Exprs.push_back(D.ReadOwnedPtr<Expr>());
unsigned NumClobbers = D.ReadInt();
Stmt->Clobbers.reserve(NumClobbers);
for (unsigned i = 0; i < NumClobbers; ++i)
Stmt->Clobbers.push_back(StringLiteral::CreateImpl(D));
return Stmt;
}
void BinaryOperator::EmitImpl(Serializer& S) const {

View File

@ -946,12 +946,25 @@ Parser::StmtResult Parser::ParseAsmStatement() {
ExprResult AsmString = ParseAsmStringLiteral();
if (AsmString.isInvalid)
return true;
// Parse Outputs, if present.
ParseAsmOperandsOpt();
llvm::SmallVector<std::string, 4> Names;
llvm::SmallVector<ExprTy*, 4> Constraints;
llvm::SmallVector<ExprTy*, 4> Exprs;
// Parse Outputs, if present.
ParseAsmOperandsOpt(Names, Constraints, Exprs);
unsigned NumOutputs = Names.size();
// Parse Inputs, if present.
ParseAsmOperandsOpt();
ParseAsmOperandsOpt(Names, Constraints, Exprs);
assert(Names.size() == Constraints.size() &&
Constraints.size() == Exprs.size()
&& "Input operand size mismatch!");
unsigned NumInputs = Names.size() - NumOutputs;
llvm::SmallVector<ExprTy*, 4> Clobbers;
// Parse the clobbers, if present.
if (Tok.is(tok::colon)) {
@ -959,8 +972,13 @@ Parser::StmtResult Parser::ParseAsmStatement() {
// Parse the asm-string list for clobbers.
while (1) {
ParseAsmStringLiteral();
ExprResult Clobber = ParseAsmStringLiteral();
if (Clobber.isInvalid)
break;
Clobbers.push_back(Clobber.Val);
if (Tok.isNot(tok::comma)) break;
ConsumeToken();
}
@ -968,8 +986,11 @@ Parser::StmtResult Parser::ParseAsmStatement() {
SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc);
// FIXME: Pass all the details down to the action.
return Actions.ActOnAsmStmt(AsmLoc, AsmString.Val, RParenLoc);
return Actions.ActOnAsmStmt(AsmLoc, NumOutputs, NumInputs,
&Names[0], &Constraints[0], &Exprs[0],
AsmString.Val,
Clobbers.size(), &Clobbers[0],
RParenLoc);
}
/// ParseAsmOperands - Parse the asm-operands production as used by
@ -984,7 +1005,9 @@ Parser::StmtResult Parser::ParseAsmStatement() {
/// asm-string-literal '(' expression ')'
/// '[' identifier ']' asm-string-literal '(' expression ')'
///
void Parser::ParseAsmOperandsOpt() {
void Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
llvm::SmallVectorImpl<ExprTy*> &Constraints,
llvm::SmallVectorImpl<ExprTy*> &Exprs) {
// Only do anything if this operand is present.
if (Tok.isNot(tok::colon)) return;
ConsumeToken();
@ -993,7 +1016,7 @@ void Parser::ParseAsmOperandsOpt() {
if (!isTokenStringLiteral() && Tok.isNot(tok::l_square))
return;
while (1) {
while (1) {
// Read the [id] if present.
if (Tok.is(tok::l_square)) {
SourceLocation Loc = ConsumeBracket();
@ -1004,13 +1027,20 @@ void Parser::ParseAsmOperandsOpt() {
return;
}
// Eat the identifier, FIXME: capture it.
IdentifierInfo *II = Tok.getIdentifierInfo();
ConsumeToken();
Names.push_back(std::string(II->getName(), II->getLength()));
MatchRHSPunctuation(tok::r_square, Loc);
}
} else
Names.push_back(std::string());
ParseAsmStringLiteral();
ExprResult Constraint = ParseAsmStringLiteral();
if (Constraint.isInvalid) {
SkipUntil(tok::r_paren);
return;
}
Constraints.push_back(Constraint.Val);
if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after, "asm operand");
@ -1024,7 +1054,7 @@ void Parser::ParseAsmOperandsOpt() {
SkipUntil(tok::r_paren);
return;
}
Exprs.push_back(Res.Val);
// Eat the comma and continue parsing if it exists.
if (Tok.isNot(tok::comma)) return;
ConsumeToken();

View File

@ -347,7 +347,14 @@ public:
ExprTy *RetValExp);
virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
unsigned NumOutputs,
unsigned NumInputs,
std::string *Names,
ExprTy **Constraints,
ExprTy **Exprs,
ExprTy *AsmString,
unsigned NumClobbers,
ExprTy **Clobbers,
SourceLocation RParenLoc);
virtual StmtResult ActOnObjcAtCatchStmt(SourceLocation AtLoc,

View File

@ -645,11 +645,29 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) {
}
Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
unsigned NumOutputs,
unsigned NumInputs,
std::string *Names,
ExprTy **Constraints,
ExprTy **Exprs,
ExprTy *AsmString,
unsigned NumClobbers,
ExprTy **Clobbers,
SourceLocation RParenLoc) {
Expr *E = (Expr *)AsmString;
return new AsmStmt(AsmLoc, cast<StringLiteral>(E), RParenLoc);
// FIXME: Make sure that the expressions are valid.
return new AsmStmt(AsmLoc,
NumOutputs,
NumInputs,
Names,
reinterpret_cast<StringLiteral**>(Constraints),
reinterpret_cast<Expr**>(Exprs),
cast<StringLiteral>(E),
NumClobbers,
reinterpret_cast<StringLiteral**>(Clobbers),
RParenLoc);
}
Action::StmtResult

View File

@ -706,16 +706,47 @@ public:
class AsmStmt : public Stmt {
SourceLocation AsmLoc, RParenLoc;
StringLiteral *AsmStr;
// FIXME: This doesn't capture most of the interesting pieces.
unsigned NumOutputs;
unsigned NumInputs;
llvm::SmallVector<std::string, 4> Names;
llvm::SmallVector<StringLiteral*, 4> Constraints;
llvm::SmallVector<Expr*, 4> Exprs;
llvm::SmallVector<StringLiteral*, 4> Clobbers;
public:
AsmStmt(SourceLocation asmloc, StringLiteral *asmstr,
SourceLocation rparenloc)
: Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc),
AsmStr(asmstr) {}
AsmStmt(SourceLocation asmloc,
unsigned numoutputs,
unsigned numinputs,
std::string *names,
StringLiteral **constraints,
Expr **exprs,
StringLiteral *asmstr,
unsigned numclobbers,
StringLiteral **clobbers,
SourceLocation rparenloc);
unsigned getNumOutputs() const { return NumOutputs; }
const std::string &getOutputName(unsigned i) const
{ return Names[i]; }
StringLiteral *getOutputConstraint(unsigned i)
{ return Constraints[i]; }
Expr *getOutputExpr(unsigned i) { return Exprs[i]; }
unsigned getNumInputs() const { return NumInputs; }
const std::string &getInputName(unsigned i) const
{ return Names[i + NumOutputs]; }
StringLiteral *getInputConstraint(unsigned i)
{ return Constraints[i + NumOutputs]; }
Expr *getInputExpr(unsigned i) { return Exprs[i + NumOutputs]; }
const StringLiteral *getAsmString() const { return AsmStr; }
StringLiteral *getAsmString() { return AsmStr; }
unsigned getNumClobbers() const { return Clobbers.size(); }
StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
virtual SourceRange getSourceRange() const {
return SourceRange(AsmLoc, RParenLoc);
}

View File

@ -287,7 +287,14 @@ public:
return 0;
}
virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
unsigned NumOutputs,
unsigned NumInputs,
std::string *Names,
ExprTy **Constraints,
ExprTy **Exprs,
ExprTy *AsmString,
unsigned NumClobbers,
ExprTy **Clobbers,
SourceLocation RParenLoc) {
return 0;
}

View File

@ -388,7 +388,10 @@ private:
StmtResult ParseAsmStatement();
StmtResult ParseObjCTryStmt(SourceLocation atLoc);
StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
void ParseAsmOperandsOpt();
void ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
llvm::SmallVectorImpl<ExprTy*> &Constraints,
llvm::SmallVectorImpl<ExprTy*> &Exprs);
//===--------------------------------------------------------------------===//
// C99 6.7: Declarations.