]> granicus.if.org Git - clang/commitdiff
[MS-ABI] Assign SEH handler indices to __try blocks
authorWarren Hunt <whunt@google.com>
Sat, 19 Jul 2014 00:45:07 +0000 (00:45 +0000)
committerWarren Hunt <whunt@google.com>
Sat, 19 Jul 2014 00:45:07 +0000 (00:45 +0000)
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
include/clang/Sema/Scope.h
include/clang/Sema/Sema.h
lib/AST/Stmt.cpp
lib/Parse/ParseStmt.cpp
lib/Sema/Scope.cpp
lib/Sema/SemaStmt.cpp
lib/Sema/TreeTransform.h

index 790c8e3e663dfc52712e4c5759f831718fe1262b..fb94097cfac72a34f7b96591db78c9ad4900f978 100644 (file)
@@ -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 SEHTryStmtCreate(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.
index 27067a111985907ef5497c5a087135f835189a1c..8e4e2ef4be21dbc8988d83b6bb90ac05c43edc76 100644 (file)
@@ -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) {
index 8ecffb6f3c7d42ba204cb29a7cd7d6ac57b2fc6c..bd4493bca6b464114c1e57ffeb85c1b852d1d39c 100644 (file)
@@ -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);
index e46edd23ec022cbfc8edbd561b2c9124d74d03d0..a5ca49df2049de0e4d38be62f464f70b73e5eea8 100644 (file)
@@ -956,22 +956,20 @@ Expr* ReturnStmt::getRetValue() {
   return cast_or_null<Expr>(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;
 }
 
-SEHTryStmtSEHTryStmt::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 6f6c495dde3b5e5de11c355a6202f70a575a7cac..1e8c4a69d86f4d12031db011238404b9986a4732 100644 (file)
@@ -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;
index 6c7977882386cf1a63fc7f46a56746583ff08d35..35e2075b38263e87f7cb5bfc7f9a3db8ca126747 100644 (file)
@@ -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)) {
index 1ddb3694cbeba1bf8038f143e56ca822a5e8f998..278e6d66828b1b14a34f47ffbeeec76034f63fc8 100644 (file)
@@ -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
index 04a3909da35e3dc79eb4024c274656f22ba9ee08..1f648d4aca6da5dbe9afb65fa978acc8a82e2ba8 100644 (file)
@@ -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<Derived>::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 <typename Derived>