diff options
| author | Douglas Gregor <dgregor@apple.com> | 2009-05-20 22:33:37 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2009-05-20 22:33:37 +0000 |
| commit | 1301fdd6c4139be806d8aa5d331bca292a04b385 (patch) | |
| tree | 58d8a54ec1af0b6628869551df11268a68ef71ad /clang/lib/Sema | |
| parent | 06555f134a7471c93124c71c8f2cf0892cc942cf (diff) | |
| download | bcm5719-llvm-1301fdd6c4139be806d8aa5d331bca292a04b385.tar.gz bcm5719-llvm-1301fdd6c4139be806d8aa5d331bca292a04b385.zip | |
Introduce a new kind of RAII class, ASTOwningVector, which is an
llvm::SmallVector that owns all of the AST nodes inside of it. This
RAII class is used to ensure proper destruction of AST nodes when
template instantiation fails.
llvm-svn: 72186
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateExpr.cpp | 108 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateStmt.cpp | 31 |
3 files changed, 47 insertions, 94 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index f5c4a7bb63a..e16f544abbb 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -2747,7 +2747,7 @@ public: T& operator*() const { return *get(); } T* operator->() const { return get(); } }; - + } // end namespace clang #endif diff --git a/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp b/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp index 099ce278f1f..a93ad1132a6 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp @@ -266,15 +266,12 @@ Sema::OwningExprResult TemplateExprInstantiator::VisitCallExpr(CallExpr *E) { return SemaRef.ExprError(); // Instantiate arguments - llvm::SmallVector<Expr*, 8> Args; + ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef); llvm::SmallVector<SourceLocation, 4> FakeCommaLocs; for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) { OwningExprResult Arg = Visit(E->getArg(I)); - if (Arg.isInvalid()) { - for (unsigned Victim = 0; Victim != I; ++Victim) - Args[Victim]->Destroy(SemaRef.Context); + if (Arg.isInvalid()) return SemaRef.ExprError(); - } FakeCommaLocs.push_back( SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd())); @@ -286,8 +283,7 @@ Sema::OwningExprResult TemplateExprInstantiator::VisitCallExpr(CallExpr *E) { return SemaRef.ActOnCallExpr(/*Scope=*/0, move(Callee), /*FIXME:*/FakeLParenLoc, Sema::MultiExprArg(SemaRef, - (void **)&Args.front(), - Args.size()), + Args.take(), Args.size()), /*FIXME:*/&FakeCommaLocs.front(), E->getRParenLoc()); } @@ -507,15 +503,11 @@ TemplateExprInstantiator::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) { Sema::OwningExprResult TemplateExprInstantiator::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { - // FIXME: Better solution for this! - llvm::SmallVector<Expr *, 8> SubExprs; + ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef); for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) { OwningExprResult SubExpr = Visit(E->getExpr(I)); - if (SubExpr.isInvalid()) { - for (unsigned Victim = 0; Victim != I; ++Victim) - SubExprs[I]->Destroy(SemaRef.Context); + if (SubExpr.isInvalid()) return SemaRef.ExprError(); - } SubExprs.push_back(SubExpr.takeAs<Expr>()); } @@ -537,7 +529,7 @@ TemplateExprInstantiator::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { // Build the CallExpr CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee, - &SubExprs[0], + SubExprs.takeAs<Expr>(), SubExprs.size(), Builtin->getResultType(), E->getRParenLoc()); @@ -656,47 +648,34 @@ TemplateExprInstantiator::VisitCXXTemporaryObjectExpr( return SemaRef.ExprError(); } - llvm::SmallVector<Expr *, 16> Args; + ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef); Args.reserve(E->getNumArgs()); - bool Invalid = false; for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end(); Arg != ArgEnd; ++Arg) { OwningExprResult InstantiatedArg = Visit(*Arg); - if (InstantiatedArg.isInvalid()) { - Invalid = true; - break; - } + if (InstantiatedArg.isInvalid()) + return SemaRef.ExprError(); Args.push_back((Expr *)InstantiatedArg.release()); } - if (!Invalid) { - SourceLocation CommaLoc; - // FIXME: HACK! - if (Args.size() > 1) - CommaLoc - = SemaRef.PP.getLocForEndOfToken(Args[0]->getSourceRange().getEnd()); - Sema::OwningExprResult Result( - SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc() - /*, FIXME*/), - T.getAsOpaquePtr(), - /*FIXME*/E->getTypeBeginLoc(), - Sema::MultiExprArg(SemaRef, - (void**)&Args[0], - Args.size()), - /*HACK*/&CommaLoc, - E->getSourceRange().getEnd())); - // At this point, Args no longer owns the arguments, no matter what. - return move(Result); + SourceLocation CommaLoc; + // FIXME: HACK! + if (Args.size() > 1) { + Expr *First = (Expr *)Args[0]; + CommaLoc + = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd()); } - - // Clean up the instantiated arguments. - // FIXME: Would rather do this with RAII. - for (unsigned Idx = 0; Idx < Args.size(); ++Idx) - SemaRef.DeleteExpr(Args[Idx]); - - return SemaRef.ExprError(); + return SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc() + /*, FIXME*/), + T.getAsOpaquePtr(), + /*FIXME*/E->getTypeBeginLoc(), + Sema::MultiExprArg(SemaRef, + Args.take(), + Args.size()), + /*HACK*/&CommaLoc, + E->getSourceRange().getEnd()); } Sema::OwningExprResult TemplateExprInstantiator::VisitCastExpr(CastExpr *E) { @@ -847,42 +826,30 @@ TemplateExprInstantiator::VisitCXXConstructExpr(CXXConstructExpr *E) { if (T.isNull()) return SemaRef.ExprError(); - bool Invalid = false; - llvm::SmallVector<Expr *, 8> Args; + ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef); for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end(); Arg != ArgEnd; ++Arg) { OwningExprResult ArgInst = Visit(*Arg); - if (ArgInst.isInvalid()) { - Invalid = true; - break; - } + if (ArgInst.isInvalid()) + return SemaRef.ExprError(); Args.push_back(ArgInst.takeAs<Expr>()); } - VarDecl *Var = 0; - if (!Invalid) { - Var = cast_or_null<VarDecl>(SemaRef.InstantiateDecl(E->getVarDecl(), - SemaRef.CurContext, - TemplateArgs)); - if (!Var) - Invalid = true; - } - - if (Invalid) { - for (unsigned I = 0, N = Args.size(); I != N; ++I) - Args[I]->Destroy(SemaRef.Context); - + VarDecl *Var = cast_or_null<VarDecl>(SemaRef.InstantiateDecl(E->getVarDecl(), + SemaRef.CurContext, + TemplateArgs)); + if (!Var) return SemaRef.ExprError(); - } SemaRef.CurrentInstantiationScope->InstantiatedLocal(E->getVarDecl(), Var); return SemaRef.Owned(CXXConstructExpr::Create(SemaRef.Context, Var, T, E->getConstructor(), E->isElidable(), - &Args.front(), Args.size())); + Args.takeAs<Expr>(), + Args.size())); } Sema::OwningExprResult @@ -937,17 +904,14 @@ TemplateExprInstantiator::VisitCXXUnresolvedConstructExpr( if (T.isNull()) return SemaRef.ExprError(); - llvm::SmallVector<Expr *, 8> Args; + ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef); llvm::SmallVector<SourceLocation, 8> FakeCommaLocs; for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end(); Arg != ArgEnd; ++Arg) { OwningExprResult InstArg = Visit(*Arg); - if (InstArg.isInvalid()) { - for (unsigned I = 0; I != Args.size(); ++I) - Args[I]->Destroy(SemaRef.Context); + if (InstArg.isInvalid()) return SemaRef.ExprError(); - } FakeCommaLocs.push_back( SemaRef.PP.getLocForEndOfToken((*Arg)->getSourceRange().getEnd())); @@ -961,7 +925,7 @@ TemplateExprInstantiator::VisitCXXUnresolvedConstructExpr( T.getAsOpaquePtr(), E->getLParenLoc(), Sema::MultiExprArg(SemaRef, - (void **)&Args.front(), + Args.take(), Args.size()), &FakeCommaLocs.front(), E->getRParenLoc()); diff --git a/clang/lib/Sema/SemaTemplateInstantiateStmt.cpp b/clang/lib/Sema/SemaTemplateInstantiateStmt.cpp index c136d254478..e83718e33de 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateStmt.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateStmt.cpp @@ -136,29 +136,22 @@ TemplateStmtInstantiator::VisitReturnStmt(ReturnStmt *S) { Sema::OwningStmtResult TemplateStmtInstantiator::VisitCompoundStmt(CompoundStmt *S) { - // FIXME: We need an *easy* RAII way to delete these statements if something - // goes wrong. - llvm::SmallVector<Stmt *, 16> Statements; + ASTOwningVector<&ActionBase::DeleteStmt> Statements(SemaRef); 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); + if (Result.isInvalid()) return SemaRef.StmtError(); - } Statements.push_back(Result.takeAs<Stmt>()); } - return SemaRef.Owned( - new (SemaRef.Context) CompoundStmt(SemaRef.Context, - &Statements[0], - Statements.size(), - S->getLBracLoc(), - S->getRBracLoc())); + return SemaRef.ActOnCompoundStmt(S->getLBracLoc(), S->getRBracLoc(), + Sema::MultiStmtArg(SemaRef, + Statements.take(), + Statements.size()), + /*isStmtExpr=*/false); } Sema::OwningStmtResult @@ -326,22 +319,18 @@ TemplateStmtInstantiator::VisitCXXTryStmt(CXXTryStmt *S) { return SemaRef.StmtError(); // Instantiate the handlers. - llvm::SmallVector<Stmt *, 4> Handlers; + ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef); 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); + if (Handler.isInvalid()) return SemaRef.StmtError(); - } Handlers.push_back(Handler.takeAs<Stmt>()); } return SemaRef.ActOnCXXTryBlock(S->getTryLoc(), move(TryBlock), Sema::MultiStmtArg(SemaRef, - (void**)&Handlers.front(), + Handlers.take(), Handlers.size())); } |

