mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fixes to wasm and function attributes.
This commit is contained in:
@@ -59,7 +59,63 @@ enum OsType
|
||||
EMSCRIPTEN,
|
||||
}
|
||||
|
||||
enum ArchType
|
||||
{
|
||||
UNKNOWN,
|
||||
ARM, // ARM (little endian): arm, armv.*, xscale
|
||||
ARMB, // ARM (big endian): armeb
|
||||
AARCH64, // AArch64 (little endian): aarch64
|
||||
AARCH64_BE, // AArch64 (big endian): aarch64_be
|
||||
AARCH64_32, // AArch64 (little endian) ILP32: aarch64_32
|
||||
ARC, // ARC: Synopsys ARC
|
||||
AVR, // AVR: Atmel AVR microcontroller
|
||||
BPFEL, // eBPF or extended BPF or 64-bit BPF (little endian)
|
||||
BPFEB, // eBPF or extended BPF or 64-bit BPF (big endian)
|
||||
HEXAGON, // Hexagon: hexagon
|
||||
MIPS, // MIPS: mips, mipsallegrex, mipsr6
|
||||
MIPSEL, // MIPSEL: mipsel, mipsallegrexe, mipsr6el
|
||||
MIPS64, // MIPS64: mips64, mips64r6, mipsn32, mipsn32r6
|
||||
MIPS64EL, // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el
|
||||
MSP430, // MSP430: msp430
|
||||
PPC, // PPC: powerpc
|
||||
PPC64, // PPC64: powerpc64, ppu
|
||||
PPC64LE, // PPC64LE: powerpc64le
|
||||
R600, // R600: AMD GPUs HD2XXX - HD6XXX
|
||||
AMDGCN, // AMDGCN: AMD GCN GPUs
|
||||
RISCV32, // RISC-V (32-bit): riscv32
|
||||
RISCV64, // RISC-V (64-bit): riscv64
|
||||
SPARC, // Sparc: sparc
|
||||
SPARCV9, // Sparcv9: Sparcv9
|
||||
SPARCEL, // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant
|
||||
SYSTEMZ, // SystemZ: s390x
|
||||
TCE, // TCE (http://tce.cs.tut.fi/): tce
|
||||
TCELE, // TCE little endian (http://tce.cs.tut.fi/): tcele
|
||||
THUMB, // Thumb (little endian): thumb, thumbv.*
|
||||
THUMBEB, // Thumb (big endian): thumbeb
|
||||
X86, // X86: i[3-9]86
|
||||
X86_64, // X86-64: amd64, x86_64
|
||||
XCORE, // XCore: xcore
|
||||
NVPTX, // NVPTX: 32-bit
|
||||
NVPTX64, // NVPTX: 64-bit
|
||||
LE32, // le32: generic little-endian 32-bit CPU (PNaCl)
|
||||
LE64, // le64: generic little-endian 64-bit CPU (PNaCl)
|
||||
AMDIL, // AMDIL
|
||||
AMDIL64, // AMDIL with 64-bit pointers
|
||||
HSAIL, // AMD HSAIL
|
||||
HSAIL64, // AMD HSAIL with 64-bit pointers
|
||||
SPIR, // SPIR: standard portable IR for OpenCL 32-bit version
|
||||
SPIR64, // SPIR: standard portable IR for OpenCL 64-bit version
|
||||
KALIMBA, // Kalimba: generic kalimba
|
||||
SHAVE, // SHAVE: Movidius vector VLIW processors
|
||||
LANAI, // Lanai: Lanai 32-bit
|
||||
WASM32, // WebAssembly with 32-bit pointers
|
||||
WASM64, // WebAssembly with 64-bit pointers
|
||||
RSCRIPT32, // 32-bit RenderScript
|
||||
RSCRIPT64, // 64-bit RenderScript
|
||||
}
|
||||
|
||||
const OsType OS_TYPE = (OsType)$$OS_TYPE;
|
||||
const ArchType ARCH_TYPE = (ArchType)$$ARCH_TYPE;
|
||||
const bool COMPILER_LIBC_AVAILABLE = $$COMPILER_LIBC_AVAILABLE;
|
||||
const CompilerOptLevel COMPILER_OPT_LEVEL = (CompilerOptLevel)$$COMPILER_OPT_LEVEL;
|
||||
const bool BIG_ENDIAN = $$PLATFORM_BIG_ENDIAN;
|
||||
|
||||
@@ -294,6 +294,15 @@ macro Allocator* current_allocator()
|
||||
return thread_allocator;
|
||||
}
|
||||
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE && env::ARCH_TYPE == ArchType.WASM32 || env::ARCH_TYPE == ArchType.WASM64):
|
||||
private SimpleHeapAllocator wasm_allocator;
|
||||
|
||||
static initialize @priority(1)
|
||||
{
|
||||
allocator::wasm_memory.allocate_block(allocator::DEFAULT_MEM_ALIGNMENT)!!; // Give us a valid null.
|
||||
wasm_allocator.init(fn (x) => allocator::wasm_memory.allocate_block(x));
|
||||
thread_allocator = &wasm_allocator;
|
||||
}
|
||||
$endif;
|
||||
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ struct WasmMemory
|
||||
uptr use;
|
||||
}
|
||||
|
||||
fn void*! WasmMemory.allocate_block(WasmMemory* this, usz bytes)
|
||||
fn char[]! WasmMemory.allocate_block(WasmMemory* this, usz bytes)
|
||||
{
|
||||
if (!this.allocation)
|
||||
{
|
||||
@@ -200,11 +200,12 @@ fn void*! WasmMemory.allocate_block(WasmMemory* this, usz bytes)
|
||||
if (bytes_required <= 0)
|
||||
{
|
||||
defer this.use += bytes;
|
||||
return (void*)this.use;
|
||||
return ((char*)this.use)[:bytes];
|
||||
}
|
||||
|
||||
usz blocks_required = (bytes_required + WASM_BLOCK_SIZE + 1) / WASM_BLOCK_SIZE;
|
||||
if (!$$wasm_memory_grow(0, blocks_required)) return AllocationFailure.OUT_OF_MEMORY!;
|
||||
if ($$wasm_memory_grow(0, blocks_required) == -1) return AllocationFailure.OUT_OF_MEMORY!;
|
||||
this.allocation = $$wasm_memory_size(0) * WASM_BLOCK_SIZE;
|
||||
defer this.use += bytes;
|
||||
return (void*)this.use;
|
||||
return ((char*)this.use)[:bytes];
|
||||
}
|
||||
@@ -2,12 +2,12 @@ module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
|
||||
fn float powf_broken(float x) @extname("powf") @weak
|
||||
fn float powf_broken(float x, float f) @extname("powf") @weak
|
||||
{
|
||||
unreachable("'powf' not supported");
|
||||
}
|
||||
|
||||
fn float pow_broken(float x) @extname("pow") @weak
|
||||
fn double pow_broken(double x, double y) @extname("pow") @weak
|
||||
{
|
||||
unreachable("'pow' not supported");
|
||||
}
|
||||
|
||||
@@ -96,4 +96,14 @@ fn bool TestRunner.run(TestRunner* runner)
|
||||
fn bool __run_default_test_runner()
|
||||
{
|
||||
return test_runner_create().run();
|
||||
}
|
||||
}
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE && env::ARCH_TYPE == ArchType.WASM32 || env::ARCH_TYPE == ArchType.WASM64):
|
||||
|
||||
extern fn void __wasm_call_ctors();
|
||||
fn void wasm_initialize() @extname("_initialize") @wasm
|
||||
{
|
||||
// The linker synthesizes this to call constructors.
|
||||
__wasm_call_ctors();
|
||||
}
|
||||
$endif;
|
||||
@@ -773,6 +773,7 @@ void compile()
|
||||
setup_bool_define("PLATFORM_I128_SUPPORTED", platform_target.int128);
|
||||
setup_bool_define("PLATFORM_F128_SUPPORTED", platform_target.float128);
|
||||
setup_bool_define("PLATFORM_F16_SUPPORTED", platform_target.float16);
|
||||
setup_int_define("ARCH_TYPE", (uint64_t)platform_target.arch, type_int);
|
||||
setup_int_define("MEMORY_ENVIRONMENT", (uint64_t)active_target.memory_environment, type_int);
|
||||
setup_bool_define("COMPILER_LIBC_AVAILABLE", !active_target.no_libc);
|
||||
setup_int_define("COMPILER_OPT_LEVEL", (uint64_t)active_target.optimization_level, type_int);
|
||||
|
||||
@@ -673,7 +673,7 @@ typedef struct Decl_
|
||||
bool obfuscate : 1;
|
||||
bool is_dynamic : 1;
|
||||
bool is_synthetic : 1;
|
||||
bool is_wasm_export : 1;
|
||||
bool is_wasm_interface : 1;
|
||||
OperatorOverload operator : 4;
|
||||
union
|
||||
{
|
||||
|
||||
@@ -407,6 +407,7 @@ static void linker_setup_linux(const char ***args_ref, LinkerType linker_type)
|
||||
add_arg("--dynamic-linker=/lib64/ld-linux-x86-64.so.2");
|
||||
add_arg("-lc");
|
||||
add_arg("-lm");
|
||||
add_arg("-lpthread");
|
||||
add_arg("-L/usr/lib/");
|
||||
add_arg("-L/lib/");
|
||||
add_arg("-m");
|
||||
@@ -636,10 +637,6 @@ static bool link_exe(const char *output_file, const char **files_to_link, unsign
|
||||
LinkerType linker_type = linker_find_linker_type();
|
||||
linker_setup(&args, files_to_link, file_count, output_file, linker_type);
|
||||
|
||||
VECEACH(active_target.link_args, i)
|
||||
{
|
||||
vec_add(args, active_target.link_args[i]);
|
||||
}
|
||||
const char *error = NULL;
|
||||
// This isn't used in most cases, but its contents should get freed after linking.
|
||||
|
||||
|
||||
@@ -947,6 +947,107 @@ LLVMValueRef llvm_get_opt_ref(GenContext *c, Decl *decl)
|
||||
return decl->var.optional_ref;
|
||||
}
|
||||
|
||||
static void llvm_emit_param_attributes(GenContext *c, LLVMValueRef function, ABIArgInfo *info, bool is_return, int index, int last_index)
|
||||
{
|
||||
assert(last_index == index || info->kind == ABI_ARG_DIRECT_PAIR || info->kind == ABI_ARG_IGNORE
|
||||
|| info->kind == ABI_ARG_EXPAND || info->kind == ABI_ARG_DIRECT || info->kind == ABI_ARG_DIRECT_COERCE
|
||||
|| info->kind == ABI_ARG_DIRECT_COERCE_INT
|
||||
|| info->kind == ABI_ARG_DIRECT_SPLIT_STRUCT);
|
||||
|
||||
if (info->attributes.zeroext)
|
||||
{
|
||||
// Direct only
|
||||
assert(index == last_index);
|
||||
llvm_attribute_add(c, function, attribute_id.zext, index);
|
||||
}
|
||||
if (info->attributes.signext)
|
||||
{
|
||||
// Direct only
|
||||
assert(index == last_index);
|
||||
llvm_attribute_add(c, function, attribute_id.sext, index);
|
||||
}
|
||||
if (info->attributes.by_reg)
|
||||
{
|
||||
llvm_attribute_add_range(c, function, attribute_id.inreg, index, last_index);
|
||||
}
|
||||
switch (info->kind)
|
||||
{
|
||||
case ABI_ARG_EXPAND:
|
||||
case ABI_ARG_IGNORE:
|
||||
case ABI_ARG_DIRECT_SPLIT_STRUCT:
|
||||
case ABI_ARG_DIRECT_COERCE:
|
||||
case ABI_ARG_DIRECT_COERCE_INT:
|
||||
case ABI_ARG_DIRECT_PAIR:
|
||||
case ABI_ARG_DIRECT:
|
||||
case ABI_ARG_EXPAND_COERCE:
|
||||
break;
|
||||
case ABI_ARG_INDIRECT:
|
||||
if (is_return)
|
||||
{
|
||||
assert(info->indirect.type);
|
||||
llvm_attribute_add_type(c, function, attribute_id.sret, llvm_get_type(c, info->indirect.type), 1);
|
||||
llvm_attribute_add(c, function, attribute_id.noalias, 1);
|
||||
llvm_attribute_add_int(c, function, attribute_id.align, info->indirect.alignment, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->attributes.by_val) llvm_attribute_add_type(c, function, attribute_id.byval, llvm_get_type(c, info->indirect.type), index);
|
||||
llvm_attribute_add_int(c, function, attribute_id.align, info->indirect.alignment, index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void llvm_append_function_attributes(GenContext *c, Decl *decl)
|
||||
{
|
||||
FunctionPrototype *prototype = decl->type->function.prototype;
|
||||
|
||||
LLVMValueRef function = decl->backend_ref;
|
||||
ABIArgInfo *ret_abi_info = prototype->ret_abi_info;
|
||||
llvm_emit_param_attributes(c, function, ret_abi_info, true, 0, 0);
|
||||
unsigned params = vec_size(prototype->param_types);
|
||||
if (prototype->ret_by_ref)
|
||||
{
|
||||
ABIArgInfo *info = prototype->ret_by_ref_abi_info;
|
||||
llvm_emit_param_attributes(c, function, prototype->ret_by_ref_abi_info, false, info->param_index_start + 1, info->param_index_end);
|
||||
}
|
||||
for (unsigned i = 0; i < params; i++)
|
||||
{
|
||||
ABIArgInfo *info = prototype->abi_args[i];
|
||||
llvm_emit_param_attributes(c, function, info, false, info->param_index_start + 1, info->param_index_end);
|
||||
}
|
||||
// We ignore decl->func_decl.attr_inline and place it in every call instead.
|
||||
if (decl->func_decl.attr_noinline)
|
||||
{
|
||||
llvm_attribute_add(c, function, attribute_id.noinline, -1);
|
||||
}
|
||||
if (decl->func_decl.signature.attrs.noreturn)
|
||||
{
|
||||
llvm_attribute_add(c, function, attribute_id.noreturn, -1);
|
||||
}
|
||||
if (decl->is_wasm_interface && arch_is_wasm(platform_target.arch))
|
||||
{
|
||||
if (decl->visibility == VISIBLE_EXTERN)
|
||||
{
|
||||
llvm_attribute_add_string(c, function, "wasm-import-name", decl_get_extname(decl), -1);
|
||||
}
|
||||
else if (c->code_module == decl->unit->module)
|
||||
{
|
||||
llvm_attribute_add_string(c, function, "wasm-export-name", decl_get_extname(decl), -1);
|
||||
}
|
||||
}
|
||||
if (decl->alignment != type_abi_alignment(decl->type))
|
||||
{
|
||||
llvm_set_alignment(function, decl->alignment);
|
||||
}
|
||||
llvm_attribute_add(c, function, attribute_id.nounwind, -1);
|
||||
if (decl->func_decl.attr_naked)
|
||||
{
|
||||
llvm_attribute_add(c, function, attribute_id.naked, -1);
|
||||
}
|
||||
LLVMSetFunctionCallConv(function, llvm_call_convention_from_call(prototype->call_abi));
|
||||
}
|
||||
LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl)
|
||||
{
|
||||
LLVMValueRef backend_ref = decl->backend_ref;
|
||||
@@ -966,6 +1067,7 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl)
|
||||
return decl->backend_ref;
|
||||
case DECL_FUNC:
|
||||
backend_ref = decl->backend_ref = LLVMAddFunction(c->module, decl_get_extname(decl), llvm_get_type(c, decl->type));
|
||||
llvm_append_function_attributes(c, decl);
|
||||
if (decl->unit->module == c->code_module && !decl->is_external_visible && !visible_external(decl->visibility))
|
||||
{
|
||||
llvm_set_internal_linkage(backend_ref);
|
||||
|
||||
@@ -582,58 +582,6 @@ void llvm_emit_body(GenContext *c, LLVMValueRef function, const char *module_nam
|
||||
c->function = prev_function;
|
||||
}
|
||||
|
||||
static void llvm_emit_param_attributes(GenContext *c, LLVMValueRef function, ABIArgInfo *info, bool is_return, int index, int last_index)
|
||||
{
|
||||
assert(last_index == index || info->kind == ABI_ARG_DIRECT_PAIR || info->kind == ABI_ARG_IGNORE
|
||||
|| info->kind == ABI_ARG_EXPAND || info->kind == ABI_ARG_DIRECT || info->kind == ABI_ARG_DIRECT_COERCE
|
||||
|| info->kind == ABI_ARG_DIRECT_COERCE_INT
|
||||
|| info->kind == ABI_ARG_DIRECT_SPLIT_STRUCT);
|
||||
|
||||
if (info->attributes.zeroext)
|
||||
{
|
||||
// Direct only
|
||||
assert(index == last_index);
|
||||
llvm_attribute_add(c, function, attribute_id.zext, index);
|
||||
}
|
||||
if (info->attributes.signext)
|
||||
{
|
||||
// Direct only
|
||||
assert(index == last_index);
|
||||
llvm_attribute_add(c, function, attribute_id.sext, index);
|
||||
}
|
||||
if (info->attributes.by_reg)
|
||||
{
|
||||
llvm_attribute_add_range(c, function, attribute_id.inreg, index, last_index);
|
||||
}
|
||||
switch (info->kind)
|
||||
{
|
||||
case ABI_ARG_EXPAND:
|
||||
case ABI_ARG_IGNORE:
|
||||
case ABI_ARG_DIRECT_SPLIT_STRUCT:
|
||||
case ABI_ARG_DIRECT_COERCE:
|
||||
case ABI_ARG_DIRECT_COERCE_INT:
|
||||
case ABI_ARG_DIRECT_PAIR:
|
||||
case ABI_ARG_DIRECT:
|
||||
case ABI_ARG_EXPAND_COERCE:
|
||||
break;
|
||||
case ABI_ARG_INDIRECT:
|
||||
if (is_return)
|
||||
{
|
||||
assert(info->indirect.type);
|
||||
llvm_attribute_add_type(c, function, attribute_id.sret, llvm_get_type(c, info->indirect.type), 1);
|
||||
llvm_attribute_add(c, function, attribute_id.noalias, 1);
|
||||
llvm_attribute_add_int(c, function, attribute_id.align, info->indirect.alignment, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->attributes.by_val) llvm_attribute_add_type(c, function, attribute_id.byval, llvm_get_type(c, info->indirect.type), index);
|
||||
llvm_attribute_add_int(c, function, attribute_id.align, info->indirect.alignment, index);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void llvm_emit_xxlizer(GenContext *c, Decl *decl)
|
||||
{
|
||||
@@ -690,48 +638,14 @@ void llvm_emit_function_decl(GenContext *c, Decl *decl)
|
||||
|
||||
LLVMValueRef function = llvm_get_ref(c, decl);
|
||||
decl->backend_ref = function;
|
||||
FunctionPrototype *prototype = decl->type->function.prototype;
|
||||
|
||||
ABIArgInfo *ret_abi_info = prototype->ret_abi_info;
|
||||
llvm_emit_param_attributes(c, function, ret_abi_info, true, 0, 0);
|
||||
unsigned params = vec_size(prototype->param_types);
|
||||
if (prototype->ret_by_ref)
|
||||
{
|
||||
ABIArgInfo *info = prototype->ret_by_ref_abi_info;
|
||||
llvm_emit_param_attributes(c, function, prototype->ret_by_ref_abi_info, false, info->param_index_start + 1, info->param_index_end);
|
||||
}
|
||||
for (unsigned i = 0; i < params; i++)
|
||||
{
|
||||
ABIArgInfo *info = prototype->abi_args[i];
|
||||
llvm_emit_param_attributes(c, function, info, false, info->param_index_start + 1, info->param_index_end);
|
||||
}
|
||||
// We ignore decl->func_decl.attr_inline and place it in every call instead.
|
||||
if (decl->func_decl.attr_noinline)
|
||||
{
|
||||
llvm_attribute_add(c, function, attribute_id.noinline, -1);
|
||||
}
|
||||
if (decl->func_decl.signature.attrs.noreturn)
|
||||
{
|
||||
llvm_attribute_add(c, function, attribute_id.noreturn, -1);
|
||||
}
|
||||
if (decl->is_wasm_export && arch_is_wasm(platform_target.arch))
|
||||
{
|
||||
llvm_attribute_add_string(c, function, "wasm-export-name", decl_get_extname(decl), -1);
|
||||
}
|
||||
if (decl->alignment != type_abi_alignment(decl->type))
|
||||
{
|
||||
llvm_set_alignment(function, decl->alignment);
|
||||
}
|
||||
if (decl->section)
|
||||
{
|
||||
LLVMSetSection(function, decl->section);
|
||||
}
|
||||
llvm_attribute_add(c, function, attribute_id.nounwind, -1);
|
||||
if (decl->func_decl.attr_naked)
|
||||
if (llvm_use_debug(c))
|
||||
{
|
||||
llvm_attribute_add(c, function, attribute_id.naked, -1);
|
||||
llvm_emit_debug_function(c, decl);
|
||||
}
|
||||
LLVMSetFunctionCallConv(function, llvm_call_convention_from_call(prototype->call_abi));
|
||||
|
||||
Visibility visibility = decl->visibility;
|
||||
if (decl->is_external_visible) visibility = VISIBLE_PUBLIC;
|
||||
@@ -748,7 +662,7 @@ void llvm_emit_function_decl(GenContext *c, Decl *decl)
|
||||
LLVMSetLinkage(function, LLVMExternalLinkage);
|
||||
}
|
||||
LLVMSetVisibility(function, LLVMDefaultVisibility);
|
||||
if (prototype->call_abi == CALL_X86_STD && platform_target.os == OS_TYPE_WIN32)
|
||||
if (decl->type->function.prototype->call_abi == CALL_X86_STD && platform_target.os == OS_TYPE_WIN32)
|
||||
{
|
||||
LLVMSetDLLStorageClass(function, LLVMDLLImportStorageClass);
|
||||
}
|
||||
@@ -762,10 +676,6 @@ void llvm_emit_function_decl(GenContext *c, Decl *decl)
|
||||
LLVMSetVisibility(function, LLVMDefaultVisibility);
|
||||
break;;
|
||||
}
|
||||
if (llvm_use_debug(c))
|
||||
{
|
||||
llvm_emit_debug_function(c, decl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1646,7 +1646,7 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr,
|
||||
decl->is_weak = true;
|
||||
break;
|
||||
case ATTRIBUTE_WASM:
|
||||
decl->is_wasm_export = true;
|
||||
decl->is_wasm_interface = true;
|
||||
break;
|
||||
case ATTRIBUTE_NAKED:
|
||||
assert(domain == ATTR_FUNC);
|
||||
|
||||
@@ -6537,7 +6537,7 @@ static inline bool sema_expr_analyse_lambda(SemaContext *context, Type *func_typ
|
||||
if (!decl_ok(decl)) return false;
|
||||
if (decl->resolve_status == RESOLVE_DONE)
|
||||
{
|
||||
expr->type = expr->type = type_get_ptr(decl->type);
|
||||
expr->type = type_get_ptr(decl->type);
|
||||
return true;
|
||||
}
|
||||
bool in_macro = context->current_macro;
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.4.26"
|
||||
#define COMPILER_VERSION "0.4.27"
|
||||
@@ -74,9 +74,9 @@ if.exit: ; preds = %if.then, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_init"(%HashMap*, i32, float, %Allocator*)
|
||||
declare void @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_init"(%HashMap*, i32, float, %Allocator*) #0
|
||||
|
||||
declare i8 @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_set"(%HashMap*, i64, { i8*, i64 } (i8*, %Allocator*)*)
|
||||
declare zeroext i8 @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_set"(%HashMap*, i64, { i8*, i64 } (i8*, %Allocator*)*) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define { i8*, i64 } @test_Foo_to_string(%Foo* %0, %Allocator* %1) #0 {
|
||||
@@ -574,14 +574,14 @@ declare void @"std_map$$int.test_Foo_HashMap_tinit"(%HashMap.0*, i32, float)
|
||||
|
||||
declare i64 @std_io_printfn(i64*, i8*, i64, i8*, i64)
|
||||
|
||||
declare i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap.0*, i32, i64, i8*)
|
||||
declare zeroext i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap.0*, i32, i64, i8*)
|
||||
|
||||
declare i64 @"std_map$$int.test_Foo_HashMap_get"(%Foo*, %HashMap.0*, i32)
|
||||
|
||||
declare i8 @"std_map$$int.test_Foo_HashMap_has_key"(%HashMap.0*, i32)
|
||||
declare zeroext i8 @"std_map$$int.test_Foo_HashMap_has_key"(%HashMap.0*, i32)
|
||||
|
||||
declare { i8*, i64 } @"std_map$$int.test_Foo_HashMap_value_list"(%HashMap.0*, %Allocator*)
|
||||
|
||||
declare void @"std_map$$int.double_HashMap_tinit"(%HashMap.3*, i32, float)
|
||||
|
||||
declare i8 @"std_map$$int.double_HashMap_set"(%HashMap.3*, i32, double)
|
||||
declare zeroext i8 @"std_map$$int.double_HashMap_set"(%HashMap.3*, i32, double)
|
||||
Reference in New Issue
Block a user