diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Sema.h | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 28 |
3 files changed, 35 insertions, 3 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index c179fe8729..48af5af0a3 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -640,9 +640,9 @@ public: virtual OwningStmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, DeclTy *ExDecl, StmtArg HandlerBlock); - //virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc, - // StmtArg TryBlock, - // MultiStmtArg Handlers); + virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc, + StmtArg TryBlock, + MultiStmtArg Handlers); //===--------------------------------------------------------------------===// // Expression Parsing Callbacks: SemaExpr.cpp. diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 4ac7ecb8af..8a37bbbe7b 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2058,6 +2058,10 @@ Sema::DeclTy *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) Diag(Begin, diag::err_catch_incomplete) << BaseType << Mode; } + // FIXME: Need to test for ability to copy-construct and destroy the + // exception variable. + // FIXME: Need to check for abstract classes. + IdentifierInfo *II = D.getIdentifier(); if (Decl *PrevDecl = LookupDecl(II, Decl::IDNS_Ordinary, S)) { // The scope should be freshly made just for us. There is just no way diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 6a322ee21c..0c441f7523 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -961,3 +961,31 @@ Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, DeclTy *ExDecl, return Owned(new CXXCatchStmt(CatchLoc, static_cast<VarDecl*>(ExDecl), static_cast<Stmt*>(HandlerBlock.release()))); } + +/// ActOnCXXTryBlock - Takes a try compound-statement and a number of +/// handlers and creates a try statement from them. +Action::OwningStmtResult +Sema::ActOnCXXTryBlock(SourceLocation TryLoc, StmtArg TryBlock, + MultiStmtArg RawHandlers) { + unsigned NumHandlers = RawHandlers.size(); + assert(NumHandlers > 0 && + "The parser shouldn't call this if there are no handlers."); + Stmt **Handlers = reinterpret_cast<Stmt**>(RawHandlers.get()); + + for(unsigned i = 0; i < NumHandlers - 1; ++i) { + CXXCatchStmt *Handler = llvm::cast<CXXCatchStmt>(Handlers[i]); + if (!Handler->getExceptionDecl()) + return StmtError(Diag(Handler->getLocStart(), diag::err_early_catch_all)); + } + // FIXME: We should detect handlers for the same type as an earlier one. + // This one is rather easy. + // FIXME: We should detect handlers that cannot catch anything because an + // earlier handler catches a superclass. Need to find a method that is not + // quadratic for this. + // Neither of these are explicitly forbidden, but every compiler detects them + // and warns. + + RawHandlers.release(); + return Owned(new CXXTryStmt(TryLoc, static_cast<Stmt*>(TryBlock.release()), + Handlers, NumHandlers)); +} |