From e7fa63a7a40f8a46640a317194dbea9b4f36f927 Mon Sep 17 00:00:00 2001 From: Warren Hunt Date: Sat, 19 Jul 2014 00:45:07 +0000 Subject: [MS-ABI] Assign SEH handler indices to __try blocks Assigns indices to try blocks. These indices will used in constructing tables that the mscrt function __except_handler3 reads during SEH. Testing will occur once we actually emit the tables, in a subsequent patch. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213437 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Stmt.h | 15 ++++++++++----- include/clang/Sema/Scope.h | 17 ++++++++++++++++ include/clang/Sema/Sema.h | 6 +++--- lib/AST/Stmt.cpp | 22 ++++++++++----------- lib/Parse/ParseStmt.cpp | 48 ++++++++++++++++++++++++++++++++++++++-------- lib/Sema/Scope.cpp | 9 ++++++++- lib/Sema/SemaStmt.cpp | 11 +++++------ lib/Sema/TreeTransform.h | 11 +++++++---- 8 files changed, 100 insertions(+), 39 deletions(-) diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 790c8e3e66..fb94097cfa 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -1892,22 +1892,24 @@ class SEHTryStmt : public Stmt { 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 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == SEHTryStmtClass; } + + int getHandlerIndex() const { return HandlerIndex; } + int getHandlerParentIndex() const { return HandlerParentIndex; } }; /// Represents a __leave statement. diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h index 27067a1119..8e4e2ef4be 100644 --- a/include/clang/Sema/Scope.h +++ b/include/clang/Sema/Scope.h @@ -135,6 +135,14 @@ private: /// 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 @@ private: /// 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 @@ public: 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) { diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 8ecffb6f3c..bd4493bca6 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -3165,9 +3165,9 @@ public: 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); diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index e46edd23ec..a5ca49df20 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -956,22 +956,20 @@ Expr* ReturnStmt::getRetValue() { 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 { diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 6f6c495dde..1e8c4a69d8 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -424,11 +424,27 @@ StmtResult Parser::ParseSEHTryBlock() { /// 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 @@ StmtResult Parser::ParseSEHTryBlockCommon(SourceLocation TryLoc) { return Actions.ActOnSEHTryBlock(false /* IsCXXTry */, TryLoc, TryBlock.get(), - Handler.get()); + Handler.get(), + SEHTryIndex, + SEHTryParentIndex); } /// ParseSEHExceptBlock - Handle __except @@ -1961,9 +1979,21 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) { 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; @@ -1988,7 +2018,9 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) { return Actions.ActOnSEHTryBlock(true /* IsCXXTry */, TryLoc, TryBlock.get(), - Handler.get()); + Handler.get(), + SEHTryIndex, + SEHTryParentIndex); } else { StmtVector Handlers; diff --git a/lib/Sema/Scope.cpp b/lib/Sema/Scope.cpp index 6c79778823..35e2075b38 100644 --- a/lib/Sema/Scope.cpp +++ b/lib/Sema/Scope.cpp @@ -39,6 +39,9 @@ void Scope::Init(Scope *parent, unsigned flags) { 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 @@ void Scope::Init(Scope *parent, unsigned flags) { 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)) { diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 1ddb3694cb..278e6d6682 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -3249,16 +3249,15 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, 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 diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 04a3909da3..1f648d4aca 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1653,8 +1653,10 @@ public: } 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 @@ StmtResult TreeTransform::TransformSEHTryStmt(SEHTryStmt *S) { 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 -- cgit v1.2.3