forked from OSchip/llvm-project
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:
parent
091a059c55
commit
94ea8aab34
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue