From: Douglas Gregor Date: Fri, 15 May 2009 22:32:39 +0000 (+0000) Subject: Template instantiation for break and continue statements. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=861ce3178c70cfb0fa50baf685e1ad363538eaa9;p=clang Template instantiation for break and continue statements. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71903 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index c4af23441b..1159ef3ffa 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -873,6 +873,9 @@ public: virtual SourceRange getSourceRange() const { return SourceRange(ContinueLoc); } + + ContinueStmt* Clone(ASTContext &C) const; + static bool classof(const Stmt *T) { return T->getStmtClass() == ContinueStmtClass; } @@ -898,6 +901,8 @@ public: virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } + BreakStmt* Clone(ASTContext &C) const; + static bool classof(const Stmt *T) { return T->getStmtClass() == BreakStmtClass; } diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index f8f6e067e1..71103b83e3 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -102,6 +102,14 @@ NullStmt* NullStmt::Clone(ASTContext &C) const { return new (C) NullStmt(SemiLoc); } +ContinueStmt* ContinueStmt::Clone(ASTContext &C) const { + return new (C) ContinueStmt(ContinueLoc); +} + +BreakStmt* BreakStmt::Clone(ASTContext &C) const { + return new (C) BreakStmt(BreakLoc); +} + void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) { if (this->Body) C.Deallocate(Body); diff --git a/lib/Sema/SemaTemplateInstantiateStmt.cpp b/lib/Sema/SemaTemplateInstantiateStmt.cpp index c7682342ff..d59f85953f 100644 --- a/lib/Sema/SemaTemplateInstantiateStmt.cpp +++ b/lib/Sema/SemaTemplateInstantiateStmt.cpp @@ -46,6 +46,8 @@ namespace { OwningStmtResult VisitExpr(Expr *E); OwningStmtResult VisitLabelStmt(LabelStmt *S); OwningStmtResult VisitGotoStmt(GotoStmt *S); + OwningStmtResult VisitBreakStmt(BreakStmt *S); + OwningStmtResult VisitContinueStmt(ContinueStmt *S); OwningStmtResult VisitReturnStmt(ReturnStmt *S); // Base case. I'm supposed to ignore this. @@ -99,6 +101,15 @@ Sema::OwningStmtResult TemplateStmtInstantiator::VisitGotoStmt(GotoStmt *S) { S->getLabel()->getID()); } +Sema::OwningStmtResult TemplateStmtInstantiator::VisitBreakStmt(BreakStmt *S) { + return SemaRef.Owned(S->Clone(SemaRef.Context)); +} + +Sema::OwningStmtResult +TemplateStmtInstantiator::VisitContinueStmt(ContinueStmt *S) { + return SemaRef.Owned(S->Clone(SemaRef.Context)); +} + Sema::OwningStmtResult TemplateStmtInstantiator::VisitReturnStmt(ReturnStmt *S) { Sema::OwningExprResult Result = SemaRef.ExprEmpty(); diff --git a/test/SemaTemplate/instantiate-function-1.cpp b/test/SemaTemplate/instantiate-function-1.cpp index 523860239c..dc48598050 100644 --- a/test/SemaTemplate/instantiate-function-1.cpp +++ b/test/SemaTemplate/instantiate-function-1.cpp @@ -116,6 +116,10 @@ template struct Do0; // expected-note{{instantiation}} template struct For0 { void f(T f, T l) { for (; f != l; ++f) { + if (*f) + continue; + else if (*f == 17) + break; } } };