forked from OSchip/llvm-project
[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. llvm-svn: 213437
This commit is contained in:
parent
6971b861d7
commit
b530bc0242
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue