mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Add paramsof.
This commit is contained in:
@@ -4,6 +4,12 @@
|
||||
module std::core::runtime;
|
||||
import libc, std::time, std::io, std::sort;
|
||||
|
||||
struct ReflectedParam @if(!$defined(ReflectedParam))
|
||||
{
|
||||
String name;
|
||||
typeid type;
|
||||
}
|
||||
|
||||
struct AnyRaw
|
||||
{
|
||||
void* ptr;
|
||||
|
||||
@@ -158,6 +158,12 @@ fn usz! Formatter.out_str(&self, any arg) @private
|
||||
assert(i < arg.type.names.len, "Illegal enum value found, numerical value was %d.", i);
|
||||
return self.out_substr(arg.type.names[i]);
|
||||
case STRUCT:
|
||||
if (arg.type == ReflectedParam.typeid)
|
||||
{
|
||||
ReflectedParam* param = arg.ptr;
|
||||
return self.out_substr("[Parameter '")
|
||||
+ self.out_substr(param.name) + self.out_substr("']");
|
||||
}
|
||||
return self.out_substr("<struct>");
|
||||
case UNION:
|
||||
return self.out_substr("<union>");
|
||||
|
||||
@@ -32,7 +32,7 @@ def Indexs = char[256] @private;
|
||||
def ElementType = $typeof(Type{}[0]);
|
||||
|
||||
const bool NO_KEY_FN @private = types::is_same(KeyFn, EmptySlot);
|
||||
const bool KEY_BY_VALUE @private = NO_KEY_FN ||| $assignable(Type{}[0], $typefrom(KeyFn.params[0]));
|
||||
const bool KEY_BY_VALUE @private = NO_KEY_FN ||| $assignable(Type{}[0], $typefrom(KeyFn.paramsof[0].type));
|
||||
const bool LIST_HAS_REF @private = $defined(&Type{}[0]);
|
||||
|
||||
def KeyFnReturnType = $typefrom(KeyFn.returns) @if(!NO_KEY_FN);
|
||||
|
||||
@@ -20,7 +20,7 @@ fn void isort(Type list, usz low, usz high, CmpFn comp, Context context)
|
||||
{
|
||||
var $has_cmp = @is_valid_macro_slot(comp);
|
||||
var $has_context = @is_valid_macro_slot(context);
|
||||
var $cmp_by_value = $has_cmp &&& $assignable(list[0], $typefrom(CmpFn.params[0]));
|
||||
var $cmp_by_value = $has_cmp &&& $assignable(list[0], $typefrom(CmpFn.paramsof[0].type));
|
||||
var $has_get_ref = $defined(&list[0]);
|
||||
for (usz i = low; i < high; ++i)
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ fn void qsort(Type list, isz low, isz high, CmpFn cmp, Context context)
|
||||
{
|
||||
var $has_cmp = @is_valid_macro_slot(cmp);
|
||||
var $has_context = @is_valid_macro_slot(context);
|
||||
var $cmp_by_value = $has_cmp &&& $assignable(list[0], $typefrom(CmpFn.params[0]));
|
||||
var $cmp_by_value = $has_cmp &&& $assignable(list[0], $typefrom(CmpFn.paramsof[0].type));
|
||||
|
||||
if (low >= 0 && high >= 0 && low < high)
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
- Allow `var` in lambdas in macros.
|
||||
- Support `int[*] { 1, 2, 3 }` expressions.
|
||||
- Support inline struct designated init as if inline was anonymous.
|
||||
- Introduce the `.paramsof` property.
|
||||
|
||||
### Fixes
|
||||
- Issue where a lambda wasn't correctly registered as external. #1408
|
||||
|
||||
@@ -1794,7 +1794,7 @@ typedef struct
|
||||
Module **module_list;
|
||||
Module **generic_module_list;
|
||||
Type **type;
|
||||
Decl** method_extensions;
|
||||
Decl **method_extensions;
|
||||
const char *lib_dir;
|
||||
const char **sources;
|
||||
File **loaded_sources;
|
||||
@@ -1850,6 +1850,7 @@ extern Type *type_cuint;
|
||||
extern Type *type_chars;
|
||||
extern Type *type_wildcard_optional;
|
||||
extern Type *type_string;
|
||||
extern Type *type_reflect_method;
|
||||
extern File stdin_file;
|
||||
|
||||
extern const char *attribute_list[NUMBER_OF_ATTRIBUTES];
|
||||
|
||||
@@ -1373,6 +1373,7 @@ typedef enum
|
||||
TYPE_PROPERTY_NAMES,
|
||||
TYPE_PROPERTY_NAMEOF,
|
||||
TYPE_PROPERTY_PARAMS,
|
||||
TYPE_PROPERTY_PARAMSOF,
|
||||
TYPE_PROPERTY_PARENTOF,
|
||||
TYPE_PROPERTY_QNAMEOF,
|
||||
TYPE_PROPERTY_RETURNS,
|
||||
|
||||
@@ -3601,6 +3601,7 @@ static inline bool sema_expr_analyse_member_access(SemaContext *context, Expr *e
|
||||
case TYPE_PROPERTY_ELEMENTS:
|
||||
case TYPE_PROPERTY_EXTNAMEOF:
|
||||
case TYPE_PROPERTY_PARAMS:
|
||||
case TYPE_PROPERTY_PARAMSOF:
|
||||
case TYPE_PROPERTY_RETURNS:
|
||||
case TYPE_PROPERTY_INF:
|
||||
case TYPE_PROPERTY_LEN:
|
||||
@@ -3635,6 +3636,7 @@ static inline bool sema_expr_analyse_member_access(SemaContext *context, Expr *e
|
||||
RETURN_SEMA_ERROR(expr, "No member '%s' found.", name);
|
||||
}
|
||||
|
||||
|
||||
expr->expr_kind = EXPR_CONST;
|
||||
expr->resolve_status = RESOLVE_DONE;
|
||||
expr->const_expr = (ExprConst) {
|
||||
@@ -3841,6 +3843,29 @@ static inline bool sema_create_const_params(SemaContext *context, Expr *expr, Ty
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool sema_create_const_paramsof(SemaContext *context, Expr *expr, Type *type)
|
||||
{
|
||||
ASSERT_SPAN(expr, type->type_kind == TYPE_FUNC_PTR);
|
||||
type = type->pointer;
|
||||
Signature *sig = type->function.signature;
|
||||
unsigned params = vec_size(sig->params);
|
||||
Expr **param_exprs = params ? VECNEW(Expr*, params) : NULL;
|
||||
SourceSpan span = expr->span;
|
||||
for (unsigned i = 0; i < params; i++)
|
||||
{
|
||||
Decl *decl = sig->params[i];
|
||||
Expr *name_expr = expr_new(EXPR_CONST, span);
|
||||
expr_rewrite_to_string(name_expr, decl->name ? decl->name : "");
|
||||
Expr *type_expr = expr_new(EXPR_CONST, span);
|
||||
expr_rewrite_const_typeid(type_expr, decl->type->canonical);
|
||||
Expr *values[] = { name_expr, type_expr };
|
||||
Expr *struct_value = sema_create_struct_from_expressions(type_reflect_method->decl, expr->span, values);
|
||||
vec_add(param_exprs, struct_value);
|
||||
}
|
||||
expr_rewrite_const_untyped_list(expr, param_exprs);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool sema_create_const_associated(SemaContext *context, Expr *expr, Type *type)
|
||||
{
|
||||
ASSERT_SPAN(expr, type->type_kind == TYPE_ENUM);
|
||||
@@ -4062,6 +4087,7 @@ static bool sema_expr_rewrite_to_typeid_property(SemaContext *context, Expr *exp
|
||||
case TYPE_PROPERTY_NAMEOF:
|
||||
case TYPE_PROPERTY_NAN:
|
||||
case TYPE_PROPERTY_PARAMS:
|
||||
case TYPE_PROPERTY_PARAMSOF:
|
||||
case TYPE_PROPERTY_QNAMEOF:
|
||||
case TYPE_PROPERTY_RETURNS:
|
||||
case TYPE_PROPERTY_TAGOF:
|
||||
@@ -4350,6 +4376,7 @@ static bool sema_type_property_is_valid_for_type(Type *original_type, TypeProper
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
case TYPE_PROPERTY_PARAMSOF:
|
||||
case TYPE_PROPERTY_PARAMS:
|
||||
case TYPE_PROPERTY_RETURNS:
|
||||
return type_is_func_ptr(type);
|
||||
@@ -4433,6 +4460,8 @@ static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr,
|
||||
sema_create_const_methodsof(context, expr, flat);
|
||||
return true;
|
||||
}
|
||||
case TYPE_PROPERTY_PARAMSOF:
|
||||
return sema_create_const_paramsof(context, expr, flat);
|
||||
case TYPE_PROPERTY_PARAMS:
|
||||
return sema_create_const_params(context, expr, flat);
|
||||
case TYPE_PROPERTY_RETURNS:
|
||||
|
||||
@@ -12,7 +12,6 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type
|
||||
Expr *initializer);
|
||||
static inline void sema_not_enough_elements_error(SemaContext *context, Expr *initializer, int element);
|
||||
static inline bool sema_expr_analyse_initializer(SemaContext *context, Type *assigned_type, Type *flattened, Expr *expr);
|
||||
static void sema_create_const_initializer_value(ConstInitializer *const_init, Expr *value);
|
||||
static void sema_create_const_initializer_from_designated_init(ConstInitializer *const_init, Expr *initializer);
|
||||
static Decl *sema_resolve_element_for_name(SemaContext *context, Decl **decls, DesignatorElement ***elements_ref, unsigned *index, bool is_substruct);
|
||||
static Type *sema_expr_analyse_designator(SemaContext *context, Type *current, Expr *expr, ArrayIndex *max_index, Decl **member_ptr);
|
||||
@@ -250,6 +249,30 @@ static inline bool sema_expr_analyse_struct_plain_initializer(SemaContext *conte
|
||||
|
||||
}
|
||||
|
||||
Expr *sema_create_struct_from_expressions(Decl *struct_decl, SourceSpan span, Expr **exprs)
|
||||
{
|
||||
Expr *expr_element = expr_calloc();
|
||||
expr_element->expr_kind = EXPR_CONST;
|
||||
expr_element->span = span;
|
||||
expr_element->type = struct_decl->type;
|
||||
expr_element->const_expr.const_kind = CONST_INITIALIZER;
|
||||
expr_element->resolve_status = RESOLVE_DONE;
|
||||
ConstInitializer *init = CALLOCS(ConstInitializer);
|
||||
expr_element->const_expr.initializer = init;
|
||||
init->kind = CONST_INIT_STRUCT;
|
||||
init->type = struct_decl->type;
|
||||
unsigned params = vec_size(struct_decl->strukt.members);
|
||||
ConstInitializer **struct_values = MALLOC(params * sizeof(ConstInitializer*));
|
||||
init->init_struct = struct_values;
|
||||
for (unsigned i = 0; i < params; i++)
|
||||
{
|
||||
ConstInitializer *member_init = MALLOCS(ConstInitializer);
|
||||
sema_create_const_initializer_value(member_init, exprs[i]);
|
||||
struct_values[i] = member_init;
|
||||
}
|
||||
return expr_element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform analysis for a plain initializer, that is one initializing all fields.
|
||||
* @return true if analysis succeeds.
|
||||
@@ -799,8 +822,7 @@ bool sema_expr_analyse_initializer_list(SemaContext *context, Type *to, Expr *ex
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void sema_create_const_initializer_value(ConstInitializer *const_init, Expr *value)
|
||||
void sema_create_const_initializer_value(ConstInitializer *const_init, Expr *value)
|
||||
{
|
||||
// Possibly this is already a const initializers, in that case
|
||||
// overwrite what is inside, eg [1] = { .a = 1 }
|
||||
|
||||
@@ -107,6 +107,8 @@ bool sema_bit_assignment_check(SemaContext *context, Expr *right, Decl *member);
|
||||
CondResult sema_check_comp_time_bool(SemaContext *context, Expr *expr);
|
||||
bool sema_expr_check_assign(SemaContext *context, Expr *expr);
|
||||
bool sema_analyse_function_signature(SemaContext *context, Decl *func_decl, TypeInfo *parent, CallABI abi, Signature *signature);
|
||||
void sema_create_const_initializer_value(ConstInitializer *const_init, Expr *value);
|
||||
Expr *sema_create_struct_from_expressions(Decl *struct_decl, SourceSpan span, Expr **exprs);
|
||||
ConstInitializer *sema_merge_bitstruct_const_initializers(ConstInitializer *lhs, ConstInitializer *rhs, BinaryOp op);
|
||||
void sema_invert_bitstruct_const_initializer(ConstInitializer *initializer);
|
||||
ArrayIndex sema_len_from_const(Expr *expr);
|
||||
|
||||
@@ -173,6 +173,7 @@ void symtab_init(uint32_t capacity)
|
||||
type_property_list[TYPE_PROPERTY_NAMES] = KW_DEF("names");
|
||||
type_property_list[TYPE_PROPERTY_NAN] = KW_DEF("nan");
|
||||
type_property_list[TYPE_PROPERTY_PARAMS] = KW_DEF("params");
|
||||
type_property_list[TYPE_PROPERTY_PARAMSOF] = KW_DEF("paramsof");
|
||||
type_property_list[TYPE_PROPERTY_PARENTOF] = KW_DEF("parentof");
|
||||
type_property_list[TYPE_PROPERTY_QNAMEOF] = KW_DEF("qnameof");
|
||||
type_property_list[TYPE_PROPERTY_RETURNS] = KW_DEF("returns");
|
||||
|
||||
@@ -49,6 +49,7 @@ Type *type_member = &t.member;
|
||||
Type *type_chars = NULL;
|
||||
Type *type_wildcard_optional = NULL;
|
||||
Type *type_string = &t.string;
|
||||
Type *type_reflect_method;
|
||||
Type *type_cint;
|
||||
Type *type_cuint;
|
||||
|
||||
@@ -1286,6 +1287,34 @@ static inline void type_create_float(const char *name, Type *type, TypeKind kind
|
||||
type_init(name, type, kind, actual_bits, compiler.platform.floats[bits]);
|
||||
}
|
||||
|
||||
Type *type_create_struct(const char *name, Type **types, const char **names, int count)
|
||||
{
|
||||
Decl *decl = decl_new_with_type(symtab_preset(name, TOKEN_TYPE_IDENT), INVALID_SPAN, DECL_STRUCT);
|
||||
decl->unit = compiler.context.core_unit;
|
||||
decl->extname = decl->name;
|
||||
AlignSize offset = 0;
|
||||
AlignSize max_align = 0;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Type *member_type = types[i];
|
||||
Decl *member = decl_new_var(symtab_preset(names[i], TOKEN_IDENT), INVALID_SPAN, type_info_new_base(member_type, INVALID_SPAN), VARDECL_MEMBER);
|
||||
member->unit = compiler.context.core_unit;
|
||||
member->type = member_type;
|
||||
member->resolve_status = RESOLVE_DONE;
|
||||
AlignSize align = type_abi_alignment(member_type);
|
||||
if (align > max_align) max_align = align;
|
||||
member->offset = aligned_offset(offset, align);
|
||||
offset = member->offset + type_size(member_type);
|
||||
member->alignment = align;
|
||||
vec_add(decl->strukt.members, member);
|
||||
}
|
||||
decl->strukt.size = aligned_offset(offset, max_align);
|
||||
decl->alignment = max_align;
|
||||
decl->resolve_status = RESOLVE_DONE;
|
||||
global_context_add_type(decl->type);
|
||||
global_context_add_decl(decl);
|
||||
return decl->type;
|
||||
}
|
||||
void type_setup(PlatformTarget *target)
|
||||
{
|
||||
max_alignment_vector = (AlignSize)target->align_max_vector;
|
||||
@@ -1340,8 +1369,13 @@ void type_setup(PlatformTarget *target)
|
||||
string_decl->distinct = type_info_new_base(type_chars, INVALID_SPAN);
|
||||
string_decl->resolve_status = RESOLVE_DONE;
|
||||
type_string = string_decl->type;
|
||||
|
||||
global_context_add_type(string_decl->type);
|
||||
global_context_add_decl(string_decl);
|
||||
|
||||
Type* types[2] = { type_string, type_typeid };
|
||||
const char* names[2] = { "name", "type" };
|
||||
type_reflect_method = type_create_struct("ReflectedParam", types, names, 2);
|
||||
}
|
||||
|
||||
int type_kind_bitsize(TypeKind kind)
|
||||
|
||||
391
test/test_suite/compile_time_introspection/paramsof.c3t
Normal file
391
test/test_suite/compile_time_introspection/paramsof.c3t
Normal file
@@ -0,0 +1,391 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
import std;
|
||||
fn void testme(int a, double b)
|
||||
{}
|
||||
|
||||
fn void main()
|
||||
{
|
||||
ReflectedParam[*] z = $typeof(testme).paramsof;
|
||||
foreach (r : z)
|
||||
{
|
||||
io::printn(r);
|
||||
}
|
||||
$foreach ($r : $typeof(testme).paramsof)
|
||||
io::printn($r.name);
|
||||
io::printn($r.type.nameof);
|
||||
$endforeach
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
|
||||
; ModuleID = 'test'
|
||||
|
||||
%ReflectedParam = type { %"char[]", i64 }
|
||||
|
||||
@.str = private unnamed_addr constant [2 x i8] c"a\00", align 1
|
||||
@"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
|
||||
@.str.1 = private unnamed_addr constant [2 x i8] c"b\00", align 1
|
||||
@"$ct.double" = linkonce global %.introspect { i8 4, i64 0, ptr null, i64 8, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
|
||||
@.__const = private unnamed_addr constant [2 x %ReflectedParam] [%ReflectedParam { %"char[]" { ptr @.str, i64 1 }, i64 ptrtoint (ptr @"$ct.int" to i64) }, %ReflectedParam { %"char[]" { ptr @.str.1, i64 1 }, i64 ptrtoint (ptr @"$ct.double" to i64) }], align 16
|
||||
@"$ct.std.io.File" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8
|
||||
@.str.2 = private unnamed_addr constant [3 x i8] c"%s\00", align 1
|
||||
@"$ct.ReflectedParam" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 24, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
|
||||
@.str.3 = private unnamed_addr constant [2 x i8] c"a\00", align 1
|
||||
@.str.4 = private unnamed_addr constant [4 x i8] c"int\00", align 1
|
||||
@.str.5 = private unnamed_addr constant [2 x i8] c"b\00", align 1
|
||||
@.str.6 = private unnamed_addr constant [7 x i8] c"double\00", align 1
|
||||
|
||||
define void @test.main() #0 {
|
||||
entry:
|
||||
%z = alloca [2 x %ReflectedParam], align 16
|
||||
%.anon = alloca i64, align 8
|
||||
%r = alloca %ReflectedParam, align 8
|
||||
%x = alloca %ReflectedParam, align 8
|
||||
%x1 = alloca %ReflectedParam, align 8
|
||||
%len = alloca i64, align 8
|
||||
%error_var = alloca i64, align 8
|
||||
%x2 = alloca %ReflectedParam, align 8
|
||||
%varargslots = alloca [1 x %any], align 16
|
||||
%retparam = alloca i64, align 8
|
||||
%taddr = alloca %any, align 8
|
||||
%indirectarg = alloca %"any[]", align 8
|
||||
%error_var4 = alloca i64, align 8
|
||||
%error_var10 = alloca i64, align 8
|
||||
%len16 = alloca i64, align 8
|
||||
%error_var17 = alloca i64, align 8
|
||||
%retparam19 = alloca i64, align 8
|
||||
%error_var25 = alloca i64, align 8
|
||||
%error_var31 = alloca i64, align 8
|
||||
%len39 = alloca i64, align 8
|
||||
%error_var40 = alloca i64, align 8
|
||||
%retparam42 = alloca i64, align 8
|
||||
%error_var48 = alloca i64, align 8
|
||||
%error_var54 = alloca i64, align 8
|
||||
%len62 = alloca i64, align 8
|
||||
%error_var63 = alloca i64, align 8
|
||||
%retparam65 = alloca i64, align 8
|
||||
%error_var71 = alloca i64, align 8
|
||||
%error_var77 = alloca i64, align 8
|
||||
%len85 = alloca i64, align 8
|
||||
%error_var86 = alloca i64, align 8
|
||||
%retparam88 = alloca i64, align 8
|
||||
%error_var94 = alloca i64, align 8
|
||||
%error_var100 = alloca i64, align 8
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %z, ptr align 16 @.__const, i32 48, i1 false)
|
||||
store i64 0, ptr %.anon, align 8
|
||||
br label %loop.cond
|
||||
|
||||
loop.cond: ; preds = %voiderr, %entry
|
||||
%0 = load i64, ptr %.anon, align 8
|
||||
%gt = icmp ugt i64 2, %0
|
||||
br i1 %gt, label %loop.body, label %loop.exit
|
||||
|
||||
loop.body: ; preds = %loop.cond
|
||||
%1 = load i64, ptr %.anon, align 8
|
||||
%ptroffset = getelementptr inbounds [24 x i8], ptr %z, i64 %1
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %r, ptr align 8 %ptroffset, i32 24, i1 false)
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %x, ptr align 8 %r, i32 24, i1 false)
|
||||
%2 = call ptr @std.io.stdout()
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %x1, ptr align 8 %x, i32 24, i1 false)
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %x2, ptr align 8 %x1, i32 24, i1 false)
|
||||
%3 = insertvalue %any undef, ptr %2, 0
|
||||
%4 = insertvalue %any %3, i64 ptrtoint (ptr @"$ct.std.io.File" to i64), 1
|
||||
%5 = insertvalue %any undef, ptr %x2, 0
|
||||
%6 = insertvalue %any %5, i64 ptrtoint (ptr @"$ct.ReflectedParam" to i64), 1
|
||||
store %any %6, ptr %varargslots, align 16
|
||||
%7 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %7, i64 1, 1
|
||||
store %any %4, ptr %taddr, align 8
|
||||
%lo = load i64, ptr %taddr, align 8
|
||||
%ptradd = getelementptr inbounds i8, ptr %taddr, i64 8
|
||||
%hi = load ptr, ptr %ptradd, align 8
|
||||
store %"any[]" %"$$temp", ptr %indirectarg, align 8
|
||||
%8 = call i64 @std.io.fprintf(ptr %retparam, i64 %lo, ptr %hi, ptr @.str.2, i64 2, ptr byval(%"any[]") align 8 %indirectarg)
|
||||
%not_err = icmp eq i64 %8, 0
|
||||
%9 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
||||
br i1 %9, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %loop.body
|
||||
store i64 %8, ptr %error_var, align 8
|
||||
br label %guard_block
|
||||
|
||||
after_check: ; preds = %loop.body
|
||||
br label %noerr_block
|
||||
|
||||
guard_block: ; preds = %assign_optional
|
||||
br label %voiderr
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%10 = load i64, ptr %retparam, align 8
|
||||
store i64 %10, ptr %len, align 8
|
||||
%11 = call i64 @std.io.File.write_byte(ptr %2, i8 zeroext 10)
|
||||
%not_err5 = icmp eq i64 %11, 0
|
||||
%12 = call i1 @llvm.expect.i1(i1 %not_err5, i1 true)
|
||||
br i1 %12, label %after_check7, label %assign_optional6
|
||||
|
||||
assign_optional6: ; preds = %noerr_block
|
||||
store i64 %11, ptr %error_var4, align 8
|
||||
br label %guard_block8
|
||||
|
||||
after_check7: ; preds = %noerr_block
|
||||
br label %noerr_block9
|
||||
|
||||
guard_block8: ; preds = %assign_optional6
|
||||
br label %voiderr
|
||||
|
||||
noerr_block9: ; preds = %after_check7
|
||||
%13 = call i64 @std.io.File.flush(ptr %2)
|
||||
%not_err11 = icmp eq i64 %13, 0
|
||||
%14 = call i1 @llvm.expect.i1(i1 %not_err11, i1 true)
|
||||
br i1 %14, label %after_check13, label %assign_optional12
|
||||
|
||||
assign_optional12: ; preds = %noerr_block9
|
||||
store i64 %13, ptr %error_var10, align 8
|
||||
br label %guard_block14
|
||||
|
||||
after_check13: ; preds = %noerr_block9
|
||||
br label %noerr_block15
|
||||
|
||||
guard_block14: ; preds = %assign_optional12
|
||||
br label %voiderr
|
||||
|
||||
noerr_block15: ; preds = %after_check13
|
||||
%15 = load i64, ptr %len, align 8
|
||||
%add = add i64 %15, 1
|
||||
br label %voiderr
|
||||
|
||||
voiderr: ; preds = %noerr_block15, %guard_block14, %guard_block8, %guard_block
|
||||
%16 = load i64, ptr %.anon, align 8
|
||||
%addnuw = add nuw i64 %16, 1
|
||||
store i64 %addnuw, ptr %.anon, align 8
|
||||
br label %loop.cond
|
||||
|
||||
loop.exit: ; preds = %loop.cond
|
||||
%17 = call ptr @std.io.stdout()
|
||||
%18 = call i64 @std.io.File.write(ptr %retparam19, ptr %17, ptr @.str.3, i64 1)
|
||||
%not_err20 = icmp eq i64 %18, 0
|
||||
%19 = call i1 @llvm.expect.i1(i1 %not_err20, i1 true)
|
||||
br i1 %19, label %after_check22, label %assign_optional21
|
||||
|
||||
assign_optional21: ; preds = %loop.exit
|
||||
store i64 %18, ptr %error_var17, align 8
|
||||
br label %guard_block23
|
||||
|
||||
after_check22: ; preds = %loop.exit
|
||||
br label %noerr_block24
|
||||
|
||||
guard_block23: ; preds = %assign_optional21
|
||||
br label %voiderr38
|
||||
|
||||
noerr_block24: ; preds = %after_check22
|
||||
%20 = load i64, ptr %retparam19, align 8
|
||||
store i64 %20, ptr %len16, align 8
|
||||
%21 = call i64 @std.io.File.write_byte(ptr %17, i8 zeroext 10)
|
||||
%not_err26 = icmp eq i64 %21, 0
|
||||
%22 = call i1 @llvm.expect.i1(i1 %not_err26, i1 true)
|
||||
br i1 %22, label %after_check28, label %assign_optional27
|
||||
|
||||
assign_optional27: ; preds = %noerr_block24
|
||||
store i64 %21, ptr %error_var25, align 8
|
||||
br label %guard_block29
|
||||
|
||||
after_check28: ; preds = %noerr_block24
|
||||
br label %noerr_block30
|
||||
|
||||
guard_block29: ; preds = %assign_optional27
|
||||
br label %voiderr38
|
||||
|
||||
noerr_block30: ; preds = %after_check28
|
||||
%23 = call i64 @std.io.File.flush(ptr %17)
|
||||
%not_err32 = icmp eq i64 %23, 0
|
||||
%24 = call i1 @llvm.expect.i1(i1 %not_err32, i1 true)
|
||||
br i1 %24, label %after_check34, label %assign_optional33
|
||||
|
||||
assign_optional33: ; preds = %noerr_block30
|
||||
store i64 %23, ptr %error_var31, align 8
|
||||
br label %guard_block35
|
||||
|
||||
after_check34: ; preds = %noerr_block30
|
||||
br label %noerr_block36
|
||||
|
||||
guard_block35: ; preds = %assign_optional33
|
||||
br label %voiderr38
|
||||
|
||||
noerr_block36: ; preds = %after_check34
|
||||
%25 = load i64, ptr %len16, align 8
|
||||
%add37 = add i64 %25, 1
|
||||
br label %voiderr38
|
||||
|
||||
voiderr38: ; preds = %noerr_block36, %guard_block35, %guard_block29, %guard_block23
|
||||
%26 = call ptr @std.io.stdout()
|
||||
%27 = call i64 @std.io.File.write(ptr %retparam42, ptr %26, ptr @.str.4, i64 3)
|
||||
%not_err43 = icmp eq i64 %27, 0
|
||||
%28 = call i1 @llvm.expect.i1(i1 %not_err43, i1 true)
|
||||
br i1 %28, label %after_check45, label %assign_optional44
|
||||
|
||||
assign_optional44: ; preds = %voiderr38
|
||||
store i64 %27, ptr %error_var40, align 8
|
||||
br label %guard_block46
|
||||
|
||||
after_check45: ; preds = %voiderr38
|
||||
br label %noerr_block47
|
||||
|
||||
guard_block46: ; preds = %assign_optional44
|
||||
br label %voiderr61
|
||||
|
||||
noerr_block47: ; preds = %after_check45
|
||||
%29 = load i64, ptr %retparam42, align 8
|
||||
store i64 %29, ptr %len39, align 8
|
||||
%30 = call i64 @std.io.File.write_byte(ptr %26, i8 zeroext 10)
|
||||
%not_err49 = icmp eq i64 %30, 0
|
||||
%31 = call i1 @llvm.expect.i1(i1 %not_err49, i1 true)
|
||||
br i1 %31, label %after_check51, label %assign_optional50
|
||||
|
||||
assign_optional50: ; preds = %noerr_block47
|
||||
store i64 %30, ptr %error_var48, align 8
|
||||
br label %guard_block52
|
||||
|
||||
after_check51: ; preds = %noerr_block47
|
||||
br label %noerr_block53
|
||||
|
||||
guard_block52: ; preds = %assign_optional50
|
||||
br label %voiderr61
|
||||
|
||||
noerr_block53: ; preds = %after_check51
|
||||
%32 = call i64 @std.io.File.flush(ptr %26)
|
||||
%not_err55 = icmp eq i64 %32, 0
|
||||
%33 = call i1 @llvm.expect.i1(i1 %not_err55, i1 true)
|
||||
br i1 %33, label %after_check57, label %assign_optional56
|
||||
|
||||
assign_optional56: ; preds = %noerr_block53
|
||||
store i64 %32, ptr %error_var54, align 8
|
||||
br label %guard_block58
|
||||
|
||||
after_check57: ; preds = %noerr_block53
|
||||
br label %noerr_block59
|
||||
|
||||
guard_block58: ; preds = %assign_optional56
|
||||
br label %voiderr61
|
||||
|
||||
noerr_block59: ; preds = %after_check57
|
||||
%34 = load i64, ptr %len39, align 8
|
||||
%add60 = add i64 %34, 1
|
||||
br label %voiderr61
|
||||
|
||||
voiderr61: ; preds = %noerr_block59, %guard_block58, %guard_block52, %guard_block46
|
||||
%35 = call ptr @std.io.stdout()
|
||||
%36 = call i64 @std.io.File.write(ptr %retparam65, ptr %35, ptr @.str.5, i64 1)
|
||||
%not_err66 = icmp eq i64 %36, 0
|
||||
%37 = call i1 @llvm.expect.i1(i1 %not_err66, i1 true)
|
||||
br i1 %37, label %after_check68, label %assign_optional67
|
||||
|
||||
assign_optional67: ; preds = %voiderr61
|
||||
store i64 %36, ptr %error_var63, align 8
|
||||
br label %guard_block69
|
||||
|
||||
after_check68: ; preds = %voiderr61
|
||||
br label %noerr_block70
|
||||
|
||||
guard_block69: ; preds = %assign_optional67
|
||||
br label %voiderr84
|
||||
|
||||
noerr_block70: ; preds = %after_check68
|
||||
%38 = load i64, ptr %retparam65, align 8
|
||||
store i64 %38, ptr %len62, align 8
|
||||
%39 = call i64 @std.io.File.write_byte(ptr %35, i8 zeroext 10)
|
||||
%not_err72 = icmp eq i64 %39, 0
|
||||
%40 = call i1 @llvm.expect.i1(i1 %not_err72, i1 true)
|
||||
br i1 %40, label %after_check74, label %assign_optional73
|
||||
|
||||
assign_optional73: ; preds = %noerr_block70
|
||||
store i64 %39, ptr %error_var71, align 8
|
||||
br label %guard_block75
|
||||
|
||||
after_check74: ; preds = %noerr_block70
|
||||
br label %noerr_block76
|
||||
|
||||
guard_block75: ; preds = %assign_optional73
|
||||
br label %voiderr84
|
||||
|
||||
noerr_block76: ; preds = %after_check74
|
||||
%41 = call i64 @std.io.File.flush(ptr %35)
|
||||
%not_err78 = icmp eq i64 %41, 0
|
||||
%42 = call i1 @llvm.expect.i1(i1 %not_err78, i1 true)
|
||||
br i1 %42, label %after_check80, label %assign_optional79
|
||||
|
||||
assign_optional79: ; preds = %noerr_block76
|
||||
store i64 %41, ptr %error_var77, align 8
|
||||
br label %guard_block81
|
||||
|
||||
after_check80: ; preds = %noerr_block76
|
||||
br label %noerr_block82
|
||||
|
||||
guard_block81: ; preds = %assign_optional79
|
||||
br label %voiderr84
|
||||
|
||||
noerr_block82: ; preds = %after_check80
|
||||
%43 = load i64, ptr %len62, align 8
|
||||
%add83 = add i64 %43, 1
|
||||
br label %voiderr84
|
||||
|
||||
voiderr84: ; preds = %noerr_block82, %guard_block81, %guard_block75, %guard_block69
|
||||
%44 = call ptr @std.io.stdout()
|
||||
%45 = call i64 @std.io.File.write(ptr %retparam88, ptr %44, ptr @.str.6, i64 6)
|
||||
%not_err89 = icmp eq i64 %45, 0
|
||||
%46 = call i1 @llvm.expect.i1(i1 %not_err89, i1 true)
|
||||
br i1 %46, label %after_check91, label %assign_optional90
|
||||
|
||||
assign_optional90: ; preds = %voiderr84
|
||||
store i64 %45, ptr %error_var86, align 8
|
||||
br label %guard_block92
|
||||
|
||||
after_check91: ; preds = %voiderr84
|
||||
br label %noerr_block93
|
||||
|
||||
guard_block92: ; preds = %assign_optional90
|
||||
br label %voiderr107
|
||||
|
||||
noerr_block93: ; preds = %after_check91
|
||||
%47 = load i64, ptr %retparam88, align 8
|
||||
store i64 %47, ptr %len85, align 8
|
||||
%48 = call i64 @std.io.File.write_byte(ptr %44, i8 zeroext 10)
|
||||
%not_err95 = icmp eq i64 %48, 0
|
||||
%49 = call i1 @llvm.expect.i1(i1 %not_err95, i1 true)
|
||||
br i1 %49, label %after_check97, label %assign_optional96
|
||||
|
||||
assign_optional96: ; preds = %noerr_block93
|
||||
store i64 %48, ptr %error_var94, align 8
|
||||
br label %guard_block98
|
||||
|
||||
after_check97: ; preds = %noerr_block93
|
||||
br label %noerr_block99
|
||||
|
||||
guard_block98: ; preds = %assign_optional96
|
||||
br label %voiderr107
|
||||
|
||||
noerr_block99: ; preds = %after_check97
|
||||
%50 = call i64 @std.io.File.flush(ptr %44)
|
||||
%not_err101 = icmp eq i64 %50, 0
|
||||
%51 = call i1 @llvm.expect.i1(i1 %not_err101, i1 true)
|
||||
br i1 %51, label %after_check103, label %assign_optional102
|
||||
|
||||
assign_optional102: ; preds = %noerr_block99
|
||||
store i64 %50, ptr %error_var100, align 8
|
||||
br label %guard_block104
|
||||
|
||||
after_check103: ; preds = %noerr_block99
|
||||
br label %noerr_block105
|
||||
|
||||
guard_block104: ; preds = %assign_optional102
|
||||
br label %voiderr107
|
||||
|
||||
noerr_block105: ; preds = %after_check103
|
||||
%52 = load i64, ptr %len85, align 8
|
||||
%add106 = add i64 %52, 1
|
||||
br label %voiderr107
|
||||
|
||||
voiderr107: ; preds = %noerr_block105, %guard_block104, %guard_block98, %guard_block92
|
||||
ret void
|
||||
}
|
||||
Reference in New Issue
Block a user