diff options
author | Anders Carlsson <andersca@mac.com> | 2010-01-24 05:50:09 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-01-24 05:50:09 +0000 |
commit | 703e39486689d6660e75f6b6de0068db031a51c7 (patch) | |
tree | b94e80b292abcab3b15e1de84b0bd66c3e836f2d | |
parent | a57259e9d7b30bcce93f0a62eee0488738026172 (diff) |
Implement instantiation of AsmStmts (Crazy, I know)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94361 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Stmt.h | 2 | ||||
-rw-r--r-- | include/clang/Parse/Action.h | 2 | ||||
-rw-r--r-- | lib/AST/Stmt.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/PrintParserCallbacks.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 87 |
7 files changed, 94 insertions, 9 deletions
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index d058f838a0..7abd55787a 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -1129,7 +1129,7 @@ class AsmStmt : public Stmt { public: AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, bool msasm, unsigned numoutputs, unsigned numinputs, - std::string *names, StringLiteral **constraints, + const std::string *names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, StringLiteral **clobbers, SourceLocation rparenloc); diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 74076c8aef..4854fe66d4 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -902,7 +902,7 @@ public: bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, - std::string *Names, + const std::string *Names, MultiExprArg Constraints, MultiExprArg Exprs, ExprArg AsmString, diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 104e336189..821bcb5106 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -338,7 +338,7 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces, AsmStmt::AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, bool msasm, unsigned numoutputs, unsigned numinputs, - std::string *names, StringLiteral **constraints, + const std::string *names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, StringLiteral **clobbers, SourceLocation rparenloc) : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr) diff --git a/lib/Frontend/PrintParserCallbacks.cpp b/lib/Frontend/PrintParserCallbacks.cpp index a91dd8d55e..8f706e0371 100644 --- a/lib/Frontend/PrintParserCallbacks.cpp +++ b/lib/Frontend/PrintParserCallbacks.cpp @@ -391,7 +391,7 @@ namespace { bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, - std::string *Names, + const std::string *Names, MultiExprArg Constraints, MultiExprArg Exprs, ExprArg AsmString, diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index ead9feb48e..874eabf9b7 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1418,7 +1418,7 @@ public: bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, - std::string *Names, + const std::string *Names, MultiExprArg Constraints, MultiExprArg Exprs, ExprArg AsmString, diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 4653c77c86..ca15de2cf2 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1131,6 +1131,10 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprArg rex) { /// This method checks to see if the argument is an acceptable l-value and /// returns false if it is a case we can handle. static bool CheckAsmLValue(const Expr *E, Sema &S) { + // Type dependent expressions will be checked during instantiation. + if (E->isTypeDependent()) + return false; + if (E->isLvalue(S.Context) == Expr::LV_Valid) return false; // Cool, this is an lvalue. @@ -1158,7 +1162,7 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, - std::string *Names, + const std::string *Names, MultiExprArg constraints, MultiExprArg exprs, ExprArg asmString, diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index b2102afdfc..0158a08eb7 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -776,6 +776,28 @@ public: StartLoc, EndLoc)); } + /// \brief Build a new inline asm statement. + /// + /// By default, performs semantic analysis to build the new statement. + /// Subclasses may override this routine to provide different behavior. + OwningStmtResult RebuildAsmStmt(SourceLocation AsmLoc, + bool IsSimple, + bool IsVolatile, + unsigned NumOutputs, + unsigned NumInputs, + const std::string *Names, + MultiExprArg Constraints, + MultiExprArg Exprs, + ExprArg AsmString, + MultiExprArg Clobbers, + SourceLocation RParenLoc, + bool MSAsm) { + return getSema().ActOnAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs, + NumInputs, Names, move(Constraints), + move(Exprs), move(AsmString), move(Clobbers), + RParenLoc, MSAsm); + } + /// \brief Build a new C++ exception declaration. /// /// By default, performs semantic analysis to build the new decaration. @@ -3327,9 +3349,68 @@ TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) { template<typename Derived> Sema::OwningStmtResult TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) { - // FIXME: Implement! - assert(false && "Inline assembly cannot be transformed"); - return SemaRef.Owned(S->Retain()); + + ASTOwningVector<&ActionBase::DeleteExpr> Constraints(getSema()); + ASTOwningVector<&ActionBase::DeleteExpr> Exprs(getSema()); + OwningExprResult AsmString(SemaRef); + ASTOwningVector<&ActionBase::DeleteExpr> Clobbers(getSema()); + + bool ExprsChanged = false; + + // Go through the outputs. + for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) { + // No need to transform the constraint literal. + Constraints.push_back(S->getOutputConstraintLiteral(I)->Retain()); + + // Transform the output expr. + Expr *OutputExpr = S->getOutputExpr(I); + OwningExprResult Result = getDerived().TransformExpr(OutputExpr); + if (Result.isInvalid()) + return SemaRef.StmtError(); + + ExprsChanged |= Result.get() != OutputExpr; + + Exprs.push_back(Result.takeAs<Expr>()); + } + + // Go through the inputs. + for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) { + // No need to transform the constraint literal. + Constraints.push_back(S->getInputConstraintLiteral(I)->Retain()); + + // Transform the input expr. + Expr *InputExpr = S->getInputExpr(I); + OwningExprResult Result = getDerived().TransformExpr(InputExpr); + if (Result.isInvalid()) + return SemaRef.StmtError(); + + ExprsChanged |= Result.get() != InputExpr; + + Exprs.push_back(Result.takeAs<Expr>()); + } + + if (!getDerived().AlwaysRebuild() && !ExprsChanged) + return SemaRef.Owned(S->Retain()); + + // Go through the clobbers. + for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) + Clobbers.push_back(S->getClobber(I)->Retain()); + + // No need to transform the asm string literal. + AsmString = SemaRef.Owned(S->getAsmString()); + + return getDerived().RebuildAsmStmt(S->getAsmLoc(), + S->isSimple(), + S->isVolatile(), + S->getNumOutputs(), + S->getNumInputs(), + S->begin_output_names(), + move_arg(Constraints), + move_arg(Exprs), + move(AsmString), + move_arg(Clobbers), + S->getRParenLoc(), + S->isMSAsm()); } |