diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-05-18 20:51:54 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-05-18 20:51:54 +0000 |
commit | d308e6201afd3a8a198c52ba034d35ed19d4bafe (patch) | |
tree | 59e3a7c999c53d076923cfe50fcbcf4b3744cf51 /lib/Sema/SemaTemplateInstantiateStmt.cpp | |
parent | cc0e354c92dd1713d7d8f041a8c4e0ca77c1c31b (diff) |
Template instantiation for C++ try/catch statements.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72035 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateStmt.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateStmt.cpp | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateStmt.cpp b/lib/Sema/SemaTemplateInstantiateStmt.cpp index a8dd6c194c..c136d25447 100644 --- a/lib/Sema/SemaTemplateInstantiateStmt.cpp +++ b/lib/Sema/SemaTemplateInstantiateStmt.cpp @@ -320,16 +320,69 @@ TemplateStmtInstantiator::VisitAsmStmt(AsmStmt *S) { //===----------------------------------------------------------------------===/ Sema::OwningStmtResult TemplateStmtInstantiator::VisitCXXTryStmt(CXXTryStmt *S) { - // FIXME: Implement this - assert(false && "Cannot instantiate a C++ try statement"); - return SemaRef.StmtError(); + // Instantiate the try block itself. + OwningStmtResult TryBlock = VisitCompoundStmt(S->getTryBlock()); + if (TryBlock.isInvalid()) + return SemaRef.StmtError(); + + // Instantiate the handlers. + llvm::SmallVector<Stmt *, 4> Handlers; + for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) { + OwningStmtResult Handler = VisitCXXCatchStmt(S->getHandler(I)); + if (Handler.isInvalid()) { + // Destroy all of the previous handlers. + for (unsigned Victim = 0; Victim != I; ++Victim) + Handlers[Victim]->Destroy(SemaRef.Context); + return SemaRef.StmtError(); + } + + Handlers.push_back(Handler.takeAs<Stmt>()); + } + + return SemaRef.ActOnCXXTryBlock(S->getTryLoc(), move(TryBlock), + Sema::MultiStmtArg(SemaRef, + (void**)&Handlers.front(), + Handlers.size())); } Sema::OwningStmtResult TemplateStmtInstantiator::VisitCXXCatchStmt(CXXCatchStmt *S) { - // FIXME: Implement this - assert(false && "Cannot instantiate a C++ catch statement"); - return SemaRef.StmtError(); + // Instantiate the exception declaration, if any. + VarDecl *Var = 0; + if (S->getExceptionDecl()) { + VarDecl *ExceptionDecl = S->getExceptionDecl(); + QualType T = SemaRef.InstantiateType(ExceptionDecl->getType(), + TemplateArgs, + ExceptionDecl->getLocation(), + ExceptionDecl->getDeclName()); + if (T.isNull()) + return SemaRef.StmtError(); + + Var = SemaRef.BuildExceptionDeclaration(0, T, + ExceptionDecl->getIdentifier(), + ExceptionDecl->getLocation(), + /*FIXME: Inaccurate*/ + SourceRange(ExceptionDecl->getLocation())); + if (Var->isInvalidDecl()) { + Var->Destroy(SemaRef.Context); + return SemaRef.StmtError(); + } + + // Introduce the exception declaration into scope. + SemaRef.CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var); + } + + // Instantiate the actual exception handler. + OwningStmtResult Handler = Visit(S->getHandlerBlock()); + if (Handler.isInvalid()) { + if (Var) + Var->Destroy(SemaRef.Context); + return SemaRef.StmtError(); + } + + return SemaRef.Owned(new (SemaRef.Context) CXXCatchStmt(S->getCatchLoc(), + Var, + Handler.takeAs<Stmt>())); } //===----------------------------------------------------------------------===/ |