From: Douglas Gregor Date: Fri, 15 May 2009 18:22:25 +0000 (+0000) Subject: Move statement instantiation into its own file. No functionality change X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b70ccad30c7854f29c44d9bdd26c70754d28d3fe;p=clang Move statement instantiation into its own file. No functionality change git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71872 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt index 20ccd57f9c..321dac18b6 100644 --- a/lib/Sema/CMakeLists.txt +++ b/lib/Sema/CMakeLists.txt @@ -26,6 +26,7 @@ add_clang_library(clangSema SemaTemplateInstantiate.cpp SemaTemplateInstantiateDecl.cpp SemaTemplateInstantiateExpr.cpp + SemaTemplateInstantiateStmt.cpp SemaType.cpp ) diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp index 401075da3f..3926397dc2 100644 --- a/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp @@ -1,4 +1,4 @@ -//===--- SemaTemplateInstantiateDecl.cpp - C++ Template Decl Instantiation ===/ +//===--- SemaTemplateInstantiateExpr.cpp - C++ Template Expr Instantiation ===/ // // The LLVM Compiler Infrastructure // @@ -6,7 +6,7 @@ // License. See LICENSE.TXT for details. //===----------------------------------------------------------------------===/ // -// This file implements C++ template instantiation for declarations. +// This file implements C++ template instantiation for expressions. // //===----------------------------------------------------------------------===/ #include "Sema.h" @@ -423,133 +423,3 @@ Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) { TemplateExprInstantiator Instantiator(*this, TemplateArgs); return Instantiator.Visit(E); } - -namespace { - class VISIBILITY_HIDDEN TemplateStmtInstantiator - : public StmtVisitor { - Sema &SemaRef; - const TemplateArgumentList &TemplateArgs; - - public: - typedef Sema::OwningExprResult OwningExprResult; - typedef Sema::OwningStmtResult OwningStmtResult; - - TemplateStmtInstantiator(Sema &SemaRef, - const TemplateArgumentList &TemplateArgs) - : SemaRef(SemaRef), TemplateArgs(TemplateArgs) { } - - // FIXME: Once we get closer to completion, replace these - // manually-written declarations with automatically-generated ones - // from clang/AST/StmtNodes.def. - OwningStmtResult VisitDeclStmt(DeclStmt *S); - OwningStmtResult VisitNullStmt(NullStmt *S); - OwningStmtResult VisitCompoundStmt(CompoundStmt *S); - OwningStmtResult VisitExpr(Expr *E); - OwningStmtResult VisitLabelStmt(LabelStmt *S); - OwningStmtResult VisitGotoStmt(GotoStmt *S); - OwningStmtResult VisitReturnStmt(ReturnStmt *S); - - // Base case. I'm supposed to ignore this. - OwningStmtResult VisitStmt(Stmt *S) { - S->dump(); - assert(false && "Cannot instantiate this kind of statement"); - return SemaRef.StmtError(); - } - }; -} - -Sema::OwningStmtResult TemplateStmtInstantiator::VisitDeclStmt(DeclStmt *S) { - llvm::SmallVector Decls; - for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end(); - D != DEnd; ++D) { - Decl *Instantiated = SemaRef.InstantiateDecl(*D, SemaRef.CurContext, - TemplateArgs); - if (!Instantiated) - return SemaRef.StmtError(); - - Decls.push_back(Instantiated); - SemaRef.CurrentInstantiationScope->InstantiatedLocal(cast(*D), - cast(Instantiated)); - } - - return SemaRef.Owned(new (SemaRef.Context) DeclStmt( - DeclGroupRef::Create(SemaRef.Context, - &Decls[0], - Decls.size()), - S->getStartLoc(), - S->getEndLoc())); -} - -Sema::OwningStmtResult TemplateStmtInstantiator::VisitNullStmt(NullStmt *S) { - return SemaRef.Owned(S->Clone(SemaRef.Context)); -} - -Sema::OwningStmtResult TemplateStmtInstantiator::VisitLabelStmt(LabelStmt *S) { - OwningStmtResult SubStmt = Visit(S->getSubStmt()); - - if (SubStmt.isInvalid()) - return SemaRef.StmtError(); - - // FIXME: Pass the real colon loc in. - return SemaRef.ActOnLabelStmt(S->getIdentLoc(), S->getID(), SourceLocation(), - move(SubStmt)); -} - -Sema::OwningStmtResult TemplateStmtInstantiator::VisitGotoStmt(GotoStmt *S) { - return SemaRef.ActOnGotoStmt(S->getGotoLoc(), S->getLabelLoc(), - S->getLabel()->getID()); -} - -Sema::OwningStmtResult -TemplateStmtInstantiator::VisitReturnStmt(ReturnStmt *S) { - Sema::OwningExprResult Result = SemaRef.ExprEmpty(); - if (Expr *E = S->getRetValue()) { - Result = SemaRef.InstantiateExpr(E, TemplateArgs); - - if (Result.isInvalid()) - return SemaRef.StmtError(); - } - - return SemaRef.ActOnReturnStmt(S->getReturnLoc(), move(Result)); -} - -Sema::OwningStmtResult -TemplateStmtInstantiator::VisitCompoundStmt(CompoundStmt *S) { - // FIXME: We need an *easy* RAII way to delete these statements if - // something goes wrong. - llvm::SmallVector Statements; - - for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end(); - B != BEnd; ++B) { - OwningStmtResult Result = Visit(*B); - if (Result.isInvalid()) { - // FIXME: This should be handled by an RAII destructor. - for (unsigned I = 0, N = Statements.size(); I != N; ++I) - Statements[I]->Destroy(SemaRef.Context); - return SemaRef.StmtError(); - } - - Statements.push_back(Result.takeAs()); - } - - return SemaRef.Owned( - new (SemaRef.Context) CompoundStmt(SemaRef.Context, - &Statements[0], - Statements.size(), - S->getLBracLoc(), - S->getRBracLoc())); -} - -Sema::OwningStmtResult TemplateStmtInstantiator::VisitExpr(Expr *E) { - Sema::OwningExprResult Result = SemaRef.InstantiateExpr(E, TemplateArgs); - if (Result.isInvalid()) - return SemaRef.StmtError(); - - return SemaRef.Owned(Result.takeAs()); -} - -Sema::OwningStmtResult -Sema::InstantiateStmt(Stmt *S, const TemplateArgumentList &TemplateArgs) { - TemplateStmtInstantiator Instantiator(*this, TemplateArgs); - return Instantiator.Visit(S); -} diff --git a/lib/Sema/SemaTemplateInstantiateStmt.cpp b/lib/Sema/SemaTemplateInstantiateStmt.cpp new file mode 100644 index 0000000000..cbe4449efc --- /dev/null +++ b/lib/Sema/SemaTemplateInstantiateStmt.cpp @@ -0,0 +1,150 @@ +//===--- SemaTemplateInstantiateStmt.cpp - C++ Template Stmt Instantiation ===/ +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +//===----------------------------------------------------------------------===/ +// +// This file implements C++ template instantiation for statements. +// +//===----------------------------------------------------------------------===/ +#include "Sema.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/AST/StmtVisitor.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" +#include "clang/Parse/DeclSpec.h" +#include "llvm/Support/Compiler.h" +using namespace clang; + +namespace { + class VISIBILITY_HIDDEN TemplateStmtInstantiator + : public StmtVisitor { + Sema &SemaRef; + const TemplateArgumentList &TemplateArgs; + + public: + typedef Sema::OwningExprResult OwningExprResult; + typedef Sema::OwningStmtResult OwningStmtResult; + + TemplateStmtInstantiator(Sema &SemaRef, + const TemplateArgumentList &TemplateArgs) + : SemaRef(SemaRef), TemplateArgs(TemplateArgs) { } + + // FIXME: Once we get closer to completion, replace these + // manually-written declarations with automatically-generated ones + // from clang/AST/StmtNodes.def. + OwningStmtResult VisitDeclStmt(DeclStmt *S); + OwningStmtResult VisitNullStmt(NullStmt *S); + OwningStmtResult VisitCompoundStmt(CompoundStmt *S); + OwningStmtResult VisitExpr(Expr *E); + OwningStmtResult VisitLabelStmt(LabelStmt *S); + OwningStmtResult VisitGotoStmt(GotoStmt *S); + OwningStmtResult VisitReturnStmt(ReturnStmt *S); + + // Base case. I'm supposed to ignore this. + OwningStmtResult VisitStmt(Stmt *S) { + S->dump(); + assert(false && "Cannot instantiate this kind of statement"); + return SemaRef.StmtError(); + } + }; +} + +Sema::OwningStmtResult TemplateStmtInstantiator::VisitDeclStmt(DeclStmt *S) { + llvm::SmallVector Decls; + for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end(); + D != DEnd; ++D) { + Decl *Instantiated = SemaRef.InstantiateDecl(*D, SemaRef.CurContext, + TemplateArgs); + if (!Instantiated) + return SemaRef.StmtError(); + + Decls.push_back(Instantiated); + SemaRef.CurrentInstantiationScope->InstantiatedLocal(cast(*D), + cast(Instantiated)); + } + + return SemaRef.Owned(new (SemaRef.Context) DeclStmt( + DeclGroupRef::Create(SemaRef.Context, + &Decls[0], + Decls.size()), + S->getStartLoc(), + S->getEndLoc())); +} + +Sema::OwningStmtResult TemplateStmtInstantiator::VisitNullStmt(NullStmt *S) { + return SemaRef.Owned(S->Clone(SemaRef.Context)); +} + +Sema::OwningStmtResult TemplateStmtInstantiator::VisitLabelStmt(LabelStmt *S) { + OwningStmtResult SubStmt = Visit(S->getSubStmt()); + + if (SubStmt.isInvalid()) + return SemaRef.StmtError(); + + // FIXME: Pass the real colon loc in. + return SemaRef.ActOnLabelStmt(S->getIdentLoc(), S->getID(), SourceLocation(), + move(SubStmt)); +} + +Sema::OwningStmtResult TemplateStmtInstantiator::VisitGotoStmt(GotoStmt *S) { + return SemaRef.ActOnGotoStmt(S->getGotoLoc(), S->getLabelLoc(), + S->getLabel()->getID()); +} + +Sema::OwningStmtResult +TemplateStmtInstantiator::VisitReturnStmt(ReturnStmt *S) { + Sema::OwningExprResult Result = SemaRef.ExprEmpty(); + if (Expr *E = S->getRetValue()) { + Result = SemaRef.InstantiateExpr(E, TemplateArgs); + + if (Result.isInvalid()) + return SemaRef.StmtError(); + } + + return SemaRef.ActOnReturnStmt(S->getReturnLoc(), move(Result)); +} + +Sema::OwningStmtResult +TemplateStmtInstantiator::VisitCompoundStmt(CompoundStmt *S) { + // FIXME: We need an *easy* RAII way to delete these statements if + // something goes wrong. + llvm::SmallVector Statements; + + for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end(); + B != BEnd; ++B) { + OwningStmtResult Result = Visit(*B); + if (Result.isInvalid()) { + // FIXME: This should be handled by an RAII destructor. + for (unsigned I = 0, N = Statements.size(); I != N; ++I) + Statements[I]->Destroy(SemaRef.Context); + return SemaRef.StmtError(); + } + + Statements.push_back(Result.takeAs()); + } + + return SemaRef.Owned( + new (SemaRef.Context) CompoundStmt(SemaRef.Context, + &Statements[0], + Statements.size(), + S->getLBracLoc(), + S->getRBracLoc())); +} + +Sema::OwningStmtResult TemplateStmtInstantiator::VisitExpr(Expr *E) { + Sema::OwningExprResult Result = SemaRef.InstantiateExpr(E, TemplateArgs); + if (Result.isInvalid()) + return SemaRef.StmtError(); + + return SemaRef.Owned(Result.takeAs()); +} + +Sema::OwningStmtResult +Sema::InstantiateStmt(Stmt *S, const TemplateArgumentList &TemplateArgs) { + TemplateStmtInstantiator Instantiator(*this, TemplateArgs); + return Instantiator.Visit(S); +}