From 89fb6d7eba51c7864ec544e07accd23b24057122 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Tue, 28 Aug 2012 20:28:20 +0000 Subject: [PATCH] [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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162784 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Stmt.h | 15 ++++++++++----- lib/AST/Stmt.cpp | 27 ++++++++++----------------- lib/Sema/SemaStmtAsm.cpp | 31 +++++++++++++++++++++++-------- 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 2303cb910f..042c513552 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -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 asmtoks, ArrayRef inputs, ArrayRef outputs, ArrayRef inputexprs, ArrayRef outputexprs, - StringRef asmstr, ArrayRef clobbers, - SourceLocation endloc); + StringRef asmstr, ArrayRef constraints, + ArrayRef 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); diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 84622658d5..ac432e85a7 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -630,14 +630,6 @@ Expr *MSAsmStmt::getOutputExpr(unsigned i) { return cast(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(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 asmtoks, ArrayRef inputs, ArrayRef outputs, ArrayRef inputexprs, ArrayRef outputexprs, - StringRef asmstr, ArrayRef clobbers, - SourceLocation endloc) + StringRef asmstr, ArrayRef constraints, + ArrayRef 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. diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index 638c87953c..f51e47656c 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -454,17 +454,20 @@ static std::string buildMSAsmString(Sema &SemaRef, ArrayRef 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 AsmToks, SourceLocation EndLoc) { + SmallVector Constraints; + std::vector InputConstraints; + std::vector OutputConstraints; SmallVector Clobbers; std::set ClobberRegs; SmallVector 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::iterator I = OutputConstraints.begin(), + E = OutputConstraints.end(); I != E; ++I) + Constraints.push_back(*I); + + for (std::vector::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); } -- 2.40.0