mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Updated mangling code.
This commit is contained in:
@@ -483,3 +483,41 @@ bool ast_supports_continue(Ast *stmt)
|
||||
if (stmt->ast_kind != AST_FOR_STMT) return false;
|
||||
return stmt->for_stmt.cond || !stmt->flow.skip_first;
|
||||
}
|
||||
|
||||
void scratch_buffer_set_extern_decl_name(Decl *decl, bool clear)
|
||||
{
|
||||
if (clear) scratch_buffer_clear();
|
||||
if (decl->extname)
|
||||
{
|
||||
scratch_buffer_append(decl->extname);
|
||||
return;
|
||||
}
|
||||
if (decl->is_extern)
|
||||
{
|
||||
scratch_buffer_append(decl->name);
|
||||
return;
|
||||
}
|
||||
if (decl->decl_kind == DECL_FUNC && decl->func_decl.type_parent)
|
||||
{
|
||||
Type *parent = type_infoptr(decl->func_decl.type_parent)->type->canonical;
|
||||
if (type_is_user_defined(parent))
|
||||
{
|
||||
Decl *parent_decl = parent->decl;
|
||||
if (parent_decl->unit && parent_decl->unit->module) scratch_buffer_append_module(parent_decl->unit->module, decl->is_export);
|
||||
scratch_buffer_append(decl->is_export ? "__" : ".");
|
||||
scratch_buffer_append(parent->name);
|
||||
scratch_buffer_append(decl->is_export ? "__" : ".");
|
||||
scratch_buffer_append(decl->name);
|
||||
return;
|
||||
}
|
||||
if (decl->unit && decl->unit->module) scratch_buffer_append_module(decl->unit->module, decl->is_export);
|
||||
scratch_buffer_append(decl->is_export ? "__" : ".");
|
||||
scratch_buffer_append(parent->name);
|
||||
scratch_buffer_append(decl->is_export ? "__" : ".");
|
||||
scratch_buffer_append(decl->name);
|
||||
return;
|
||||
}
|
||||
if (decl->unit && decl->unit->module) scratch_buffer_append_module(decl->unit->module, decl->is_export);
|
||||
scratch_buffer_append(decl->is_export ? "__" : ".");
|
||||
scratch_buffer_append(decl->name);
|
||||
}
|
||||
|
||||
@@ -2230,6 +2230,7 @@ bool decl_needs_prefix(Decl *decl);
|
||||
AlignSize decl_find_member_offset(Decl *decl, Decl *member);
|
||||
bool decl_is_externally_visible(Decl *decl);
|
||||
bool decl_is_local(Decl *decl);
|
||||
void scratch_buffer_set_extern_decl_name(Decl *decl, bool clear);
|
||||
|
||||
// --- Expression functions
|
||||
|
||||
@@ -2300,7 +2301,7 @@ bool lexer_next_token(Lexer *lexer);
|
||||
|
||||
// --- Module functions
|
||||
|
||||
void module_copy_extern_name_to_buffer(Module *module);
|
||||
void scratch_buffer_append_module(Module *module, bool is_export);
|
||||
Decl *module_find_symbol(Module *module, const char *symbol);
|
||||
const char *module_create_object_file_name(Module *module);
|
||||
|
||||
@@ -3572,10 +3573,6 @@ INLINE Ast *ast_next(AstId *current_ptr)
|
||||
}
|
||||
|
||||
|
||||
INLINE const char *decl_get_extname(Decl *decl)
|
||||
{
|
||||
return decl->extname;
|
||||
}
|
||||
|
||||
|
||||
INLINE void expr_rewrite_const_bool(Expr *expr, Type *type, bool b)
|
||||
|
||||
@@ -108,7 +108,7 @@ bool context_set_module(ParseContext *context, Path *path, const char **generic_
|
||||
|
||||
void unit_register_external_symbol(CompilationUnit *unit, Decl *decl)
|
||||
{
|
||||
if (decl_module(decl) == unit->module || !decl->extname) return;
|
||||
if (decl_module(decl) == unit->module) return;
|
||||
decl->is_external_visible = true;
|
||||
}
|
||||
|
||||
@@ -174,7 +174,6 @@ void unit_register_global_decl(CompilationUnit *unit, Decl *decl)
|
||||
{
|
||||
vec_add(unit->macros, decl);
|
||||
}
|
||||
decl_set_external_name(decl);
|
||||
decl_register(decl);
|
||||
break;
|
||||
case DECL_FUNC:
|
||||
@@ -193,7 +192,6 @@ void unit_register_global_decl(CompilationUnit *unit, Decl *decl)
|
||||
case DECL_VAR:
|
||||
assert(decl->name);
|
||||
vec_add(unit->vars, decl);
|
||||
decl_set_external_name(decl);
|
||||
decl_register(decl);
|
||||
break;
|
||||
case DECL_INTERFACE:
|
||||
@@ -205,19 +203,16 @@ void unit_register_global_decl(CompilationUnit *unit, Decl *decl)
|
||||
case DECL_BITSTRUCT:
|
||||
assert(decl->name);
|
||||
vec_add(unit->types, decl);
|
||||
decl_set_external_name(decl);
|
||||
decl_register(decl);
|
||||
break;
|
||||
case DECL_DEFINE:
|
||||
assert(decl->name);
|
||||
vec_add(unit->generic_defines, decl);
|
||||
decl_set_external_name(decl);
|
||||
decl_register(decl);
|
||||
break;
|
||||
case DECL_ENUM:
|
||||
assert(decl->name);
|
||||
vec_add(unit->enums, decl);
|
||||
decl_set_external_name(decl);
|
||||
decl_register(decl);
|
||||
break;
|
||||
case DECL_ATTRIBUTE:
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
static void header_gen_struct_union(FILE *file, int indent, Decl *decl);
|
||||
static void header_gen_maybe_generate_type(FILE *file, HTable *table, Type *type);
|
||||
|
||||
INLINE const char *decl_get_extname(Decl *decl)
|
||||
{
|
||||
return decl->extname;
|
||||
}
|
||||
|
||||
static bool type_is_func_pointer(Type *type)
|
||||
{
|
||||
if (type->type_kind != TYPE_DISTINCT && type->type_kind != TYPE_TYPEDEF) return false;
|
||||
|
||||
@@ -518,10 +518,29 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl)
|
||||
|
||||
|
||||
LLVMValueRef old = decl->backend_ref;
|
||||
LLVMValueRef global_ref = decl->backend_ref = llvm_add_global_raw(c,
|
||||
decl_get_extname(decl),
|
||||
LLVMTypeOf(init_value),
|
||||
decl->alignment);
|
||||
scratch_buffer_set_extern_decl_name(decl, true);
|
||||
char *name = scratch_buffer_copy();
|
||||
LLVMValueRef global_ref = decl->backend_ref = llvm_add_global_raw(c, name, LLVMTypeOf(init_value), decl->alignment);
|
||||
if (llvm_use_debug(c))
|
||||
{
|
||||
SourceSpan loc = decl->span;
|
||||
decl->var.backend_debug_ref = LLVMDIBuilderCreateGlobalVariableExpression(
|
||||
c->debug.builder,
|
||||
c->debug.file.debug_file,
|
||||
decl->name,
|
||||
strlen(decl->name),
|
||||
name,
|
||||
strlen(name),
|
||||
c->debug.file.debug_file,
|
||||
loc.row ? loc.row : 1,
|
||||
llvm_get_debug_type(c, decl->type),
|
||||
decl_is_local(decl),
|
||||
LLVMDIBuilderCreateExpression(c->debug.builder, NULL, 0),
|
||||
NULL,
|
||||
decl->alignment);
|
||||
LLVMGlobalSetMetadata(llvm_get_ref(c, decl), 0, decl->var.backend_debug_ref);
|
||||
}
|
||||
|
||||
if (decl->var.is_addr)
|
||||
{
|
||||
LLVMSetUnnamedAddress(global_ref, LLVMNoUnnamedAddr);
|
||||
@@ -586,11 +605,6 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl)
|
||||
LLVMDeleteGlobal(old);
|
||||
}
|
||||
|
||||
// Should we set linkage here?
|
||||
if (llvm_use_debug(c))
|
||||
{
|
||||
llvm_emit_debug_global_var(c, decl);
|
||||
}
|
||||
}
|
||||
static void gencontext_verify_ir(GenContext *context)
|
||||
{
|
||||
@@ -1012,13 +1026,23 @@ const char *llvm_codegen(void *context)
|
||||
return object_name;
|
||||
}
|
||||
|
||||
|
||||
void llvm_add_global_decl(GenContext *c, Decl *decl)
|
||||
{
|
||||
assert(decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST);
|
||||
|
||||
bool same_module = decl_module(decl) == c->code_module;
|
||||
const char *name = same_module ? "temp_global" : decl_get_extname(decl);
|
||||
decl->backend_ref = llvm_add_global(c, name, decl->type, decl->alignment);
|
||||
LLVMTypeRef type = llvm_get_type(c, decl->type);
|
||||
if (same_module)
|
||||
{
|
||||
// If we initialize it later, we must use a temp name.
|
||||
decl->backend_ref = llvm_add_global_raw(c, ".tempglobal", type, decl->alignment);
|
||||
}
|
||||
else
|
||||
{
|
||||
scratch_buffer_set_extern_decl_name(decl, true);
|
||||
decl->backend_ref = llvm_add_global_raw(c, scratch_buffer_to_string(), type, decl->alignment);
|
||||
}
|
||||
if (!same_module)
|
||||
{
|
||||
LLVMSetLinkage(decl->backend_ref, LLVMExternalLinkage);
|
||||
@@ -1029,10 +1053,10 @@ void llvm_add_global_decl(GenContext *c, Decl *decl)
|
||||
}
|
||||
if (IS_OPTIONAL(decl))
|
||||
{
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_append(decl_get_extname(decl));
|
||||
LLVMTypeRef anyfault = llvm_get_type(c, type_anyfault);
|
||||
scratch_buffer_set_extern_decl_name(decl, true);
|
||||
scratch_buffer_append(".f");
|
||||
decl->var.optional_ref = llvm_add_global(c, scratch_buffer_to_string(), type_anyfault, 0);
|
||||
decl->var.optional_ref = llvm_add_global_raw(c, scratch_buffer_to_string(), anyfault, 0);
|
||||
}
|
||||
llvm_set_global_tls(decl);
|
||||
}
|
||||
@@ -1136,12 +1160,14 @@ void llvm_append_function_attributes(GenContext *c, Decl *decl)
|
||||
{
|
||||
if (c->code_module == decl_module(decl))
|
||||
{
|
||||
llvm_attribute_add_string(c, function, "wasm-export-name", decl_get_extname(decl), -1);
|
||||
scratch_buffer_set_extern_decl_name(decl, true);
|
||||
llvm_attribute_add_string(c, function, "wasm-export-name", scratch_buffer_to_string(), -1);
|
||||
}
|
||||
}
|
||||
if (decl->is_extern && arch_is_wasm(platform_target.arch))
|
||||
{
|
||||
llvm_attribute_add_string(c, function, "wasm-import-name", decl_get_extname(decl), -1);
|
||||
scratch_buffer_set_extern_decl_name(decl, true);
|
||||
llvm_attribute_add_string(c, function, "wasm-import-name", scratch_buffer_to_string(), -1);
|
||||
}
|
||||
if (decl->alignment != type_abi_alignment(decl->type))
|
||||
{
|
||||
@@ -1186,7 +1212,9 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl)
|
||||
{
|
||||
return decl->backend_ref = llvm_get_selector(c, decl->name);
|
||||
}
|
||||
backend_ref = decl->backend_ref = LLVMAddFunction(c->module, decl_get_extname(decl), llvm_get_type(c, decl->type));
|
||||
LLVMTypeRef type = llvm_get_type(c, decl->type);
|
||||
scratch_buffer_set_extern_decl_name(decl, true);
|
||||
backend_ref = decl->backend_ref = LLVMAddFunction(c->module, scratch_buffer_to_string(), type);
|
||||
llvm_append_function_attributes(c, decl);
|
||||
if (decl->is_export && platform_target.os == OS_TYPE_WIN32 && !active_target.win.def && decl->name != kw_main && decl->name != kw_mainstub)
|
||||
{
|
||||
@@ -1246,7 +1274,8 @@ static void llvm_gen_test_main(GenContext *c)
|
||||
LLVMTypeRef main_type = LLVMFunctionType(cint, NULL, 0, true);
|
||||
LLVMTypeRef runner_type = LLVMFunctionType(c->byte_type, NULL, 0, true);
|
||||
LLVMValueRef func = LLVMAddFunction(c->module, kw_main, main_type);
|
||||
LLVMValueRef other_func = LLVMAddFunction(c->module, test_runner->extname, runner_type);
|
||||
scratch_buffer_set_extern_decl_name(test_runner, true);
|
||||
LLVMValueRef other_func = LLVMAddFunction(c->module, scratch_buffer_to_string(), runner_type);
|
||||
LLVMBuilderRef builder = llvm_create_function_entry(c, func, NULL);
|
||||
LLVMValueRef val = LLVMBuildCall2(builder, runner_type, other_func, NULL, 0, "");
|
||||
val = LLVMBuildSelect(builder, LLVMBuildTrunc(builder, val, c->bool_type, ""),
|
||||
@@ -1275,7 +1304,8 @@ INLINE GenContext *llvm_gen_tests(Module** modules, unsigned module_count, LLVMC
|
||||
FOREACH_BEGIN(Decl *test, module->tests)
|
||||
LLVMValueRef ref;
|
||||
LLVMTypeRef type = opt_test;
|
||||
ref = LLVMAddFunction(c->module, test->extname, type);
|
||||
scratch_buffer_set_extern_decl_name(test, true);
|
||||
ref = LLVMAddFunction(c->module, scratch_buffer_to_string(), type);
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_printf("%s::%s", module->name->module, test->name);
|
||||
LLVMValueRef name = llvm_emit_string_const(c, scratch_buffer_to_string(), ".test.name");
|
||||
@@ -1342,7 +1372,8 @@ static void llvm_gen_benchmark_main(GenContext *c)
|
||||
LLVMTypeRef main_type = LLVMFunctionType(cint, NULL, 0, true);
|
||||
LLVMTypeRef runner_type = LLVMFunctionType(c->byte_type, NULL, 0, true);
|
||||
LLVMValueRef func = LLVMAddFunction(c->module, kw_main, main_type);
|
||||
LLVMValueRef other_func = LLVMAddFunction(c->module, benchmark_runner->extname, runner_type);
|
||||
scratch_buffer_set_extern_decl_name(benchmark_runner, true);
|
||||
LLVMValueRef other_func = LLVMAddFunction(c->module, scratch_buffer_to_string(), runner_type);
|
||||
LLVMBuilderRef builder = llvm_create_function_entry(c, func, NULL);
|
||||
LLVMValueRef val = LLVMBuildCall2(builder, runner_type, other_func, NULL, 0, "");
|
||||
val = LLVMBuildSelect(builder, LLVMBuildTrunc(builder, val, c->bool_type, ""),
|
||||
@@ -1371,7 +1402,8 @@ INLINE GenContext *llvm_gen_benchmarks(Module** modules, unsigned module_count,
|
||||
FOREACH_BEGIN(Decl *benchmark, module->benchmarks)
|
||||
LLVMValueRef ref;
|
||||
LLVMTypeRef type = opt_benchmark;
|
||||
ref = LLVMAddFunction(c->module, benchmark->extname, type);
|
||||
scratch_buffer_set_extern_decl_name(benchmark, true);
|
||||
ref = LLVMAddFunction(c->module, scratch_buffer_to_string(), type);
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_printf("%s::%s", module->name->module, benchmark->name);
|
||||
LLVMValueRef name = llvm_emit_string_const(c, scratch_buffer_to_string(), ".benchmark.name");
|
||||
|
||||
@@ -40,7 +40,7 @@ static inline LLVMMetadataRef llvm_get_debug_struct(GenContext *c, Type *type, c
|
||||
}
|
||||
LLVMMetadataRef real = LLVMDIBuilderCreateStructType(c->debug.builder,
|
||||
scope,
|
||||
external_name_len ? type->name : "", external_name_len ? strlen(type->name) : 0,
|
||||
type->name ? type->name : "", type->name ? strlen(type->name) : 0,
|
||||
file,
|
||||
row,
|
||||
type_size(type) * 8,
|
||||
@@ -80,26 +80,6 @@ LLVMMetadataRef llvm_debug_current_scope(GenContext *context)
|
||||
return context->debug.compile_unit;
|
||||
}
|
||||
|
||||
void llvm_emit_debug_global_var(GenContext *c, Decl *global)
|
||||
{
|
||||
SourceSpan loc = global->span;
|
||||
global->var.backend_debug_ref = LLVMDIBuilderCreateGlobalVariableExpression(
|
||||
c->debug.builder,
|
||||
c->debug.file.debug_file,
|
||||
global->name,
|
||||
strlen(global->name),
|
||||
global->extname,
|
||||
strlen(global->extname),
|
||||
c->debug.file.debug_file,
|
||||
loc.row ? loc.row : 1,
|
||||
llvm_get_debug_type(c, global->type),
|
||||
decl_is_local(global),
|
||||
LLVMDIBuilderCreateExpression(c->debug.builder, NULL, 0),
|
||||
NULL,
|
||||
global->alignment);
|
||||
LLVMGlobalSetMetadata(llvm_get_ref(c, global), 0, global->var.backend_debug_ref);
|
||||
}
|
||||
|
||||
void llvm_emit_debug_function(GenContext *c, Decl *decl)
|
||||
{
|
||||
if (!decl->func_decl.body) return;
|
||||
@@ -110,13 +90,13 @@ void llvm_emit_debug_function(GenContext *c, Decl *decl)
|
||||
uint32_t row = decl->span.row;
|
||||
if (!row) row = 1;
|
||||
assert(decl->name);
|
||||
assert(decl->extname);
|
||||
assert(c->debug.file.debug_file);
|
||||
LLVMMetadataRef debug_type = llvm_get_debug_type(c, decl->type);
|
||||
scratch_buffer_set_extern_decl_name(decl, true);
|
||||
c->debug.function = LLVMDIBuilderCreateFunction(c->debug.builder,
|
||||
c->debug.file.debug_file,
|
||||
decl->name, strlen(decl->name),
|
||||
decl->extname, strlen(decl->extname),
|
||||
scratch_buffer_to_string(), scratch_buffer.len,
|
||||
c->debug.file.debug_file,
|
||||
row,
|
||||
debug_type,
|
||||
@@ -264,8 +244,8 @@ static LLVMMetadataRef llvm_debug_forward_comp(GenContext *c, Type *type, const
|
||||
type_size(type) * 8,
|
||||
type_abi_alignment(type) * 8,
|
||||
flags,
|
||||
external_name,
|
||||
strlen(external_name));
|
||||
"temp",
|
||||
4);
|
||||
|
||||
}
|
||||
|
||||
@@ -348,7 +328,7 @@ static LLVMMetadataRef llvm_debug_enum_type(GenContext *c, Type *type, LLVMMetad
|
||||
{
|
||||
Decl *decl = type->decl;
|
||||
|
||||
LLVMMetadataRef forward = llvm_debug_forward_comp(c, type, decl->extname, &decl->span, scope, LLVMDIFlagZero);
|
||||
LLVMMetadataRef forward = llvm_debug_forward_comp(c, type, "temp_enum", &decl->span, scope, LLVMDIFlagZero);
|
||||
type->backend_debug_type = forward;
|
||||
|
||||
Type *enum_real_type = decl->enums.type_info->type->canonical;
|
||||
@@ -389,7 +369,7 @@ static LLVMMetadataRef llvm_debug_structlike_type(GenContext *c, Type *type, LLV
|
||||
LLVMDIFlags flags = 0;
|
||||
|
||||
// Create a forward reference in case of recursive data.
|
||||
LLVMMetadataRef forward = llvm_debug_forward_comp(c, type, decl->extname, &decl->span, scope, flags);
|
||||
LLVMMetadataRef forward = llvm_debug_forward_comp(c, type, "temp", &decl->span, scope, flags);
|
||||
type->backend_debug_type = forward;
|
||||
|
||||
LLVMMetadataRef *elements = NULL;
|
||||
@@ -408,24 +388,33 @@ static LLVMMetadataRef llvm_debug_structlike_type(GenContext *c, Type *type, LLV
|
||||
}
|
||||
|
||||
LLVMMetadataRef real;
|
||||
|
||||
const char *extname = "";
|
||||
unsigned extname_len = 0;
|
||||
if (decl->name)
|
||||
{
|
||||
scratch_buffer_set_extern_decl_name(decl, true);
|
||||
extname = scratch_buffer_to_string();
|
||||
extname_len = scratch_buffer.len;
|
||||
}
|
||||
if (type->type_kind == TYPE_UNION)
|
||||
{
|
||||
unsigned row = decl->span.row;
|
||||
real = LLVMDIBuilderCreateUnionType(c->debug.builder,
|
||||
scope,
|
||||
type->decl->name ? type->decl->name : "",
|
||||
type->decl->name ? strlen(type->decl->name) : 0,
|
||||
decl->name ? decl->name : "",
|
||||
decl->name ? strlen(decl->name) : 0,
|
||||
c->debug.file.debug_file, row ? row : 1, type_size(type) * 8,
|
||||
type_abi_alignment(type) * 8,
|
||||
LLVMDIFlagZero,
|
||||
elements, vec_size(members),
|
||||
c->debug.runtime_version,
|
||||
type->decl->name ? decl->extname : "",
|
||||
type->decl->name ? strlen(decl->extname) : 0);
|
||||
extname,
|
||||
extname_len);
|
||||
LLVMMetadataReplaceAllUsesWith(forward, real);
|
||||
return real;
|
||||
}
|
||||
return llvm_get_debug_struct(c, type, decl->name ? decl->extname : "", elements, vec_size(elements), &decl->span, scope, LLVMDIFlagZero);
|
||||
return llvm_get_debug_struct(c, type, extname, elements, vec_size(elements), &decl->span, scope, LLVMDIFlagZero);
|
||||
}
|
||||
|
||||
static LLVMMetadataRef llvm_debug_slice_type(GenContext *c, Type *type)
|
||||
|
||||
@@ -404,7 +404,7 @@ void llvm_emit_return_implicit(GenContext *c)
|
||||
|
||||
void llvm_emit_function_body(GenContext *c, Decl *decl)
|
||||
{
|
||||
DEBUG_LOG("Generating function %s.", decl->extname);
|
||||
DEBUG_LOG("Generating function %s.", decl->name);
|
||||
if (decl->func_decl.attr_dynamic) vec_add(c->dynamic_functions, decl);
|
||||
assert(decl->backend_ref);
|
||||
if (decl->func_decl.attr_init || decl->func_decl.attr_finalizer)
|
||||
@@ -577,8 +577,8 @@ void llvm_emit_dynamic_functions(GenContext *c, Decl **funcs)
|
||||
Type *type = typeget(decl->func_decl.type_parent);
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_append("$ct.dyn.");
|
||||
scratch_buffer_append(decl_get_extname(decl));
|
||||
LLVMValueRef global = llvm_add_global_raw(c, scratch_buffer_to_string(), c->dtable_type, 0);
|
||||
scratch_buffer_set_extern_decl_name(decl, false);
|
||||
LLVMValueRef global = llvm_add_global_raw(c, scratch_buffer_copy(), c->dtable_type, 0);
|
||||
Decl *proto = declptrzero(decl->func_decl.interface_method);
|
||||
LLVMValueRef proto_ref = proto ? llvm_get_ref(c, proto) : llvm_get_selector(c, decl->name);
|
||||
LLVMValueRef vals[3] = { llvm_get_ref(c, decl), proto_ref, LLVMConstNull(c->ptr_type) };
|
||||
|
||||
@@ -560,7 +560,6 @@ void llvm_emit_debug_location(GenContext *c, SourceSpan location);
|
||||
LLVMMetadataRef llvm_create_debug_location(GenContext *c, SourceSpan location);
|
||||
void llvm_emit_debug_parameter(GenContext *c, Decl *parameter, unsigned index);
|
||||
void llvm_emit_debug_local_var(GenContext *c, Decl *var);
|
||||
void llvm_emit_debug_global_var(GenContext *c, Decl *global);
|
||||
|
||||
#define FRAMEPOINTER (platform_target.arch == ARCH_TYPE_AARCH64 ? 1 : 2)
|
||||
#define UWTABLE (active_target.arch_os_target == MACOS_AARCH64 ? 1 : 2)
|
||||
|
||||
@@ -43,13 +43,15 @@ void llvm_emit_local_static(GenContext *c, Decl *decl, BEValue *value)
|
||||
c->builder = c->global_builder;
|
||||
|
||||
// Emit the global.
|
||||
decl->backend_ref = llvm_add_global(c, "temp", type_lowering(decl->type), decl->alignment);
|
||||
decl->backend_ref = llvm_add_global(c, "temp", decl->type, decl->alignment);
|
||||
if (IS_OPTIONAL(decl))
|
||||
{
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_append(decl_get_extname(decl));
|
||||
LLVMTypeRef anyfault = llvm_get_type(c, type_anyfault);
|
||||
scratch_buffer_append(c->cur_func.name);
|
||||
scratch_buffer_append_char('.');
|
||||
scratch_buffer_append(decl->name);
|
||||
scratch_buffer_append(".f");
|
||||
decl->var.optional_ref = llvm_add_global(c, scratch_buffer_to_string(), type_anyfault, 0);
|
||||
decl->var.optional_ref = llvm_add_global_raw(c, scratch_buffer_to_string(), anyfault, 0);
|
||||
}
|
||||
llvm_emit_global_variable_init(c, decl);
|
||||
|
||||
|
||||
@@ -555,8 +555,7 @@ static LLVMValueRef llvm_get_introspection_for_enum(GenContext *c, Type *type)
|
||||
Decl *associated_value = associated_values[ai];
|
||||
LLVMValueRef associated_value_arr = mixed ? llvm_get_packed_struct(c, values, elements)
|
||||
: llvm_get_array(val_type, values, elements);
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_append(decl->extname);
|
||||
scratch_buffer_set_extern_decl_name(decl, true);
|
||||
scratch_buffer_append("$");
|
||||
scratch_buffer_append(associated_value->name);
|
||||
LLVMValueRef global_ref = llvm_add_global_raw(c,
|
||||
@@ -598,8 +597,7 @@ static LLVMValueRef llvm_get_introspection_for_fault(GenContext *c, Type *type)
|
||||
LLVMValueRef ref = llvm_generate_temp_introspection_global(c, type);
|
||||
for (unsigned i = 0; i < elements; i++)
|
||||
{
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_append(decl_get_extname(decl));
|
||||
scratch_buffer_set_extern_decl_name(decl, true);
|
||||
scratch_buffer_append_char('$');
|
||||
Decl *val = fault_vals[i];
|
||||
scratch_buffer_append(val->name);
|
||||
|
||||
@@ -9,7 +9,7 @@ Decl *module_find_symbol(Module *module, const char *symbol)
|
||||
return htable_get(&module->symbols, (void*)symbol);
|
||||
}
|
||||
|
||||
void module_copy_extern_name_to_buffer(Module *module)
|
||||
void scratch_buffer_append_module(Module *module, bool is_export)
|
||||
{
|
||||
if (module->extname)
|
||||
{
|
||||
@@ -24,7 +24,7 @@ void module_copy_extern_name_to_buffer(Module *module)
|
||||
{
|
||||
case ':':
|
||||
assert(name[0] == ':');
|
||||
scratch_buffer_append_char('_');
|
||||
scratch_buffer_append_char(is_export ? '_' : '.');
|
||||
name++;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -846,13 +846,6 @@ static bool sema_analyse_interface(SemaContext *context, Decl *decl, bool *erase
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!method->extname)
|
||||
{
|
||||
scratch_buffer_clear();
|
||||
type_mangle_introspect_name_to_buffer(decl->type);
|
||||
scratch_buffer_printf(".%s", name);
|
||||
method->extname = scratch_buffer_copy();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1231,7 +1224,6 @@ static inline bool sema_analyse_typedef(SemaContext *context, Decl *decl, bool *
|
||||
if (*erase_decl) return true;
|
||||
|
||||
bool is_export = decl->is_export;
|
||||
if (is_export) decl_set_external_name(decl);
|
||||
if (decl->typedef_decl.is_func)
|
||||
{
|
||||
Decl *fn_decl = decl->typedef_decl.decl;
|
||||
@@ -1610,39 +1602,6 @@ static bool sema_check_operator_method_validity(SemaContext *context, Decl *meth
|
||||
UNREACHABLE
|
||||
}
|
||||
|
||||
INLINE void sema_set_method_ext_name(CompilationUnit *unit, const char *parent_name, Decl *method_like)
|
||||
{
|
||||
if (method_like->has_extname) return;
|
||||
scratch_buffer_clear();
|
||||
if (method_like->is_export)
|
||||
{
|
||||
scratch_buffer_append(parent_name);
|
||||
scratch_buffer_append("_");
|
||||
scratch_buffer_append(method_like->name);
|
||||
method_like->extname = scratch_buffer_copy();
|
||||
return;
|
||||
}
|
||||
switch (method_like->visibility)
|
||||
{
|
||||
case VISIBLE_PUBLIC:
|
||||
case VISIBLE_PRIVATE:
|
||||
scratch_buffer_append(parent_name);
|
||||
scratch_buffer_append_char('.');
|
||||
scratch_buffer_append(method_like->name);
|
||||
break;
|
||||
case VISIBLE_LOCAL:
|
||||
scratch_buffer_append(unit->file->name);
|
||||
scratch_buffer_append_char('.');
|
||||
scratch_buffer_append(parent_name);
|
||||
scratch_buffer_append_char('.');
|
||||
scratch_buffer_append(method_like->name);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE
|
||||
}
|
||||
method_like->extname = scratch_buffer_copy();
|
||||
}
|
||||
|
||||
bool sema_decl_if_cond(SemaContext *context, Decl *decl)
|
||||
{
|
||||
Attr *attr = attr_find_kind(decl->attributes, ATTRIBUTE_IF);
|
||||
@@ -1686,9 +1645,6 @@ unit_add_base_extension_method(SemaContext *context, CompilationUnit *unit, Type
|
||||
"Only user-defined types support operator oveloading.");
|
||||
}
|
||||
|
||||
// As with normal methods, update the name.
|
||||
sema_set_method_ext_name(unit, parent_type->name, method);
|
||||
|
||||
// Add it to the right list of extensions.
|
||||
switch (method->visibility)
|
||||
{
|
||||
@@ -1890,8 +1846,6 @@ static inline bool unit_add_method(SemaContext *context, Type *parent_type, Decl
|
||||
if (!sema_analyse_operator_method(context, parent_type, method)) return false;
|
||||
}
|
||||
|
||||
// Set the external name
|
||||
sema_set_method_ext_name(unit, parent->extname, method);
|
||||
DEBUG_LOG("Method-like '%s.%s' analysed.", parent->name, method->name);
|
||||
|
||||
// Add it to the correct place: type methods, private extensions, local method extensions
|
||||
@@ -3145,7 +3099,6 @@ static inline bool sema_analyse_func(SemaContext *context, Decl *decl, bool *era
|
||||
}
|
||||
if (!sema_analyse_main_function(context, decl)) return false;
|
||||
}
|
||||
decl_set_external_name(decl);
|
||||
}
|
||||
|
||||
// Do we have fn void any.foo(void*) { ... }?
|
||||
@@ -3464,6 +3417,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
|
||||
case VARDECL_GLOBAL:
|
||||
is_global = true;
|
||||
break;
|
||||
case VARDECL_CONST:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -3499,14 +3453,6 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
|
||||
bool is_static = decl->var.is_static;
|
||||
bool global_level_var = is_static || decl->var.kind == VARDECL_CONST || is_global;
|
||||
|
||||
if (global_level_var && !decl->has_extname)
|
||||
{
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_append(context->call_env.kind == CALL_ENV_FUNCTION ? context->call_env.current_function->name : ".global");
|
||||
scratch_buffer_append_char('.');
|
||||
scratch_buffer_append(decl->name);
|
||||
decl->extname = scratch_buffer_copy();
|
||||
}
|
||||
if (decl->is_extern && decl->var.init_expr)
|
||||
{
|
||||
assert(is_global);
|
||||
@@ -3650,6 +3596,15 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
|
||||
}
|
||||
}
|
||||
EXIT_OK:;
|
||||
// Patch the external name for local consts and static variables.
|
||||
if ((decl->var.kind == VARDECL_CONST || is_static) && !decl->extname && context->call_env.kind == CALL_ENV_FUNCTION)
|
||||
{
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_append(context->call_env.current_function->name);
|
||||
scratch_buffer_append_char('.');
|
||||
scratch_buffer_append(decl->name);
|
||||
decl->extname = scratch_buffer_copy();
|
||||
}
|
||||
if (!decl->alignment)
|
||||
{
|
||||
if (!sema_set_alloca_alignment(context, decl->type, &decl->alignment)) return false;
|
||||
@@ -4109,23 +4064,19 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl)
|
||||
decl->resolve_status = RESOLVE_RUNNING;
|
||||
assert(decl->unit);
|
||||
bool erase_decl = false;
|
||||
bool set_external_name = false;
|
||||
switch (decl->decl_kind)
|
||||
{
|
||||
case DECL_ERASED:
|
||||
break;
|
||||
case DECL_INTERFACE:
|
||||
if (!sema_analyse_interface(context, decl, &erase_decl)) goto FAILED;
|
||||
set_external_name = true;
|
||||
break;
|
||||
case DECL_BITSTRUCT:
|
||||
if (!sema_analyse_bitstruct(context, decl, &erase_decl)) goto FAILED;
|
||||
set_external_name = true;
|
||||
break;
|
||||
case DECL_STRUCT:
|
||||
case DECL_UNION:
|
||||
if (!sema_analyse_struct_union(context, decl, &erase_decl)) goto FAILED;
|
||||
set_external_name = true;
|
||||
break;
|
||||
case DECL_FNTYPE:
|
||||
if (!sema_analyse_fntype(context, decl, &erase_decl)) goto FAILED;
|
||||
@@ -4138,25 +4089,21 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl)
|
||||
break;
|
||||
case DECL_VAR:
|
||||
if (!sema_analyse_var_decl(context, decl, false)) goto FAILED;
|
||||
set_external_name = true;
|
||||
break;
|
||||
case DECL_ATTRIBUTE:
|
||||
if (!sema_analyse_attribute_decl(context, context, decl, &erase_decl)) goto FAILED;
|
||||
break;
|
||||
case DECL_DISTINCT:
|
||||
if (!sema_analyse_distinct(context, decl, &erase_decl)) goto FAILED;
|
||||
set_external_name = true;
|
||||
break;
|
||||
case DECL_TYPEDEF:
|
||||
if (!sema_analyse_typedef(context, decl, &erase_decl)) goto FAILED;
|
||||
break;
|
||||
case DECL_ENUM:
|
||||
if (!sema_analyse_enum(context, decl, &erase_decl)) goto FAILED;
|
||||
set_external_name = true;
|
||||
break;
|
||||
case DECL_FAULT:
|
||||
if (!sema_analyse_error(context, decl, &erase_decl)) goto FAILED;
|
||||
set_external_name = true;
|
||||
break;
|
||||
case DECL_DEFINE:
|
||||
if (!sema_analyse_define(context, decl, &erase_decl)) goto FAILED;
|
||||
@@ -4178,9 +4125,7 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl)
|
||||
if (erase_decl)
|
||||
{
|
||||
decl->decl_kind = DECL_ERASED;
|
||||
set_external_name = false;
|
||||
}
|
||||
if (set_external_name) decl_set_external_name(decl);
|
||||
decl->resolve_status = RESOLVE_DONE;
|
||||
sema_context_destroy(&temp_context);
|
||||
|
||||
|
||||
@@ -7372,7 +7372,15 @@ static inline void sema_expr_rewrite_to_type_nameof(Expr *expr, Type *type, Toke
|
||||
if (type_is_func_ptr(type)) type = type->pointer->function.prototype->raw_type;
|
||||
if (name_type == TOKEN_CT_EXTNAMEOF)
|
||||
{
|
||||
expr_rewrite_to_string(expr, type->decl->extname);
|
||||
if (type_is_user_defined(type))
|
||||
{
|
||||
scratch_buffer_set_extern_decl_name(type->decl, true);
|
||||
expr_rewrite_to_string(expr, scratch_buffer_copy());
|
||||
}
|
||||
else
|
||||
{
|
||||
expr_rewrite_to_string(expr, type->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7409,12 +7417,64 @@ static inline bool sema_expr_analyse_ct_nameof(SemaContext *context, Expr *expr)
|
||||
|
||||
if (name_type == TOKEN_CT_EXTNAMEOF)
|
||||
{
|
||||
if (!decl->extname)
|
||||
switch (decl->decl_kind)
|
||||
{
|
||||
SEMA_ERROR(main_var, "'%s' does not have an external name.", decl->name);
|
||||
return false;
|
||||
case DECL_VAR:
|
||||
switch (decl->var.kind)
|
||||
{
|
||||
case VARDECL_CONST:
|
||||
case VARDECL_GLOBAL:
|
||||
goto RETURN_CT;
|
||||
case VARDECL_LOCAL:
|
||||
case VARDECL_PARAM:
|
||||
case VARDECL_MEMBER:
|
||||
case VARDECL_BITMEMBER:
|
||||
case VARDECL_PARAM_REF:
|
||||
case VARDECL_PARAM_EXPR:
|
||||
case VARDECL_UNWRAPPED:
|
||||
case VARDECL_ERASE:
|
||||
case VARDECL_REWRAPPED:
|
||||
case VARDECL_PARAM_CT:
|
||||
case VARDECL_PARAM_CT_TYPE:
|
||||
case VARDECL_LOCAL_CT:
|
||||
case VARDECL_LOCAL_CT_TYPE:
|
||||
// TODO verify that all of these are correct.
|
||||
break;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case DECL_POISONED:
|
||||
case DECL_ATTRIBUTE:
|
||||
case DECL_BODYPARAM:
|
||||
case DECL_CT_ASSERT:
|
||||
case DECL_CT_ECHO:
|
||||
case DECL_CT_EXEC:
|
||||
case DECL_CT_INCLUDE:
|
||||
case DECL_DECLARRAY:
|
||||
case DECL_ERASED:
|
||||
case DECL_GLOBALS:
|
||||
case DECL_IMPORT:
|
||||
case DECL_LABEL:
|
||||
case DECL_MACRO:
|
||||
case DECL_DEFINE:
|
||||
RETURN_SEMA_ERROR(main_var, "'%s' does not have an external name.", decl->name);
|
||||
case DECL_BITSTRUCT:
|
||||
case DECL_DISTINCT:
|
||||
case DECL_ENUM:
|
||||
case DECL_ENUM_CONSTANT:
|
||||
case DECL_FAULT:
|
||||
case DECL_FAULTVALUE:
|
||||
case DECL_FNTYPE:
|
||||
case DECL_FUNC:
|
||||
case DECL_INTERFACE:
|
||||
case DECL_STRUCT:
|
||||
case DECL_TYPEDEF:
|
||||
case DECL_UNION:
|
||||
// TODO verify that all of these are correct
|
||||
goto RETURN_CT;
|
||||
}
|
||||
expr_rewrite_to_string(expr, decl->extname);
|
||||
RETURN_CT:
|
||||
scratch_buffer_set_extern_decl_name(decl, true);
|
||||
expr_rewrite_to_string(expr, scratch_buffer_to_string());
|
||||
return true;
|
||||
}
|
||||
if (!decl->unit || name_type == TOKEN_CT_NAMEOF || decl_is_var_local(decl))
|
||||
@@ -7808,7 +7868,8 @@ static inline bool sema_expr_analyse_lambda(SemaContext *context, Type *target_t
|
||||
}
|
||||
scratch_buffer_append("$lambda");
|
||||
scratch_buffer_append_unsigned_int(++unit->lambda_count);
|
||||
decl->extname = decl->name = scratch_buffer_copy();
|
||||
decl->name = scratch_buffer_copy();
|
||||
decl->extname = decl->name;
|
||||
decl->type = type_new_func(decl, sig);
|
||||
if (!sema_analyse_function_signature(context, decl, sig->abi, sig)) return false;
|
||||
if (target_type && flat->pointer->function.prototype->raw_type != decl->type->function.prototype->raw_type)
|
||||
|
||||
@@ -633,7 +633,7 @@ void type_mangle_introspect_name_to_buffer(Type *type)
|
||||
type = type->function.prototype->raw_type;
|
||||
if (type->function.decl)
|
||||
{
|
||||
module_copy_extern_name_to_buffer(decl_module(type->function.decl));
|
||||
scratch_buffer_append_module(decl_module(type->function.decl), true);
|
||||
scratch_buffer_append("$");
|
||||
scratch_buffer_append(type->name);
|
||||
}
|
||||
|
||||
@@ -690,11 +690,11 @@ no_match: ; preds = %compare
|
||||
!106 = !{!12}
|
||||
!107 = !DILocalVariable(name: "scratch", scope: !108, file: !5, line: 110, type: !109, align: 8)
|
||||
!108 = distinct !DISubprogram(name: "@scratch", linkageName: "@scratch", scope: !5, file: !5, line: 109, scopeLine: 109, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit:
|
||||
!109 = !DICompositeType(tag: DW_TAG_structure_type, name: "Arena_Cursor", scope: !5, file: !5, line: 88, size: 128, align: 64, elements: !110, identifier: "foo_Arena_Cursor")
|
||||
!109 = !DICompositeType(tag: DW_TAG_structure_type, name: "Arena_Cursor", scope: !5, file: !5, line: 88, size: 128, align: 64, elements: !110, identifier: "foo__Arena_Cursor")
|
||||
!110 = !{!111, !116}
|
||||
!111 = !DIDerivedType(tag: DW_TAG_member, name: "arena", scope: !109, file: !5, line: 89, baseType: !112, size: 64, align: 64)
|
||||
!112 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "Arena*", baseType: !113, size: 64, align: 64, dwarfAddressSpace: 0)
|
||||
!113 = !DICompositeType(tag: DW_TAG_structure_type, name: "Arena", scope: !5, file: !5, line: 84, size: 64, align: 64, elements: !114, identifier: "foo_Arena")
|
||||
!113 = !DICompositeType(tag: DW_TAG_structure_type, name: "Arena", scope: !5, file: !5, line: 84, size: 64, align: 64, elements: !114, identifier: "foo__Arena")
|
||||
!114 = !{!115}
|
||||
!115 = !DIDerivedType(tag: DW_TAG_member, name: "cursor", scope: !113, file: !5, line: 85, baseType: !44, size: 64, align: 64)
|
||||
!116 = !DIDerivedType(tag: DW_TAG_member, name: "cursor", scope: !109, file: !5, line: 90, baseType: !44, size: 64, align: 64, offset: 64)
|
||||
|
||||
@@ -12,7 +12,7 @@ fn int main()
|
||||
|
||||
/* #expect: foo.ll
|
||||
|
||||
@foo_data = local_unnamed_addr global <{ { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } }, { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } }> <{ { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } { { float, [4 x float], float, [4 x float], float, [4 x float], float } { float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00 } } }, { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } { { float, [4 x float], float, [4 x float], float, [4 x float], float } { float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00 } } } }>, align 16
|
||||
@foo__data = local_unnamed_addr global <{ { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } }, { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } }> <{ { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } { { float, [4 x float], float, [4 x float], float, [4 x float], float } { float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00 } } }, { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } { { float, [4 x float], float, [4 x float], float, [4 x float], float } { float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00 } } } }>, align 16
|
||||
@foo.x = local_unnamed_addr global { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } } { { { float, [4 x float], float, [4 x float], float, [4 x float], float } } { { float, [4 x float], float, [4 x float], float, [4 x float], float } { float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00, [4 x float] zeroinitializer, float 1.000000e+00 } } }, align 4
|
||||
|
||||
entry:
|
||||
|
||||
@@ -19,11 +19,11 @@ int d @private;
|
||||
/* #expect: test.ll
|
||||
|
||||
|
||||
@TEST_a = local_unnamed_addr global i32 0, align 4
|
||||
@TEST__a = local_unnamed_addr global i32 0, align 4
|
||||
@TEST.b = internal unnamed_addr global i32 0, align 4
|
||||
@TEST_c = local_unnamed_addr global i32 0, align 4
|
||||
@TEST_d = local_unnamed_addr global i32 0, align 4
|
||||
@TEST__c = local_unnamed_addr global i32 0, align 4
|
||||
@TEST__d = local_unnamed_addr global i32 0, align 4
|
||||
|
||||
define internal void @TEST.hello()
|
||||
define void @TEST_hello2()
|
||||
define void @TEST_helloe()
|
||||
define void @TEST__hello2()
|
||||
define void @TEST__helloe()
|
||||
@@ -17,7 +17,7 @@ fn int foo(int x) @export
|
||||
}
|
||||
/* #expect: test.ll
|
||||
|
||||
define i32 @test_foo(i32 %0) #0 {
|
||||
define i32 @test__foo(i32 %0) #0 {
|
||||
entry:
|
||||
%x = alloca i32, align 4
|
||||
%switch = alloca i32, align 4
|
||||
|
||||
@@ -718,7 +718,7 @@ entry:
|
||||
br i1 %eq, label %and.rhs, label %and.phi
|
||||
|
||||
and.rhs: ; preds = %entry
|
||||
%2 = call i8 @char.is_alpha(i8 zeroext %1)
|
||||
%2 = call i8 @std.ascii.char.is_alpha(i8 zeroext %1)
|
||||
%3 = trunc i8 %2 to i1
|
||||
br label %and.phi
|
||||
|
||||
@@ -731,7 +731,7 @@ or.rhs: ; preds = %and.phi
|
||||
br i1 %lt, label %and.rhs1, label %and.phi2
|
||||
|
||||
and.rhs1: ; preds = %or.rhs
|
||||
%4 = call i8 @char.is_alnum(i8 zeroext %1)
|
||||
%4 = call i8 @std.ascii.char.is_alnum(i8 zeroext %1)
|
||||
%5 = trunc i8 %4 to i1
|
||||
br label %and.phi2
|
||||
|
||||
|
||||
Reference in New Issue
Block a user