aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/Sema.h6
-rw-r--r--lib/Sema/SemaDeclCXX.cpp4
-rw-r--r--lib/Sema/SemaStmt.cpp28
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));
+}