Implement instantiation of AsmStmts (Crazy, I know)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94361 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index d058f83..7abd557 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -1129,7 +1129,7 @@
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 74076c8..4854fe6 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -902,7 +902,7 @@
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 104e336..821bcb5 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -338,7 +338,7 @@
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 a91dd8d..8f706e0 100644
--- a/lib/Frontend/PrintParserCallbacks.cpp
+++ b/lib/Frontend/PrintParserCallbacks.cpp
@@ -391,7 +391,7 @@
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 ead9feb..874eabf 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1418,7 +1418,7 @@
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 4653c77..ca15de2 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -1131,6 +1131,10 @@
/// 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 @@
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 b2102af..0158a08 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -776,6 +776,28 @@
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 @@
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());
}