mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Improved debug information on defer.
This commit is contained in:
@@ -1213,6 +1213,7 @@ static_assert(sizeof(Expr) == 56, "Expr not expected size");
|
||||
typedef struct
|
||||
{
|
||||
AstId first_stmt;
|
||||
AstId parent_defer;
|
||||
} AstCompoundStmt;
|
||||
|
||||
|
||||
@@ -1338,6 +1339,7 @@ typedef struct
|
||||
{
|
||||
AstId prev_defer;
|
||||
AstId body; // Compound statement
|
||||
void *scope;
|
||||
bool is_try : 1;
|
||||
bool is_catch : 1;
|
||||
} AstDeferStmt;
|
||||
|
||||
@@ -625,6 +625,7 @@ RETRY:
|
||||
break;
|
||||
case AST_COMPOUND_STMT:
|
||||
MACRO_COPY_ASTID(ast->compound_stmt.first_stmt);
|
||||
fixup_astid(c, &ast->compound_stmt.parent_defer);
|
||||
break;
|
||||
case AST_CT_IF_STMT:
|
||||
MACRO_COPY_EXPR(ast->ct_if_stmt.expr);
|
||||
|
||||
@@ -11,6 +11,13 @@ void llvm_emit_compound_stmt(GenContext *c, Ast *ast)
|
||||
{
|
||||
assert(ast->ast_kind == AST_COMPOUND_STMT);
|
||||
|
||||
DebugScope *old_block = NULL;
|
||||
if (ast->compound_stmt.parent_defer && llvm_use_debug(c))
|
||||
{
|
||||
old_block = c->debug.block_stack;
|
||||
assert(ast->compound_stmt.parent_defer);
|
||||
c->debug.block_stack = astptr(ast->compound_stmt.parent_defer)->defer_stmt.scope;
|
||||
}
|
||||
// Push the lexical scope if in debug.
|
||||
DEBUG_PUSH_LEXICAL_SCOPE(c, ast->span);
|
||||
|
||||
@@ -19,6 +26,7 @@ void llvm_emit_compound_stmt(GenContext *c, Ast *ast)
|
||||
|
||||
// Pop lexical scope.
|
||||
DEBUG_POP_LEXICAL_SCOPE(c);
|
||||
if (old_block) c->debug.block_stack = old_block;
|
||||
}
|
||||
|
||||
void llvm_emit_local_static(GenContext *c, Decl *decl, BEValue *value)
|
||||
@@ -1616,6 +1624,8 @@ void llvm_emit_stmt(GenContext *c, Ast *ast)
|
||||
gencontext_emit_next_stmt(c, ast);
|
||||
break;
|
||||
case AST_DEFER_STMT:
|
||||
if (llvm_use_debug(c)) ast->defer_stmt.scope = c->debug.block_stack;
|
||||
break;
|
||||
case AST_NOP_STMT:
|
||||
break;
|
||||
case AST_ASM_BLOCK_STMT:
|
||||
|
||||
@@ -26,7 +26,7 @@ static inline bool sema_analyse_switch_stmt(SemaContext *context, Ast *statement
|
||||
static inline bool sema_return_optional_check_is_valid_in_scope(SemaContext *context, Expr *ret_expr);
|
||||
static inline bool sema_defer_by_result(AstId defer_top, AstId defer_bottom);
|
||||
static inline bool sema_analyse_block_exit_stmt(SemaContext *context, Ast *statement);
|
||||
static inline bool sema_analyse_defer_stmt_body(SemaContext *context, Ast *statement, Ast *body);
|
||||
static inline bool sema_analyse_defer_stmt_body(SemaContext *context, Ast *statement);
|
||||
static inline bool sema_analyse_for_cond(SemaContext *context, ExprId *cond_ref, bool *infinite);
|
||||
static inline bool assert_create_from_contract(SemaContext *context, Ast *directive, AstId **asserts, SourceSpan evaluation_location);
|
||||
static bool sema_analyse_asm_string_stmt(SemaContext *context, Ast *stmt);
|
||||
@@ -1241,13 +1241,21 @@ static inline bool sema_analyse_expr_stmt(SemaContext *context, Ast *statement)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sema_analyse_defer_stmt_body(SemaContext *context, Ast *statement, Ast *body)
|
||||
bool sema_analyse_defer_stmt_body(SemaContext *context, Ast *statement)
|
||||
{
|
||||
Ast *body = astptr(statement->defer_stmt.body);
|
||||
if (body->ast_kind == AST_DEFER_STMT)
|
||||
{
|
||||
SEMA_ERROR(body, "A defer may not have a body consisting of a raw 'defer', this looks like a mistake.");
|
||||
return false;
|
||||
RETURN_SEMA_ERROR(body, "A defer may not have a body consisting of a raw 'defer', this looks like a mistake.");
|
||||
}
|
||||
if (body->ast_kind != AST_COMPOUND_STMT)
|
||||
{
|
||||
Ast *new_body = new_ast(AST_COMPOUND_STMT, body->span);
|
||||
new_body->compound_stmt.first_stmt = astid(body);
|
||||
body = new_body;
|
||||
statement->defer_stmt.body = astid(body);
|
||||
}
|
||||
body->compound_stmt.parent_defer = astid(statement);
|
||||
bool success = true;
|
||||
SCOPE_START
|
||||
|
||||
@@ -1276,7 +1284,7 @@ bool sema_analyse_defer_stmt_body(SemaContext *context, Ast *statement, Ast *bod
|
||||
static inline bool sema_analyse_defer_stmt(SemaContext *context, Ast *statement)
|
||||
{
|
||||
|
||||
if (!sema_analyse_defer_stmt_body(context, statement, astptr(statement->defer_stmt.body))) return false;
|
||||
if (!sema_analyse_defer_stmt_body(context, statement)) return false;
|
||||
|
||||
statement->defer_stmt.prev_defer = context->active_scope.defer_last;
|
||||
context->active_scope.defer_last = astid(statement);
|
||||
@@ -1328,14 +1336,12 @@ static inline bool sema_analyse_for_stmt(SemaContext *context, Ast *statement)
|
||||
assert(body);
|
||||
if (body->ast_kind == AST_DEFER_STMT)
|
||||
{
|
||||
SEMA_ERROR(body, "Looping over a raw 'defer' is not allowed, was this a mistake?");
|
||||
return false;
|
||||
RETURN_SEMA_ERROR(body, "Looping over a raw 'defer' is not allowed, was this a mistake?");
|
||||
}
|
||||
bool do_loop = statement->for_stmt.flow.skip_first;
|
||||
if (body->ast_kind != AST_COMPOUND_STMT && do_loop)
|
||||
{
|
||||
SEMA_ERROR(body, "A do loop must use { } around its body.");
|
||||
return false;
|
||||
RETURN_SEMA_ERROR(body, "A do loop must use { } around its body.");
|
||||
}
|
||||
// Enter for scope
|
||||
SCOPE_OUTER_START
|
||||
@@ -1825,8 +1831,7 @@ static inline bool sema_analyse_if_stmt(SemaContext *context, Ast *statement)
|
||||
Ast *then = astptr(statement->if_stmt.then_body);
|
||||
if (then->ast_kind == AST_DEFER_STMT)
|
||||
{
|
||||
SEMA_ERROR(then, "An 'if' statement may not be followed by a raw 'defer' statement, this looks like a mistake.");
|
||||
return false;
|
||||
RETURN_SEMA_ERROR(then, "An 'if' statement may not be followed by a raw 'defer' statement, this looks like a mistake.");
|
||||
}
|
||||
AstId else_id = statement->if_stmt.else_body;
|
||||
Ast *else_body = else_id ? astptr(else_id) : NULL;
|
||||
|
||||
Reference in New Issue
Block a user