mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Rollback expression / macro unification.
This commit is contained in:
@@ -1016,6 +1016,13 @@ typedef struct
|
||||
void *block_return_out;
|
||||
} BlockExit;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AstId first_stmt;
|
||||
BlockExit **block_exit_ref;
|
||||
} ExprFuncBlock;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AstId first_stmt;
|
||||
@@ -1023,9 +1030,12 @@ typedef struct
|
||||
bool is_must_use : 1;
|
||||
bool is_optional_return : 1;
|
||||
bool had_optional_arg : 1;
|
||||
DeclId macro_id;
|
||||
Decl **params;
|
||||
Decl *macro;
|
||||
BlockExit **block_exit;
|
||||
} ExprBlock;
|
||||
} ExprMacroBlock;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -1166,6 +1176,7 @@ struct Expr_
|
||||
ExprEmbedExpr embed_expr; // 16
|
||||
Expr** exec_expr; // 8
|
||||
ExprAsmArg expr_asm_arg; // 24
|
||||
ExprFuncBlock expr_block; // 4
|
||||
ExprCompoundLiteral expr_compound_literal; // 16
|
||||
Expr** expression_list; // 8
|
||||
ExprGenericIdent generic_ident_expr;
|
||||
@@ -1174,7 +1185,7 @@ struct Expr_
|
||||
Expr** initializer_list; // 8
|
||||
Expr *inner_expr; // 8
|
||||
Decl *lambda_expr; // 8
|
||||
ExprBlock expr_block; // 24
|
||||
ExprMacroBlock macro_block; // 24
|
||||
ExprMacroBody macro_body_expr; // 16;
|
||||
OperatorOverload overload_expr; // 4
|
||||
ExprPointerOffset pointer_offset_expr;
|
||||
|
||||
@@ -449,13 +449,18 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr)
|
||||
case EXPR_COND:
|
||||
MACRO_COPY_EXPR_LIST(expr->cond_expr);
|
||||
return expr;
|
||||
case EXPR_EXPR_BLOCK:
|
||||
MACRO_COPY_ASTID(expr->expr_block.first_stmt);
|
||||
case EXPR_MACRO_BLOCK:
|
||||
MACRO_COPY_DECL_LIST(expr->macro_block.params);
|
||||
MACRO_COPY_ASTID(expr->macro_block.first_stmt);
|
||||
fixup_decl(c, &expr->macro_block.macro);
|
||||
return expr;
|
||||
case EXPR_COMPOUND_LITERAL:
|
||||
MACRO_COPY_EXPR(expr->expr_compound_literal.initializer);
|
||||
MACRO_COPY_TYPE(expr->expr_compound_literal.type_info);
|
||||
return expr;
|
||||
case EXPR_EXPR_BLOCK:
|
||||
MACRO_COPY_ASTID(expr->expr_block.first_stmt);
|
||||
return expr;
|
||||
case EXPR_POISONED:
|
||||
return source_expr;
|
||||
case EXPR_RETHROW:
|
||||
|
||||
@@ -251,6 +251,7 @@ typedef enum
|
||||
EXPR_INITIALIZER_LIST,
|
||||
EXPR_LAMBDA,
|
||||
EXPR_LAST_FAULT,
|
||||
EXPR_MACRO_BLOCK,
|
||||
EXPR_MACRO_BODY_EXPANSION,
|
||||
EXPR_NOP,
|
||||
EXPR_OPERATOR_CHARS,
|
||||
|
||||
@@ -104,6 +104,7 @@ bool expr_may_addr(Expr *expr)
|
||||
case EXPR_EXPR_BLOCK:
|
||||
case EXPR_OPTIONAL:
|
||||
case EXPR_FORCE_UNWRAP:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_MACRO_BODY_EXPANSION:
|
||||
case EXPR_NOP:
|
||||
case EXPR_OPERATOR_CHARS:
|
||||
@@ -218,6 +219,7 @@ bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind)
|
||||
case EXPR_POST_UNARY:
|
||||
case EXPR_SLICE_ASSIGN:
|
||||
case EXPR_SLICE_COPY:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_RETHROW:
|
||||
return false;
|
||||
case EXPR_IDENTIFIER:
|
||||
@@ -508,9 +510,9 @@ bool expr_is_compile_time(Expr *expr)
|
||||
{
|
||||
case EXPR_CONST:
|
||||
return true;
|
||||
case EXPR_EXPR_BLOCK:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
{
|
||||
AstId current = expr->expr_block.first_stmt;
|
||||
AstId current = expr->macro_block.first_stmt;
|
||||
while (current)
|
||||
{
|
||||
if (!ast_is_compile_time(ast_next(¤t))) return false;
|
||||
@@ -740,6 +742,7 @@ bool expr_is_pure(Expr *expr)
|
||||
case EXPR_OPTIONAL:
|
||||
case EXPR_RETHROW:
|
||||
case EXPR_HASH_IDENT:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_INITIALIZER_LIST:
|
||||
case EXPR_DESIGNATED_INITIALIZER_LIST:
|
||||
case EXPR_POST_UNARY:
|
||||
|
||||
@@ -24,6 +24,7 @@ static inline void llvm_emit_initialize_reference_bitstruct(GenContext *c, BEVal
|
||||
static inline void llvm_emit_initialize_reference_list(GenContext *c, BEValue *ref, Expr *expr);
|
||||
static inline void llvm_emit_initialize_reference_vector(GenContext *c, BEValue *ref, Type *real_type, Expr **elements);
|
||||
static inline void llvm_emit_initializer_list_expr(GenContext *c, BEValue *value, Expr *expr);
|
||||
static inline void llvm_emit_macro_block(GenContext *c, BEValue *be_value, Expr *expr);
|
||||
static inline void llvm_emit_post_inc_dec(GenContext *c, BEValue *value, Expr *expr, int diff, bool allow_wrap);
|
||||
static inline void llvm_emit_pre_inc_dec(GenContext *c, BEValue *value, Expr *expr, int diff, bool allow_wrap);
|
||||
static inline void llvm_emit_return_block(GenContext *c, BEValue *be_value, Type *type, AstId current, BlockExit **block_exit);
|
||||
@@ -6172,30 +6173,77 @@ DONE:
|
||||
}
|
||||
|
||||
static inline void llvm_emit_expr_block(GenContext *c, BEValue *be_value, Expr *expr)
|
||||
{
|
||||
DEBUG_PUSH_LEXICAL_SCOPE(c, astptr(expr->expr_block.first_stmt)->span);
|
||||
llvm_emit_return_block(c, be_value, expr->type, expr->expr_block.first_stmt, expr->expr_block.block_exit_ref);
|
||||
DEBUG_POP_LEXICAL_SCOPE(c);
|
||||
}
|
||||
|
||||
static inline void llvm_emit_macro_block(GenContext *c, BEValue *be_value, Expr *expr)
|
||||
{
|
||||
DebugScope *old_inline_location = c->debug.block_stack;
|
||||
DebugScope updated;
|
||||
if (expr->expr_block.macro_id && llvm_use_debug(c))
|
||||
if (llvm_use_debug(c))
|
||||
{
|
||||
SourceSpan span = expr->span;
|
||||
Decl *macro = declptr(expr->expr_block.macro_id);
|
||||
Decl *macro = expr->macro_block.macro;
|
||||
LLVMMetadataRef macro_def = llvm_debug_create_macro(c, macro);
|
||||
LLVMMetadataRef loc = llvm_create_debug_location(c, span);
|
||||
|
||||
updated = (DebugScope) { .lexical_block = macro_def, .inline_loc = loc, .outline_loc = old_inline_location };
|
||||
c->debug.block_stack = &updated;
|
||||
}
|
||||
DEBUG_PUSH_LEXICAL_SCOPE(c, astptr(expr->expr_block.first_stmt)->span);
|
||||
llvm_emit_return_block(c, be_value, expr->type, expr->expr_block.first_stmt, expr->expr_block.block_exit);
|
||||
bool is_unreachable = expr->expr_block.is_noreturn && c->current_block;
|
||||
FOREACH_BEGIN(Decl *val, expr->macro_block.params)
|
||||
// Skip vararg
|
||||
if (!val) continue;
|
||||
// In case we have a constant, we never do an emit. The value is already folded.
|
||||
switch (val->var.kind)
|
||||
{
|
||||
case VARDECL_CONST:
|
||||
case VARDECL_GLOBAL:
|
||||
case VARDECL_LOCAL:
|
||||
case VARDECL_MEMBER:
|
||||
case VARDECL_LOCAL_CT:
|
||||
case VARDECL_LOCAL_CT_TYPE:
|
||||
case VARDECL_UNWRAPPED:
|
||||
case VARDECL_REWRAPPED:
|
||||
case VARDECL_ERASE:
|
||||
case VARDECL_BITMEMBER:
|
||||
UNREACHABLE
|
||||
case VARDECL_PARAM_CT:
|
||||
case VARDECL_PARAM_CT_TYPE:
|
||||
case VARDECL_PARAM_EXPR:
|
||||
continue;
|
||||
case VARDECL_PARAM_REF:
|
||||
case VARDECL_PARAM:
|
||||
break;
|
||||
}
|
||||
|
||||
Expr *init_expr = val->var.init_expr;
|
||||
BEValue value;
|
||||
c->debug.block_stack = old_inline_location;
|
||||
llvm_emit_expr(c, &value, init_expr);
|
||||
if (llvm_value_is_addr(&value) || val->var.is_written || val->var.is_addr || llvm_use_accurate_debug_info(c))
|
||||
{
|
||||
c->debug.block_stack = &updated;
|
||||
llvm_emit_and_set_decl_alloca(c, val);
|
||||
llvm_store_decl(c, val, &value);
|
||||
continue;
|
||||
}
|
||||
val->is_value = true;
|
||||
val->backend_value = value.value;
|
||||
FOREACH_END();
|
||||
|
||||
c->debug.block_stack = &updated;
|
||||
llvm_emit_return_block(c, be_value, expr->type, expr->macro_block.first_stmt, expr->macro_block.block_exit);
|
||||
bool is_unreachable = expr->macro_block.is_noreturn && c->current_block;
|
||||
if (is_unreachable)
|
||||
{
|
||||
llvm_emit_unreachable(c);
|
||||
}
|
||||
DEBUG_POP_LEXICAL_SCOPE(c);
|
||||
c->debug.block_stack = old_inline_location;
|
||||
}
|
||||
|
||||
|
||||
LLVMValueRef llvm_emit_call_intrinsic(GenContext *context, unsigned intrinsic, LLVMTypeRef *types, unsigned type_count,
|
||||
LLVMValueRef *values, unsigned arg_count)
|
||||
{
|
||||
@@ -6859,6 +6907,9 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
case EXPR_TRY_UNWRAP_CHAIN:
|
||||
llvm_emit_try_unwrap_chain(c, value, expr);
|
||||
return;
|
||||
case EXPR_MACRO_BLOCK:
|
||||
llvm_emit_macro_block(c, value, expr);
|
||||
return;
|
||||
case EXPR_TRY_UNWRAP:
|
||||
llvm_emit_try_unwrap(c, value, expr);
|
||||
return;
|
||||
|
||||
@@ -540,6 +540,7 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp
|
||||
case EXPR_DESIGNATED_INITIALIZER_LIST:
|
||||
case EXPR_DESIGNATOR:
|
||||
case EXPR_EXPR_BLOCK:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_OPTIONAL:
|
||||
case EXPR_FORCE_UNWRAP:
|
||||
case EXPR_INITIALIZER_LIST:
|
||||
@@ -659,6 +660,7 @@ static bool expr_may_ref(Expr *expr)
|
||||
case EXPR_OPTIONAL:
|
||||
case EXPR_FORCE_UNWRAP:
|
||||
case EXPR_INITIALIZER_LIST:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_MACRO_BODY_EXPANSION:
|
||||
case EXPR_NOP:
|
||||
case EXPR_OPERATOR_CHARS:
|
||||
@@ -2162,40 +2164,16 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s
|
||||
goto EXIT;
|
||||
}
|
||||
}
|
||||
NOT_CT:;
|
||||
Expr **list = NULL;
|
||||
FOREACH_BEGIN(Decl *param, params)
|
||||
if (!param) continue;
|
||||
VarDeclKind kind = param->var.kind;
|
||||
if (kind != VARDECL_PARAM_REF && kind != VARDECL_PARAM) continue;
|
||||
Expr *decl_expr = expr_new(EXPR_DECL, param->span);
|
||||
decl_expr->decl_expr = param;
|
||||
decl_expr->type = param->type;
|
||||
decl_expr->resolve_status = RESOLVE_DONE;
|
||||
vec_add(list, decl_expr);
|
||||
FOREACH_END();
|
||||
Expr *new_block;
|
||||
if (list)
|
||||
{
|
||||
call_expr->expr_kind = EXPR_EXPRESSION_LIST;
|
||||
new_block = expr_new(EXPR_EXPR_BLOCK, call_expr->span);
|
||||
new_block->type = call_expr->type;
|
||||
vec_add(list, new_block);
|
||||
call_expr->expression_list = list;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_block = call_expr;
|
||||
call_expr->expr_kind = EXPR_EXPR_BLOCK;
|
||||
}
|
||||
new_block->resolve_status = RESOLVE_DONE;
|
||||
new_block->expr_block.macro_id = declid(decl);
|
||||
new_block->expr_block.had_optional_arg = has_optional_arg;
|
||||
new_block->expr_block.is_must_use = must_use;
|
||||
new_block->expr_block.is_optional_return = optional_return;
|
||||
new_block->expr_block.first_stmt = body->compound_stmt.first_stmt;
|
||||
new_block->expr_block.block_exit = block_exit_ref;
|
||||
new_block->expr_block.is_noreturn = is_no_return;
|
||||
NOT_CT:
|
||||
call_expr->expr_kind = EXPR_MACRO_BLOCK;
|
||||
call_expr->macro_block.had_optional_arg = has_optional_arg;
|
||||
call_expr->macro_block.is_must_use = must_use;
|
||||
call_expr->macro_block.is_optional_return = optional_return;
|
||||
call_expr->macro_block.first_stmt = body->compound_stmt.first_stmt;
|
||||
call_expr->macro_block.macro = decl;
|
||||
call_expr->macro_block.params = params;
|
||||
call_expr->macro_block.block_exit = block_exit_ref;
|
||||
call_expr->macro_block.is_noreturn = is_no_return;
|
||||
EXIT:
|
||||
assert(context->active_scope.defer_last == context->active_scope.defer_start);
|
||||
context->active_scope = old_scope;
|
||||
@@ -6823,7 +6801,7 @@ static inline bool sema_expr_analyse_expr_block(SemaContext *context, Type *infe
|
||||
BlockExit **ref = CALLOCS(BlockExit*);
|
||||
BlockExit **stored_block_exit = context->block_exit_ref;
|
||||
context->block_exit_ref = ref;
|
||||
expr->expr_block.block_exit = ref;
|
||||
expr->expr_block.block_exit_ref = ref;
|
||||
SCOPE_START_WITH_FLAGS(SCOPE_EXPR_BLOCK)
|
||||
|
||||
context->block_return_defer = context->active_scope.defer_last;
|
||||
@@ -6871,7 +6849,6 @@ static inline bool sema_expr_analyse_expr_block(SemaContext *context, Type *infe
|
||||
POP_NEXT();
|
||||
context_pop_defers(context, &stmt->next);
|
||||
SCOPE_END;
|
||||
expr->expr_block.macro_id = 0;
|
||||
context->expected_block_type = stored_block_type;
|
||||
context->block_exit_ref = stored_block_exit;
|
||||
context_pop_returns(context, saved_returns);
|
||||
@@ -7982,6 +7959,7 @@ static inline bool sema_expr_analyse_ct_defined(SemaContext *context, Expr *expr
|
||||
case EXPR_ASM:
|
||||
case EXPR_CONST:
|
||||
case EXPR_NOP:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_LAMBDA:
|
||||
case EXPR_EXPR_BLOCK:
|
||||
case EXPR_CT_IS_CONST:
|
||||
@@ -8408,6 +8386,8 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr)
|
||||
case EXPR_BITASSIGN:
|
||||
// Created during semantic analysis
|
||||
UNREACHABLE
|
||||
case EXPR_MACRO_BLOCK:
|
||||
UNREACHABLE
|
||||
case EXPR_TYPEINFO:
|
||||
expr->type = type_typeinfo;
|
||||
return sema_resolve_type_info(context, expr->type_expr, RESOLVE_TYPE_DEFAULT);
|
||||
@@ -8759,15 +8739,15 @@ bool sema_expr_check_discard(SemaContext *context, Expr *expr)
|
||||
if (expr->expr_kind == EXPR_BINARY && expr->binary_expr.operator >= BINARYOP_ASSIGN) return true;
|
||||
if (expr->expr_kind == EXPR_EXPR_BLOCK)
|
||||
{
|
||||
if (!expr->expr_block.macro_id)
|
||||
if (type_is_void(expr->type)) return true;
|
||||
RETURN_SEMA_ERROR(expr, "The block returns a value of type %s, which must be handled – did you forget to assign it to something?",
|
||||
type_quoted_error_string(expr->type));
|
||||
}
|
||||
if (expr->expr_kind == EXPR_MACRO_BLOCK)
|
||||
{
|
||||
if (expr->macro_block.is_must_use)
|
||||
{
|
||||
if (type_is_void(expr->type)) return true;
|
||||
RETURN_SEMA_ERROR(expr, "The block returns a value of type %s, which must be handled – did you forget to assign it to something?",
|
||||
type_quoted_error_string(expr->type));
|
||||
}
|
||||
if (expr->expr_block.is_must_use)
|
||||
{
|
||||
if (expr->expr_block.is_optional_return)
|
||||
if (expr->macro_block.is_optional_return)
|
||||
{
|
||||
RETURN_SEMA_ERROR(expr, "The macro returns %s, which is an optional and must be handled. "
|
||||
"You can either assign it to a variable, rethrow it using '!', "
|
||||
@@ -8776,7 +8756,7 @@ bool sema_expr_check_discard(SemaContext *context, Expr *expr)
|
||||
}
|
||||
RETURN_SEMA_ERROR(expr, "The called macro is marked `@nodiscard` meaning the result should be kept. You can still discard it using a void cast (e.g. '(void)the_call()') if you want.");
|
||||
}
|
||||
if (expr->expr_block.had_optional_arg) goto ERROR_ARGS;
|
||||
if (expr->macro_block.had_optional_arg) goto ERROR_ARGS;
|
||||
return true;
|
||||
}
|
||||
if (expr->expr_kind == EXPR_CALL)
|
||||
|
||||
@@ -401,6 +401,14 @@ RETRY:
|
||||
case EXPR_LAMBDA:
|
||||
sema_trace_decl_liveness(expr->lambda_expr);
|
||||
return;
|
||||
case EXPR_MACRO_BLOCK:
|
||||
{
|
||||
FOREACH_BEGIN(Decl *val, expr->macro_block.params)
|
||||
sema_trace_decl_liveness(val);
|
||||
FOREACH_END();
|
||||
sema_trace_stmt_chain_liveness(expr->macro_block.first_stmt);
|
||||
return;
|
||||
}
|
||||
case EXPR_EXPR_BLOCK:
|
||||
sema_trace_stmt_chain_liveness(expr->expr_block.first_stmt);
|
||||
return;
|
||||
|
||||
@@ -647,6 +647,7 @@ static inline bool sema_expr_valid_try_expression(Expr *expr)
|
||||
case EXPR_EMBED:
|
||||
case EXPR_EXPRESSION_LIST:
|
||||
case EXPR_EXPR_BLOCK:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_OPTIONAL:
|
||||
case EXPR_FORCE_UNWRAP:
|
||||
case EXPR_GENERIC_IDENT:
|
||||
@@ -1227,8 +1228,8 @@ static inline bool sema_analyse_expr_stmt(SemaContext *context, Ast *statement)
|
||||
case EXPR_CALL:
|
||||
if (expr->call_expr.no_return) context->active_scope.jump_end = true;
|
||||
break;
|
||||
case EXPR_EXPR_BLOCK:
|
||||
if (expr->expr_block.is_noreturn) context->active_scope.jump_end = true;
|
||||
case EXPR_MACRO_BLOCK:
|
||||
if (expr->macro_block.is_noreturn) context->active_scope.jump_end = true;
|
||||
break;
|
||||
case EXPR_CONST:
|
||||
// Remove all const statements.
|
||||
|
||||
@@ -47,48 +47,48 @@ entry:
|
||||
%0 = load ptr, ptr %x1, align 8, !dbg !16
|
||||
%1 = load atomic i32, ptr %0 seq_cst, align 4, !dbg !16
|
||||
store i32 %1, ptr %x, align 4, !dbg !16
|
||||
call void @llvm.dbg.declare(metadata ptr %y, metadata !21, metadata !DIExpression()), !dbg !22
|
||||
call void @llvm.dbg.declare(metadata ptr %y, metadata !20, metadata !DIExpression()), !dbg !21
|
||||
store ptr %a, ptr %x2, align 8
|
||||
%2 = load ptr, ptr %x2, align 8, !dbg !23
|
||||
%3 = load atomic volatile i32, ptr %2 monotonic, align 4, !dbg !23
|
||||
store i32 %3, ptr %y, align 4, !dbg !23
|
||||
%2 = load ptr, ptr %x2, align 8, !dbg !22
|
||||
%3 = load atomic volatile i32, ptr %2 monotonic, align 4, !dbg !22
|
||||
store i32 %3, ptr %y, align 4, !dbg !22
|
||||
store ptr %a, ptr %x3, align 8
|
||||
%4 = load i32, ptr %x, align 4, !dbg !27
|
||||
%add = add i32 123, %4, !dbg !28
|
||||
%4 = load i32, ptr %x, align 4, !dbg !25
|
||||
%add = add i32 123, %4, !dbg !26
|
||||
store i32 %add, ptr %value, align 4
|
||||
%5 = load ptr, ptr %x3, align 8, !dbg !29
|
||||
%6 = load i32, ptr %value, align 4, !dbg !29
|
||||
store atomic i32 %6, ptr %5 seq_cst, align 4, !dbg !29
|
||||
%5 = load ptr, ptr %x3, align 8, !dbg !27
|
||||
%6 = load i32, ptr %value, align 4, !dbg !27
|
||||
store atomic i32 %6, ptr %5 seq_cst, align 4, !dbg !27
|
||||
store ptr %a, ptr %x4, align 8
|
||||
%7 = load i32, ptr %y, align 4, !dbg !33
|
||||
%add5 = add i32 33, %7, !dbg !34
|
||||
%7 = load i32, ptr %y, align 4, !dbg !30
|
||||
%add5 = add i32 33, %7, !dbg !31
|
||||
store i32 %add5, ptr %value6, align 4
|
||||
%8 = load ptr, ptr %x4, align 8, !dbg !35
|
||||
%9 = load i32, ptr %value6, align 4, !dbg !35
|
||||
store atomic volatile i32 %9, ptr %8 monotonic, align 4, !dbg !35
|
||||
%10 = insertvalue %any undef, ptr %a, 0, !dbg !39
|
||||
%11 = insertvalue %any %10, i64 ptrtoint (ptr @"$ct.int" to i64), 1, !dbg !39
|
||||
store %any %11, ptr %varargslots, align 16, !dbg !39
|
||||
%12 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 2, ptr %varargslots, i64 1), !dbg !40
|
||||
ret void, !dbg !40
|
||||
%8 = load ptr, ptr %x4, align 8, !dbg !32
|
||||
%9 = load i32, ptr %value6, align 4, !dbg !32
|
||||
store atomic volatile i32 %9, ptr %8 monotonic, align 4, !dbg !32
|
||||
%10 = insertvalue %any undef, ptr %a, 0, !dbg !35
|
||||
%11 = insertvalue %any %10, i64 ptrtoint (ptr @"$ct.int" to i64), 1, !dbg !35
|
||||
store %any %11, ptr %varargslots, align 16, !dbg !35
|
||||
%12 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 2, ptr %varargslots, i64 1), !dbg !36
|
||||
ret void, !dbg !36
|
||||
}
|
||||
; Function Attrs: nounwind uwtable
|
||||
define i32 @main(i32 %0, ptr %1) #0 !dbg !41 {
|
||||
define i32 @main(i32 %0, ptr %1) #0 !dbg !37 {
|
||||
entry:
|
||||
%.anon = alloca i32, align 4
|
||||
%.anon1 = alloca ptr, align 8
|
||||
%.anon2 = alloca i32, align 4
|
||||
%.anon3 = alloca ptr, align 8
|
||||
store i32 %0, ptr %.anon, align 4
|
||||
call void @llvm.dbg.declare(metadata ptr %.anon, metadata !47, metadata !DIExpression()), !dbg !48
|
||||
call void @llvm.dbg.declare(metadata ptr %.anon, metadata !43, metadata !DIExpression()), !dbg !44
|
||||
store ptr %1, ptr %.anon1, align 8
|
||||
call void @llvm.dbg.declare(metadata ptr %.anon1, metadata !49, metadata !DIExpression()), !dbg !48
|
||||
call void @llvm.dbg.declare(metadata ptr %.anon1, metadata !45, metadata !DIExpression()), !dbg !44
|
||||
%2 = load i32, ptr %.anon, align 4
|
||||
store i32 %2, ptr %.anon2, align 4
|
||||
%3 = load ptr, ptr %.anon1, align 8
|
||||
store ptr %3, ptr %.anon3, align 8
|
||||
call void @test.main(), !dbg !50
|
||||
ret i32 0, !dbg !54
|
||||
call void @test.main(), !dbg !46
|
||||
ret i32 0, !dbg !49
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
|
||||
@@ -117,41 +117,36 @@ declare i1 @llvm.expect.i1(i1, i1) #2
|
||||
!14 = !DILocalVariable(name: "x", scope: !6, file: !5, line: 13, type: !11, align: 4)
|
||||
!15 = !DILocation(line: 13, column: 6, scope: !6)
|
||||
!16 = !DILocation(line:
|
||||
!17 = distinct !DILexicalBlock(scope: !19, file: !18,
|
||||
!17 = distinct !DISubprogram(name: "@atomic_load", linkageName: "@atomic_load", scope: !18, file: !18,
|
||||
!18 = !DIFile(filename: "mem.c3",
|
||||
!19 = distinct !DISubprogram(name: "@atomic_load", linkageName: "@atomic_load", scope: !18
|
||||
!20 = !DILocation(line: 13, column: 10, scope: !6)
|
||||
!21 = !DILocalVariable(name: "y", scope: !6, file: !5, line: 14, type: !11, align: 4)
|
||||
!22 = !DILocation(line: 14, column: 6, scope: !6)
|
||||
!23 = !DILocation(line:
|
||||
!24 = distinct !DILexicalBlock(scope: !25, file: !18
|
||||
!25 = distinct !DISubprogram(name: "@atomic_load", linkageName: "@atomic_load", scope: !18
|
||||
!26 = !DILocation(line: 14, column: 10, scope: !6)
|
||||
!27 = !DILocation(line: 15, column: 25, scope: !6)
|
||||
!28 = !DILocation(line: 15, column: 19, scope: !6)
|
||||
!29 = !DILocation(line: 212, column: 20, scope: !30, inlinedAt: !32)
|
||||
!30 = distinct !DILexicalBlock(scope: !31, file: !18, line:
|
||||
!31 = distinct !DISubprogram(name: "@atomic_store", linkageName: "@atomic_store", scope: !18
|
||||
!32 = !DILocation(line: 15, column: 2, scope: !6)
|
||||
!33 = !DILocation(line: 16, column: 24, scope: !6)
|
||||
!34 = !DILocation(line: 16, column: 19, scope: !6)
|
||||
!35 = !DILocation(line: 212, column: 20, scope: !36, inlinedAt: !38)
|
||||
!36 = distinct !DILexicalBlock(scope: !37, file: !18, line: 212, column: 2)
|
||||
!37 = distinct !DISubprogram(name: "@atomic_store", linkageName: "@atomic_store", scope: !18, file: !18, line: 210, scopeLine: 210, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !4
|
||||
!38 = !DILocation(line: 16, column: 2, scope: !6)
|
||||
!39 = !DILocation(line: 17, column: 20, scope: !6)
|
||||
!40 = !DILocation(line: 17, column: 6, scope: !6)
|
||||
!41 = distinct !DISubprogram(name: "_$main", linkageName: "main", scope: !5, file: !5, line: 10, type: !42, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !4, retainedNodes: !9)
|
||||
!42 = !DISubroutineType(types: !43)
|
||||
!43 = !{!11, !11, !44}
|
||||
!44 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char**", baseType: !45, size: 64, align: 64, dwarfAddressSpace: 0)
|
||||
!45 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char*", baseType: !46, size: 64, align: 64, dwarfAddressSpace: 0)
|
||||
!46 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char)
|
||||
!47 = !DILocalVariable(name: ".anon", arg: 1, scope: !41, file: !5, line: 10, type: !11)
|
||||
!48 = !DILocation(line: 10, column: 9, scope: !41)
|
||||
!49 = !DILocalVariable(name: ".anon", arg: 2, scope: !41, file: !5, line: 10, type: !44)
|
||||
!50 = !DILocation(line: 18, column: 2, scope: !51, inlinedAt: !48)
|
||||
!51 = distinct !DILexicalBlock(scope: !53, file: !52, line: 18, column: 2)
|
||||
!52 = !DIFile(filename: "main_stub.c3"
|
||||
!53 = distinct !DISubprogram(name: "@main_to_void_main", linkageName: "@main_to_void_main", scope: !52, file: !52, line: 16, scopeLine: 16, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition,
|
||||
!54 = !DILocation(line: 19, column: 9, scope: !51, inlinedAt: !48)
|
||||
!19 = !DILocation(line: 13, column: 10, scope: !6)
|
||||
!20 = !DILocalVariable(name: "y", scope: !6, file: !5, line: 14, type: !11, align: 4)
|
||||
!21 = !DILocation(line: 14, column: 6, scope: !6)
|
||||
!22 = !DILocation(line:
|
||||
!23 = distinct !DISubprogram(name: "@atomic_load", linkageName: "@atomic_load", scope: !18
|
||||
!24 = !DILocation(line: 14, column: 10, scope: !6)
|
||||
!25 = !DILocation(line: 15, column: 25, scope: !6)
|
||||
!26 = !DILocation(line: 15, column: 19, scope: !6)
|
||||
!27 = !DILocation(line: 212, column: 20, scope: !28, inlinedAt: !29)
|
||||
!28 = distinct !DISubprogram(name: "@atomic_store", linkageName: "@atomic_store", scope: !18
|
||||
!29 = !DILocation(line: 15, column: 2, scope: !6)
|
||||
!30 = !DILocation(line: 16, column: 24, scope: !6)
|
||||
!31 = !DILocation(line: 16, column: 19, scope: !6)
|
||||
!32 = !DILocation(line: 212, column: 20, scope: !33, inlinedAt: !34)
|
||||
!33 = distinct !DISubprogram(name: "@atomic_store", linkageName: "@atomic_store", scope: !18, file: !18, line: 210, scopeLine: 210, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !4
|
||||
!34 = !DILocation(line: 16, column: 2, scope: !6)
|
||||
!35 = !DILocation(line: 17, column: 20, scope: !6)
|
||||
!36 = !DILocation(line: 17, column: 6, scope: !6)
|
||||
!37 = distinct !DISubprogram(name: "_$main", linkageName: "main", scope: !5, file: !5, line: 10, type: !38, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !4, retainedNodes: !9)
|
||||
!38 = !DISubroutineType(types: !39)
|
||||
!39 = !{!11, !11, !40}
|
||||
!40 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char**", baseType: !41, size: 64, align: 64, dwarfAddressSpace: 0)
|
||||
!41 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char*", baseType: !42, size: 64, align: 64, dwarfAddressSpace: 0)
|
||||
!42 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char)
|
||||
!43 = !DILocalVariable(name: ".anon", arg: 1, scope: !37, file: !5, line: 10, type: !11)
|
||||
!44 = !DILocation(line: 10, column: 9, scope: !37)
|
||||
!45 = !DILocalVariable(name: ".anon", arg: 2, scope: !37, file: !5, line: 10, type: !40)
|
||||
!46 = !DILocation(line: 18, column: 2, scope: !47, inlinedAt: !44)
|
||||
!47 = distinct !DISubprogram(name: "@main_to_void_main", linkageName: "@main_to_void_main", scope: !48, file: !48, line: 16, scopeLine: 16, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
|
||||
!48 = !DIFile(filename: "main_stub.c3", directory:
|
||||
!49 = !DILocation(line: 19, column: 9, scope: !47, inlinedAt: !44)
|
||||
Reference in New Issue
Block a user