Index: include/clang/AST/Stmt.h =================================================================== --- include/clang/AST/Stmt.h +++ include/clang/AST/Stmt.h @@ -1892,22 +1892,24 @@ bool IsCXXTry; SourceLocation TryLoc; Stmt *Children[2]; + int HandlerIndex; + int HandlerParentIndex; enum { TRY = 0, HANDLER = 1 }; SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try' - SourceLocation TryLoc, - Stmt *TryBlock, - Stmt *Handler); + SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler, + int HandlerIndex, int HandlerParentIndex); friend class ASTReader; friend class ASTStmtReader; explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { } public: - static SEHTryStmt* Create(const ASTContext &C, bool isCXXTry, + static SEHTryStmt *Create(const ASTContext &C, bool isCXXTry, SourceLocation TryLoc, Stmt *TryBlock, - Stmt *Handler); + Stmt *Handler, int HandlerIndex, + int HandlerParentIndex); SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); } SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } @@ -1934,6 +1936,9 @@ static bool classof(const Stmt *T) { return T->getStmtClass() == SEHTryStmtClass; } + + int getHandlerIndex() const { return HandlerIndex; } + int getHandlerParentIndex() const { return HandlerParentIndex; } }; /// Represents a __leave statement. Index: include/clang/Sema/Scope.h =================================================================== --- include/clang/Sema/Scope.h +++ include/clang/Sema/Scope.h @@ -135,6 +135,14 @@ /// scopes seen as a component. unsigned short MSLocalManglingNumber; + /// \brief SEH __try blocks get uniquely numbered within a function. This + /// variable holds the index for an SEH try block. + short SEHTryIndex; + + /// \brief SEH __try blocks get uniquely numbered within a function. This + /// variable holds the next free index at a function's scope. + short SEHTryIndexPool; + /// PrototypeDepth - This is the number of function prototype scopes /// enclosing this scope, including this scope. unsigned short PrototypeDepth; @@ -147,6 +155,7 @@ /// pointer is non-null and points to it. This is used for label processing. Scope *FnParent; Scope *MSLocalManglingParent; + Scope *SEHTryParent; /// BreakParent/ContinueParent - This is a direct link to the innermost /// BreakScope/ContinueScope which contains the contents of this scope @@ -285,6 +294,14 @@ return 1; } + int getSEHTryIndex() { + return SEHTryIndex; + } + + int getSEHTryParentIndex() const { + return SEHTryParent ? SEHTryParent->SEHTryIndex : -1; + } + /// isDeclScope - Return true if this is the scope that the specified decl is /// declared in. bool isDeclScope(Decl *D) { Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -3165,9 +3165,9 @@ StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ? SourceLocation TryLoc, Stmt *TryBlock, - Stmt *Handler); - StmtResult ActOnSEHExceptBlock(SourceLocation Loc, - Expr *FilterExpr, + Stmt *Handler, int HandlerIndex, + int HandlerParentIndex); + StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr, Stmt *Block); StmtResult ActOnSEHFinallyBlock(SourceLocation Loc, Stmt *Block); StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope); Index: lib/AST/Stmt.cpp =================================================================== --- lib/AST/Stmt.cpp +++ lib/AST/Stmt.cpp @@ -956,22 +956,20 @@ return cast_or_null(RetExpr); } -SEHTryStmt::SEHTryStmt(bool IsCXXTry, - SourceLocation TryLoc, - Stmt *TryBlock, - Stmt *Handler) - : Stmt(SEHTryStmtClass), - IsCXXTry(IsCXXTry), - TryLoc(TryLoc) -{ - Children[TRY] = TryBlock; +SEHTryStmt::SEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, + Stmt *Handler, int HandlerIndex, int HandlerParentIndex) + : Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc), + HandlerIndex(HandlerIndex), HandlerParentIndex(HandlerParentIndex) { + Children[TRY] = TryBlock; Children[HANDLER] = Handler; } -SEHTryStmt* SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry, +SEHTryStmt *SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, - Stmt *Handler) { - return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler); + Stmt *Handler, int HandlerIndex, + int HandlerParentIndex) { + return new (C) SEHTryStmt(IsCXXTry, TryLoc, TryBlock, Handler, HandlerIndex, + HandlerParentIndex); } SEHExceptStmt* SEHTryStmt::getExceptHandler() const { Index: lib/Parse/ParseStmt.cpp =================================================================== --- lib/Parse/ParseStmt.cpp +++ lib/Parse/ParseStmt.cpp @@ -424,11 +424,27 @@ /// seh-finally-block /// StmtResult Parser::ParseSEHTryBlockCommon(SourceLocation TryLoc) { - if(Tok.isNot(tok::l_brace)) + if (Tok.isNot(tok::l_brace)) return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace); - StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false, - Scope::DeclScope | Scope::SEHTryScope)); + int SEHTryIndex, SEHTryParentIndex; + StmtResult TryBlock; + { + assert(Tok.is(tok::l_brace) && "Not a compount stmt!"); + + // Enter a scope to hold everything within the compound stmt. Compound + // statements can always hold declarations. + ParseScope CompoundScope(this, Scope::DeclScope | Scope::SEHTryScope); + SEHTryIndex = getCurScope()->getSEHTryIndex(); + SEHTryParentIndex = getCurScope()->getSEHTryParentIndex(); + + // Parse the statements in the body. + TryBlock = ParseCompoundStatementBody(); + } + + //StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false, + // Scope::DeclScope | Scope::SEHTryScope)); + if(TryBlock.isInvalid()) return TryBlock; @@ -450,7 +466,9 @@ return Actions.ActOnSEHTryBlock(false /* IsCXXTry */, TryLoc, TryBlock.get(), - Handler.get()); + Handler.get(), + SEHTryIndex, + SEHTryParentIndex); } /// ParseSEHExceptBlock - Handle __except @@ -1966,9 +1984,21 @@ return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace); // FIXME: Possible draft standard bug: attribute-specifier should be allowed? - StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false, - Scope::DeclScope | Scope::TryScope | - (FnTry ? Scope::FnTryCatchScope : 0))); + int SEHTryIndex, SEHTryParentIndex; + StmtResult TryBlock; + { + assert(Tok.is(tok::l_brace) && "Not a compount stmt!"); + + // Enter a scope to hold everything within the compound stmt. Compound + // statements can always hold declarations. + ParseScope CompoundScope(this, Scope::DeclScope | Scope::TryScope | + (FnTry ? Scope::FnTryCatchScope : 0)); + SEHTryIndex = getCurScope()->getSEHTryIndex(); + SEHTryParentIndex = getCurScope()->getSEHTryParentIndex(); + + // Parse the statements in the body. + TryBlock = ParseCompoundStatementBody(); + } if (TryBlock.isInvalid()) return TryBlock; @@ -1993,7 +2023,9 @@ return Actions.ActOnSEHTryBlock(true /* IsCXXTry */, TryLoc, TryBlock.get(), - Handler.get()); + Handler.get(), + SEHTryIndex, + SEHTryParentIndex); } else { StmtVector Handlers; Index: lib/Sema/Scope.cpp =================================================================== --- lib/Sema/Scope.cpp +++ lib/Sema/Scope.cpp @@ -39,6 +39,9 @@ BlockParent = parent->BlockParent; TemplateParamParent = parent->TemplateParamParent; MSLocalManglingParent = parent->MSLocalManglingParent; + SEHTryParent = parent->SEHTryParent; + if (parent->Flags & SEHTryScope) + SEHTryParent = parent; if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope | FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) == 0) @@ -47,13 +50,17 @@ Depth = 0; PrototypeDepth = 0; PrototypeIndex = 0; - MSLocalManglingParent = FnParent = BlockParent = nullptr; + SEHTryParent = MSLocalManglingParent = FnParent = BlockParent = nullptr; TemplateParamParent = nullptr; MSLocalManglingNumber = 1; } // If this scope is a function or contains breaks/continues, remember it. if (flags & FnScope) FnParent = this; + SEHTryIndexPool = 0; + SEHTryIndex = -1; + if (flags & SEHTryScope) + SEHTryIndex = FnParent ? FnParent->SEHTryIndexPool++ : -1; // The MS mangler uses the number of scopes that can hold declarations as // part of an external name. if (Flags & (ClassScope | FnScope)) { Index: lib/Sema/SemaStmt.cpp =================================================================== --- lib/Sema/SemaStmt.cpp +++ lib/Sema/SemaStmt.cpp @@ -3243,16 +3243,15 @@ return CXXTryStmt::Create(Context, TryLoc, TryBlock, Handlers); } -StmtResult -Sema::ActOnSEHTryBlock(bool IsCXXTry, - SourceLocation TryLoc, - Stmt *TryBlock, - Stmt *Handler) { +StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, + Stmt *TryBlock, Stmt *Handler, + int HandlerIndex, int HandlerParentIndex) { assert(TryBlock && Handler); getCurFunction()->setHasBranchProtectedScope(); - return SEHTryStmt::Create(Context,IsCXXTry,TryLoc,TryBlock,Handler); + return SEHTryStmt::Create(Context, IsCXXTry, TryLoc, TryBlock, Handler, + HandlerIndex, HandlerParentIndex); } StmtResult Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -1653,8 +1653,10 @@ } StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, - Stmt *TryBlock, Stmt *Handler) { - return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler); + Stmt *TryBlock, Stmt *Handler, int HandlerIndex, + int HandlerParentIndex) { + return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler, + HandlerIndex, HandlerParentIndex); } StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, @@ -6366,8 +6368,9 @@ Handler.get() == S->getHandler()) return S; - return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(), - TryBlock.get(), Handler.get()); + return getDerived().RebuildSEHTryStmt( + S->getIsCXXTry(), S->getTryLoc(), TryBlock.get(), Handler.get(), + S->getHandlerIndex(), S->getHandlerParentIndex()); } template