[ms-inline asm] Add constraints to MSAsmStmt. We don't currently compute

the constraints, so in the interim we speculatively assume a 'r' constraint.
This is expected to work for most cases on x86.

llvm-svn: 162784
This commit is contained in:
Chad Rosier 2012-08-28 20:28:20 +00:00
parent 6cb2080e5e
commit 3dd7bf2c86
3 changed files with 43 additions and 30 deletions

View File

@ -1677,6 +1677,7 @@ class MSAsmStmt : public AsmStmt {
unsigned NumAsmToks;
Token *AsmToks;
StringRef *Constraints;
StringRef *Clobbers;
public:
@ -1684,12 +1685,12 @@ public:
bool issimple, bool isvolatile, ArrayRef<Token> asmtoks,
ArrayRef<IdentifierInfo*> inputs, ArrayRef<IdentifierInfo*> outputs,
ArrayRef<Expr*> inputexprs, ArrayRef<Expr*> outputexprs,
StringRef asmstr, ArrayRef<StringRef> clobbers,
SourceLocation endloc);
StringRef asmstr, ArrayRef<StringRef> constraints,
ArrayRef<StringRef> clobbers, SourceLocation endloc);
/// \brief Build an empty MS-style inline-assembly statement.
explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty),
NumAsmToks(0), AsmToks(0), Clobbers(0) { }
NumAsmToks(0), AsmToks(0), Constraints(0), Clobbers(0) { }
SourceLocation getLBraceLoc() const { return LBraceLoc; }
void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
@ -1712,7 +1713,9 @@ public:
//===--- Output operands ---===//
StringRef getOutputConstraint(unsigned i) const;
StringRef getOutputConstraint(unsigned i) const {
return Constraints[i];
}
Expr *getOutputExpr(unsigned i);
@ -1722,7 +1725,9 @@ public:
//===--- Input operands ---===//
StringRef getInputConstraint(unsigned i) const;
StringRef getInputConstraint(unsigned i) const {
return Constraints[i + NumOutputs];
}
Expr *getInputExpr(unsigned i);
void setInputExpr(unsigned i, Expr *E);

View File

@ -630,14 +630,6 @@ Expr *MSAsmStmt::getOutputExpr(unsigned i) {
return cast<Expr>(Exprs[i]);
}
/// getOutputConstraint - Return the constraint string for the specified
/// output operand. All output constraints are known to be non-empty (either
/// '=' or '+').
StringRef MSAsmStmt::getOutputConstraint(unsigned i) const {
// FIXME: Compute constraints.
return StringRef();
}
Expr *MSAsmStmt::getInputExpr(unsigned i) {
return cast<Expr>(Exprs[i + NumOutputs]);
}
@ -645,13 +637,6 @@ void MSAsmStmt::setInputExpr(unsigned i, Expr *E) {
Exprs[i + NumOutputs] = E;
}
/// getInputConstraint - Return the specified input constraint. Unlike output
/// constraints, these can be empty.
StringRef MSAsmStmt::getInputConstraint(unsigned i) const {
// FIXME: Compute constraints.
return StringRef();
}
QualType CXXCatchStmt::getCaughtType() const {
if (ExceptionDecl)
return ExceptionDecl->getType();
@ -691,8 +676,8 @@ MSAsmStmt::MSAsmStmt(ASTContext &C, SourceLocation asmloc,
ArrayRef<Token> asmtoks, ArrayRef<IdentifierInfo*> inputs,
ArrayRef<IdentifierInfo*> outputs,
ArrayRef<Expr*> inputexprs, ArrayRef<Expr*> outputexprs,
StringRef asmstr, ArrayRef<StringRef> clobbers,
SourceLocation endloc)
StringRef asmstr, ArrayRef<StringRef> constraints,
ArrayRef<StringRef> clobbers, SourceLocation endloc)
: AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, outputs.size(), inputs.size(),
clobbers.size()), LBraceLoc(lbraceloc), EndLoc(endloc),
AsmStr(asmstr.str()), NumAsmToks(asmtoks.size()) {
@ -717,6 +702,14 @@ MSAsmStmt::MSAsmStmt(ASTContext &C, SourceLocation asmloc,
for (unsigned i = 0, e = NumAsmToks; i != e; ++i)
AsmToks[i] = asmtoks[i];
Constraints = new (C) StringRef[NumExprs];
for (unsigned i = 0, e = NumExprs; i != e; ++i) {
size_t size = constraints[i].size();
char *dest = new (C) char[size];
std::strncpy(dest, constraints[i].data(), size);
Constraints[i] = StringRef(dest, size);
}
Clobbers = new (C) StringRef[NumClobbers];
for (unsigned i = 0, e = NumClobbers; i != e; ++i) {
// FIXME: Avoid the allocation/copy if at all possible.

View File

@ -454,17 +454,20 @@ static std::string buildMSAsmString(Sema &SemaRef, ArrayRef<Token> AsmToks,
return Res.str();
}
#define DEF_SIMPLE_MSASM \
MSAsmStmt *NS = \
new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true, \
/*IsVolatile*/ true, AsmToks, Inputs, Outputs, \
InputExprs, OutputExprs, AsmString, Clobbers, \
EndLoc);
#define DEF_SIMPLE_MSASM \
MSAsmStmt *NS = \
new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true, \
/*IsVolatile*/ true, AsmToks, Inputs, Outputs, \
InputExprs, OutputExprs, AsmString, Constraints, \
Clobbers, EndLoc);
StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc,
SourceLocation LBraceLoc,
ArrayRef<Token> AsmToks,
SourceLocation EndLoc) {
SmallVector<StringRef, 4> Constraints;
std::vector<std::string> InputConstraints;
std::vector<std::string> OutputConstraints;
SmallVector<StringRef,4> Clobbers;
std::set<std::string> ClobberRegs;
SmallVector<IdentifierInfo*, 4> Inputs;
@ -606,9 +609,11 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc,
if (isDef) {
Outputs.push_back(II);
OutputExprs.push_back(Result.take());
OutputConstraints.push_back("=r");
} else {
Inputs.push_back(II);
InputExprs.push_back(Result.take());
InputConstraints.push_back("r");
}
}
}
@ -620,10 +625,20 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc,
E = ClobberRegs.end(); I != E; ++I)
Clobbers.push_back(*I);
// Merge the output and input constraints. Output constraints are expected
// first.
for (std::vector<std::string>::iterator I = OutputConstraints.begin(),
E = OutputConstraints.end(); I != E; ++I)
Constraints.push_back(*I);
for (std::vector<std::string>::iterator I = InputConstraints.begin(),
E = InputConstraints.end(); I != E; ++I)
Constraints.push_back(*I);
MSAsmStmt *NS =
new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple,
/*IsVolatile*/ true, AsmToks, Inputs, Outputs,
InputExprs, OutputExprs, AsmString, Clobbers,
EndLoc);
InputExprs, OutputExprs, AsmString, Constraints,
Clobbers, EndLoc);
return Owned(NS);
}