diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 9370ab61e..090cb9e6f 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -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; diff --git a/src/compiler/copying.c b/src/compiler/copying.c index 2470bf8b5..af78a842c 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -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: diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 1f8c8f61e..8c1f36e68 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -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, diff --git a/src/compiler/expr.c b/src/compiler/expr.c index 88bea93af..2946a1b46 100644 --- a/src/compiler/expr.c +++ b/src/compiler/expr.c @@ -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: diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 435119a12..e476afcfe 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -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; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index d62c8eb15..ea9efd184 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -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) diff --git a/src/compiler/sema_liveness.c b/src/compiler/sema_liveness.c index 490e3c084..0a6f6e2aa 100644 --- a/src/compiler/sema_liveness.c +++ b/src/compiler/sema_liveness.c @@ -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; diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 4ec2c5b01..761b7baf3 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -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. diff --git a/test/test_suite/concurrency/atomic_load_store_debug.c3t b/test/test_suite/concurrency/atomic_load_store_debug.c3t index 0629e7057..b7a94b117 100644 --- a/test/test_suite/concurrency/atomic_load_store_debug.c3t +++ b/test/test_suite/concurrency/atomic_load_store_debug.c3t @@ -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) \ No newline at end of file +!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) \ No newline at end of file