diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHReaderStmt.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHWriterStmt.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 13 |
5 files changed, 30 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 51b7cf8a112..34e364967d6 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -692,6 +692,11 @@ void CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) { } void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { + CleanupScope ConditionScope(*this); + + if (S.getConditionVariable()) + EmitLocalBlockVarDecl(*S.getConditionVariable()); + llvm::Value *CondV = EmitScalarExpr(S.getCond()); // Handle nested switch statements. diff --git a/clang/lib/Frontend/PCHReaderStmt.cpp b/clang/lib/Frontend/PCHReaderStmt.cpp index fb95584b2a8..1e9f72bd6ed 100644 --- a/clang/lib/Frontend/PCHReaderStmt.cpp +++ b/clang/lib/Frontend/PCHReaderStmt.cpp @@ -188,6 +188,7 @@ unsigned PCHStmtReader::VisitIfStmt(IfStmt *S) { unsigned PCHStmtReader::VisitSwitchStmt(SwitchStmt *S) { VisitStmt(S); + S->setConditionVariable(cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++]))); S->setCond(cast<Expr>(StmtStack[StmtStack.size() - 2])); S->setBody(StmtStack.back()); S->setSwitchLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); diff --git a/clang/lib/Frontend/PCHWriterStmt.cpp b/clang/lib/Frontend/PCHWriterStmt.cpp index 8de094a2967..064c258edc8 100644 --- a/clang/lib/Frontend/PCHWriterStmt.cpp +++ b/clang/lib/Frontend/PCHWriterStmt.cpp @@ -181,6 +181,7 @@ void PCHStmtWriter::VisitIfStmt(IfStmt *S) { void PCHStmtWriter::VisitSwitchStmt(SwitchStmt *S) { VisitStmt(S); + Writer.AddDeclRef(S->getConditionVariable(), Record); Writer.WriteSubStmt(S->getCond()); Writer.WriteSubStmt(S->getBody()); Writer.AddSourceLocation(S->getSwitchLoc(), Record); diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index cecc9b32c10..6ff3d638fe9 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -280,7 +280,17 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Action::OwningStmtResult Sema::ActOnStartOfSwitchStmt(ExprArg cond) { - SwitchStmt *SS = new (Context) SwitchStmt(cond.takeAs<Expr>()); + Expr *condExpr = cond.takeAs<Expr>(); + VarDecl *ConditionVar = 0; + if (CXXConditionDeclExpr *Cond = dyn_cast<CXXConditionDeclExpr>(condExpr)) { + ConditionVar = Cond->getVarDecl(); + condExpr = DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar, + ConditionVar->getLocation(), + ConditionVar->getType().getNonReferenceType()); + // FIXME: Leaks the old condExpr + } + + SwitchStmt *SS = new (Context) SwitchStmt(ConditionVar, condExpr); getSwitchStack().push_back(SS); return Owned(SS); } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index d226c1eb5c2..a7a9cfaca84 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -3126,7 +3126,18 @@ template<typename Derived> Sema::OwningStmtResult TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) { // Transform the condition. - OwningExprResult Cond = getDerived().TransformExpr(S->getCond()); + OwningExprResult Cond(SemaRef); + VarDecl *ConditionVar = 0; + if (S->getConditionVariable()) { + ConditionVar + = cast_or_null<VarDecl>( + getDerived().TransformDefinition(S->getConditionVariable())); + if (!ConditionVar) + return SemaRef.StmtError(); + + Cond = getSema().CheckConditionVariable(ConditionVar); + } else + Cond = getDerived().TransformExpr(S->getCond()); if (Cond.isInvalid()) return SemaRef.StmtError(); |