summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp5
-rw-r--r--clang/lib/Frontend/PCHReaderStmt.cpp1
-rw-r--r--clang/lib/Frontend/PCHWriterStmt.cpp1
-rw-r--r--clang/lib/Sema/SemaStmt.cpp12
-rw-r--r--clang/lib/Sema/TreeTransform.h13
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();
OpenPOWER on IntegriCloud