forked from OSchip/llvm-project
[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:
parent
6cb2080e5e
commit
3dd7bf2c86
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue