mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Version bump. Updated printf using "Formatter". Fix to initializers.
This commit is contained in:
committed by
Christoffer Lerno
parent
9f7ed00f04
commit
4783946476
@@ -128,7 +128,7 @@ fn void test()
|
||||
|
||||
### Current status
|
||||
|
||||
The current version of the compiler is alpha release 0.2.
|
||||
The current version of the compiler is alpha release 0.3.
|
||||
|
||||
It's possible to try out the current C3 compiler in the browser: https://ide.judge0.com/ – this is courtesy of the
|
||||
developer of Judge0.
|
||||
|
||||
572
lib/std/io_formatter_private.c3
Normal file
572
lib/std/io_formatter_private.c3
Normal file
@@ -0,0 +1,572 @@
|
||||
module std::io;
|
||||
|
||||
private fn void! Formatter.left_adjust(Formatter* this, usize len)
|
||||
{
|
||||
if (!this.flags.left) return;
|
||||
for (usize l = len; l < this.width; l++) this.out(' ')?;
|
||||
}
|
||||
|
||||
private fn void! Formatter.right_adjust(Formatter* this, usize len)
|
||||
{
|
||||
if (this.flags.left) return;
|
||||
for (usize l = len; l < this.width; l++) this.out(' ')?;
|
||||
}
|
||||
|
||||
|
||||
private fn NtoaType int_from_variant(variant arg, bool *is_neg)
|
||||
{
|
||||
*is_neg = false;
|
||||
$if (NtoaType.typeid == uint128.typeid):
|
||||
switch (arg)
|
||||
{
|
||||
case int128:
|
||||
int128 val = *arg;
|
||||
return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : val;
|
||||
case uint128:
|
||||
return *arg;
|
||||
}
|
||||
$endif;
|
||||
|
||||
if (arg.type.kind == TypeKind.POINTER)
|
||||
{
|
||||
return (NtoaType)(uptr)*(void**)arg.ptr;
|
||||
}
|
||||
switch (arg)
|
||||
{
|
||||
case bool:
|
||||
return (NtoaType)*arg;
|
||||
case ichar:
|
||||
int val = *arg;
|
||||
return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : (NtoaType)val;
|
||||
case short:
|
||||
int val = *arg;
|
||||
return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : (NtoaType)val;
|
||||
case int:
|
||||
int val = *arg;
|
||||
return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : (NtoaType)val;
|
||||
case long:
|
||||
long val = *arg;
|
||||
return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : (NtoaType)val;
|
||||
case char:
|
||||
return *arg;
|
||||
case ushort:
|
||||
return *arg;
|
||||
case uint:
|
||||
return *arg;
|
||||
case ulong:
|
||||
return *arg;
|
||||
case float:
|
||||
float f = *arg;
|
||||
return (NtoaType)((*is_neg = f < 0) ? -f : f);
|
||||
case double:
|
||||
double d = *arg;
|
||||
return (NtoaType)((*is_neg = d < 0) ? -d : d);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private fn FloatType float_from_variant(variant arg)
|
||||
{
|
||||
$if (env::I128_SUPPORT):
|
||||
switch (arg)
|
||||
{
|
||||
case int128:
|
||||
return *arg;
|
||||
case uint128:
|
||||
return *arg;
|
||||
}
|
||||
$endif;
|
||||
$if (env::F128_SUPPORT):
|
||||
if (arg.type == float128.typeid) return *((float128*)arg.ptr);
|
||||
$endif;
|
||||
$if (env::F16_SUPPORT):
|
||||
if (arg.type == float16.typeid) return *((float16*)arg.ptr);
|
||||
$endif;
|
||||
|
||||
if (arg.type.kind == TypeKind.POINTER)
|
||||
{
|
||||
return (FloatType)(uptr)(void*)arg.ptr;
|
||||
}
|
||||
switch (arg)
|
||||
{
|
||||
case bool:
|
||||
return (FloatType)*arg;
|
||||
case ichar:
|
||||
return *arg;
|
||||
case short:
|
||||
return *arg;
|
||||
case int:
|
||||
return *arg;
|
||||
case long:
|
||||
return *arg;
|
||||
case char:
|
||||
return *arg;
|
||||
case ushort:
|
||||
return *arg;
|
||||
case uint:
|
||||
return *arg;
|
||||
case ulong:
|
||||
return *arg;
|
||||
case float:
|
||||
return (FloatType)*arg;
|
||||
case double:
|
||||
return (FloatType)*arg;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a simple integer value, typically for formatting.
|
||||
*
|
||||
* @param [inout] len_ptr "the length remaining."
|
||||
* @param [in] buf "the buf to read from."
|
||||
* @param maxlen "the maximum len that can be read."
|
||||
* @return "The result of the atoi."
|
||||
**/
|
||||
private fn uint simple_atoi(char* buf, usize maxlen, usize* len_ptr) @inline
|
||||
{
|
||||
uint i = 0;
|
||||
usize len = *len_ptr;
|
||||
while (len < maxlen)
|
||||
{
|
||||
char c = buf[len];
|
||||
if (c < '0' || c > '9') break;
|
||||
i = i * 10 + c - '0';
|
||||
len++;
|
||||
}
|
||||
*len_ptr = len;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
private fn void! Formatter.out_substr(Formatter *this, char[] str)
|
||||
{
|
||||
usize l = conv::utf8_codepoints(str);
|
||||
uint prec = this.prec;
|
||||
if (this.flags.precision && l < prec) l = prec;
|
||||
this.right_adjust(' ')?;
|
||||
usize index = 0;
|
||||
usize chars = str.len;
|
||||
char* ptr = str.ptr;
|
||||
while (index < chars)
|
||||
{
|
||||
char c = ptr[index];
|
||||
// Break if we have precision set and we ran out...
|
||||
if (c & 0xC0 != 0x80 && this.flags.precision && !prec--) break;
|
||||
this.out(c)?;
|
||||
index++;
|
||||
}
|
||||
return this.left_adjust(l);
|
||||
}
|
||||
|
||||
|
||||
union ConvUnion
|
||||
{
|
||||
ulong u;
|
||||
double f;
|
||||
}
|
||||
|
||||
private fn void! Formatter.etoa(Formatter* this, FloatType value)
|
||||
{
|
||||
// check for NaN and special values
|
||||
if (value != value || value < FloatType.min || value > FloatType.max)
|
||||
{
|
||||
return this.ftoa(value);
|
||||
}
|
||||
|
||||
// determine the sign
|
||||
bool negative = value < 0;
|
||||
if (negative) value = -value;
|
||||
|
||||
// default precision
|
||||
if (!this.flags.precision)
|
||||
{
|
||||
this.prec = PRINTF_DEFAULT_FLOAT_PRECISION;
|
||||
}
|
||||
|
||||
// determine the decimal exponent
|
||||
// based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c)
|
||||
ConvUnion conv;
|
||||
|
||||
conv.f = (double)value;
|
||||
int exp2 = (int)(conv.u >> 52 & 0x7FF) - 1023; // effectively log2
|
||||
conv.u = (conv.u & (1u64 << 52 - 1)) | (1023u64 << 52); // drop the exponent so conv.F is now in [1,2)
|
||||
// now approximate log10 from the log2 integer part and an expansion of ln around 1.5
|
||||
int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.f - 1.5) * 0.289529654602168);
|
||||
// now we want to compute 10^expval but we want to be sure it won't overflow
|
||||
exp2 = (int)(expval * 3.321928094887362 + 0.5);
|
||||
double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453;
|
||||
double z2 = z * z;
|
||||
conv.u = (ulong)(exp2 + 1023) << 52;
|
||||
// compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex
|
||||
conv.f *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14)))));
|
||||
// correct for rounding errors
|
||||
if (value < conv.f)
|
||||
{
|
||||
expval--;
|
||||
conv.f /= 10;
|
||||
}
|
||||
|
||||
// the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters
|
||||
uint minwidth = ((expval < 100) && (expval > -100)) ? 4 : 5;
|
||||
|
||||
// in "%g" mode, "prec" is the number of *significant figures* not decimals
|
||||
if (this.flags.adapt_exp)
|
||||
{
|
||||
// do we want to fall-back to "%f" mode?
|
||||
if (value >= 1e-4 && value < 1e6)
|
||||
{
|
||||
this.prec = this.prec > expval ? this.prec - expval - 1 : 0;
|
||||
this.flags.precision = true; // make sure ftoa respects precision
|
||||
// no characters in exponent
|
||||
minwidth = 0;
|
||||
expval = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we use one sigfig for the whole part
|
||||
if (this.prec > 0 && this.flags.precision) this.prec--;
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust width
|
||||
uint fwidth = this.width > minwidth ? this.width - minwidth : 0;
|
||||
|
||||
// if we're padding on the right, DON'T pad the floating part
|
||||
if (this.flags.left && minwidth) fwidth = 0;
|
||||
|
||||
// rescale the float value
|
||||
if (expval) value /= conv.f;
|
||||
|
||||
// output the floating part
|
||||
usize start_idx = this.idx;
|
||||
PrintFlags old = this.flags;
|
||||
this.flags.adapt_exp = false;
|
||||
this.width = fwidth;
|
||||
this.ftoa(negative ? -value : value)?;
|
||||
this.flags = old;
|
||||
|
||||
// output the exponent part
|
||||
if (minwidth)
|
||||
{
|
||||
// output the exponential symbol
|
||||
this.out(this.flags.uppercase ? 'E' : 'e')?;
|
||||
// output the exponent value
|
||||
this.flags = { .zeropad = true, .plus = true };
|
||||
this.width = minwidth - 1;
|
||||
this.prec = 0;
|
||||
this.ntoa((NtoaType)(expval < 0 ? -expval : expval), expval < 0, 10)?;
|
||||
this.flags = old;
|
||||
// might need to right-pad spaces
|
||||
this.left_adjust(this.idx - start_idx)?;
|
||||
}
|
||||
}
|
||||
|
||||
// internal ftoa for fixed decimal floating point
|
||||
private fn void! Formatter.ftoa(Formatter* this, FloatType value)
|
||||
{
|
||||
char[PRINTF_FTOA_BUFFER_SIZE] buf = void;
|
||||
usize len = 0;
|
||||
const FloatType[] POW10 = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
|
||||
FloatType diff = 0.0;
|
||||
|
||||
// powers of 10
|
||||
|
||||
// test for special values
|
||||
if (value != value)
|
||||
{
|
||||
return this.out_reverse("nan");
|
||||
}
|
||||
if (value < -FloatType.max)
|
||||
{
|
||||
return this.out_reverse("fni-");
|
||||
}
|
||||
if (value > FloatType.max)
|
||||
{
|
||||
if (this.flags.plus)
|
||||
{
|
||||
return this.out_reverse("fni+");
|
||||
}
|
||||
return this.out_reverse("fni");
|
||||
}
|
||||
|
||||
// test for very large values
|
||||
// standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
|
||||
if (value > PRINTF_MAX_FLOAT || value < -PRINTF_MAX_FLOAT)
|
||||
{
|
||||
return this.etoa(value);
|
||||
}
|
||||
|
||||
// test for negative
|
||||
bool negative = value < 0;
|
||||
if (negative) value = 0 - value;
|
||||
|
||||
// set default precision, if not set explicitly
|
||||
if (!this.flags.precision) this.prec = PRINTF_DEFAULT_FLOAT_PRECISION;
|
||||
|
||||
// limit precision to 9, cause a prec >= 10 can lead to overflow errors
|
||||
while (this.prec > 9)
|
||||
{
|
||||
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
buf[len++] = '0';
|
||||
this.prec--;
|
||||
}
|
||||
|
||||
// Safe due to 1e9 limit.
|
||||
int whole = (int)value;
|
||||
FloatType tmp = (value - whole) * POW10[this.prec];
|
||||
ulong frac = (ulong)tmp;
|
||||
diff = tmp - frac;
|
||||
|
||||
switch (true)
|
||||
{
|
||||
case diff > 0.5:
|
||||
++frac;
|
||||
// handle rollover, e.g. case 0.99 with prec 1 is 1.0
|
||||
if (frac >= POW10[this.prec])
|
||||
{
|
||||
frac = 0;
|
||||
++whole;
|
||||
}
|
||||
case diff < 0.5:
|
||||
break;
|
||||
case !frac && (frac & 1):
|
||||
// if halfway, round up if odd OR if last digit is 0
|
||||
++frac;
|
||||
}
|
||||
if (!this.prec)
|
||||
{
|
||||
diff = value - (FloatType)whole;
|
||||
if ((!(diff < 0.5) || diff > 0.5) && (whole & 1))
|
||||
{
|
||||
// exactly 0.5 and ODD, then round up
|
||||
// 1.5 -> 2, but 2.5 -> 2
|
||||
++whole;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint count = this.prec;
|
||||
// now do fractional part, as an unsigned number
|
||||
do
|
||||
{
|
||||
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
--count;
|
||||
buf[len++] = (char)(48 + (frac % 10));
|
||||
}
|
||||
while (frac /= 10);
|
||||
// add extra 0s
|
||||
while (count-- > 0)
|
||||
{
|
||||
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
buf[len++] = '0';
|
||||
}
|
||||
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
// add decimal
|
||||
buf[len++] = '.';
|
||||
}
|
||||
|
||||
// do whole part, number is reversed
|
||||
do
|
||||
{
|
||||
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
buf[len++] = (char)(48 + (whole % 10));
|
||||
}
|
||||
while (whole /= 10);
|
||||
|
||||
// pad leading zeros
|
||||
if (!this.flags.left && this.flags.zeropad)
|
||||
{
|
||||
if (this.width && (negative || this.flags.plus || this.flags.space)) this.width--;
|
||||
while (len < this.width)
|
||||
{
|
||||
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
buf[len++] = '0';
|
||||
}
|
||||
}
|
||||
|
||||
char next = {|
|
||||
if (negative) return '-';
|
||||
if (this.flags.plus) return '+';
|
||||
if (this.flags.space) return ' ';
|
||||
return 0;
|
||||
|};
|
||||
if (next)
|
||||
{
|
||||
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
buf[len++] = next;
|
||||
}
|
||||
return this.out_reverse(buf[:len]);
|
||||
}
|
||||
|
||||
private fn void! Formatter.ntoa(Formatter* this, NtoaType value, bool negative, uint base)
|
||||
{
|
||||
char[PRINTF_NTOA_BUFFER_SIZE] buf = void;
|
||||
usize len = 0;
|
||||
|
||||
// no hash for 0 values
|
||||
if (!value) this.flags.hash = false;
|
||||
|
||||
// write if precision != 0 or value is != 0
|
||||
if (!this.flags.precision || value)
|
||||
{
|
||||
char past_10 = (this.flags.uppercase ? 'A' : 'a') - 10;
|
||||
do
|
||||
{
|
||||
if (len >= PRINTF_NTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
char digit = (char)(value % base);
|
||||
buf[len++] = digit + (digit < 10 ? '0' : past_10);
|
||||
value /= base;
|
||||
}
|
||||
while (value);
|
||||
}
|
||||
return this.ntoa_format(buf[:PRINTF_NTOA_BUFFER_SIZE], len, negative, base);
|
||||
}
|
||||
|
||||
private fn void! Formatter.ntoa_format(Formatter* this, char[] buf, usize len, bool negative, uint base)
|
||||
{
|
||||
// pad leading zeros
|
||||
if (!this.flags.left)
|
||||
{
|
||||
if (this.width && this.flags.zeropad && (negative || this.flags.plus || this.flags.space)) this.width--;
|
||||
while (len < this.prec)
|
||||
{
|
||||
if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
buf[len++] = '0';
|
||||
}
|
||||
while (this.flags.zeropad && len < this.width)
|
||||
{
|
||||
if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
buf[len++] = '0';
|
||||
}
|
||||
}
|
||||
|
||||
// handle hash
|
||||
if (this.flags.hash && base != 10)
|
||||
{
|
||||
if (!this.flags.precision && len && len == this.prec && len == this.width)
|
||||
{
|
||||
len--;
|
||||
if (len) len--;
|
||||
}
|
||||
if (base != 10)
|
||||
{
|
||||
if (len + 1 >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
switch (base)
|
||||
{
|
||||
case 16:
|
||||
buf[len++] = this.flags.uppercase ? 'X' : 'x';
|
||||
case 8:
|
||||
buf[len++] = this.flags.uppercase ? 'O' : 'o';
|
||||
case 2:
|
||||
buf[len++] = this.flags.uppercase ? 'B' : 'b';
|
||||
default:
|
||||
unreachable();
|
||||
}
|
||||
buf[len++] = '0';
|
||||
}
|
||||
}
|
||||
|
||||
switch (true)
|
||||
{
|
||||
case negative:
|
||||
if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
buf[len++] = '-';
|
||||
case this.flags.plus:
|
||||
if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
buf[len++] = '+';
|
||||
case this.flags.space:
|
||||
if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
|
||||
buf[len++] = ' ';
|
||||
}
|
||||
if (!len) return;
|
||||
return this.out_reverse(buf[:len]);
|
||||
}
|
||||
|
||||
$if (env::I128_SUPPORT):
|
||||
define NtoaType = uint128;
|
||||
$else:
|
||||
define NtoaType = ulong;
|
||||
$endif;
|
||||
|
||||
private fn void! Formatter.ntoa_variant(Formatter* this, variant arg, uint base)
|
||||
{
|
||||
bool is_neg;
|
||||
NtoaType val = int_from_variant(arg, &is_neg);
|
||||
return this.ntoa(val, is_neg, base) @inline;
|
||||
}
|
||||
|
||||
private fn void! Formatter.out_char(Formatter* this, variant arg)
|
||||
{
|
||||
uint l = 1;
|
||||
// pre padding
|
||||
this.right_adjust(l)?;
|
||||
// char output
|
||||
Char32 c = types::variant_to_int(arg, uint) ?? 0xFFFD;
|
||||
switch (true)
|
||||
{
|
||||
case c < 0x7f:
|
||||
this.out((char)c)?;
|
||||
case c < 0x7ff:
|
||||
this.out((char)(0xC0 | c >> 6))?;
|
||||
this.out((char)(0x80 | (c & 0x3F)))?;
|
||||
case c < 0xffff:
|
||||
this.out((char)(0xE0 | c >> 12))?;
|
||||
this.out((char)(0x80 | (c >> 6 & 0x3F)))?;
|
||||
this.out((char)(0x80 | (c & 0x3F)))?;
|
||||
default:
|
||||
this.out((char)(0xF0 | c >> 18))?;
|
||||
this.out((char)(0x80 | (c >> 12 & 0x3F)))?;
|
||||
this.out((char)(0x80 | (c >> 6 & 0x3F)))?;
|
||||
this.out((char)(0x80 | (c & 0x3F)))?;
|
||||
}
|
||||
return this.left_adjust(l);
|
||||
}
|
||||
|
||||
|
||||
private fn void! Formatter.out_reverse(Formatter* this, char[] buf)
|
||||
{
|
||||
usize buffer_start_idx = this.idx;
|
||||
usize len = buf.len;
|
||||
// pad spaces up to given width
|
||||
if (!this.flags.left && !this.flags.zeropad)
|
||||
{
|
||||
for (usize i = len; i < this.width; i++)
|
||||
{
|
||||
this.out(' ')?;
|
||||
}
|
||||
}
|
||||
// reverse string
|
||||
while (len) this.out(buf[--len])?;
|
||||
|
||||
// append pad spaces up to given width
|
||||
return this.left_adjust(this.idx - buffer_start_idx);
|
||||
}
|
||||
|
||||
private fn void! printf_advance_format(usize format_len, usize *index_ptr) @inline
|
||||
{
|
||||
usize val = ++(*index_ptr);
|
||||
if (val >= format_len) return FormattingFault.UNTERMINATED_FORMAT!;
|
||||
}
|
||||
|
||||
private fn variant! next_variant(variant* args_ptr, usize args_len, usize* arg_index_ptr) @inline
|
||||
{
|
||||
if (*arg_index_ptr >= args_len) return FormattingFault.MISSING_ARG!;
|
||||
return args_ptr[(*arg_index_ptr)++];
|
||||
}
|
||||
|
||||
private fn int! printf_parse_format_field(variant* args_ptr, usize args_len, usize* args_index_ptr, char* format_ptr, usize format_len, usize* index_ptr) @inline
|
||||
{
|
||||
char c = format_ptr[*index_ptr];
|
||||
if (c >= '0' && c <= '9') return simple_atoi(format_ptr, format_len, index_ptr);
|
||||
if (c != '*') return 0;
|
||||
printf_advance_format(format_len, index_ptr)?;
|
||||
variant val = next_variant(args_ptr, args_len, args_index_ptr)?;
|
||||
if (!val.type.kind.is_int()) return FormattingFault.INVALID_WIDTH_ARG!;
|
||||
uint! intval = types::variant_to_int(val, int);
|
||||
if (catch intval) return FormattingFault.INVALID_WIDTH_ARG!;
|
||||
return intval;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -642,6 +642,7 @@ void llvm_emit_xxlizer(GenContext *c, Decl *decl)
|
||||
scratch_buffer_clear();
|
||||
scratch_buffer_printf(is_finalizer ? ".static_finalize.%u" : ".static_initialize.%u", vec_size(*array_ref));
|
||||
LLVMValueRef function = LLVMAddFunction(c->module, scratch_buffer_to_string(), initializer_type);
|
||||
LLVMSetLinkage(function, LLVMInternalLinkage);
|
||||
if (llvm_use_debug(c))
|
||||
{
|
||||
uint32_t row = decl->span.row;
|
||||
|
||||
@@ -1761,6 +1761,7 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s
|
||||
call_expr->type = type_add_optional(sum_returns, failable);
|
||||
}
|
||||
|
||||
assert(call_expr->type);
|
||||
if (call_expr->call_expr.result_unused)
|
||||
{
|
||||
Type *type = call_expr->type;
|
||||
@@ -3275,6 +3276,7 @@ CHECK_DEEPER:
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(member->type);
|
||||
if (member->decl_kind == DECL_VAR)
|
||||
{
|
||||
if (member->var.kind == VARDECL_BITMEMBER)
|
||||
|
||||
@@ -404,10 +404,6 @@ void sema_analysis_pass_decls(Module *module)
|
||||
{
|
||||
sema_analyse_decl(&context, unit->generic_defines[i]);
|
||||
}
|
||||
VECEACH(unit->xxlizers, i)
|
||||
{
|
||||
sema_analyse_decl(&context, unit->xxlizers[i]);
|
||||
}
|
||||
sema_context_destroy(&context);
|
||||
}
|
||||
DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found);
|
||||
@@ -417,11 +413,16 @@ void sema_analysis_pass_functions(Module *module)
|
||||
{
|
||||
DEBUG_LOG("Pass: Function analysis %s", module->name->module);
|
||||
|
||||
|
||||
VECEACH(module->units, index)
|
||||
{
|
||||
CompilationUnit *unit = module->units[index];
|
||||
SemaContext context;
|
||||
sema_context_init(&context, unit);
|
||||
VECEACH(unit->xxlizers, i)
|
||||
{
|
||||
sema_analyse_decl(&context, unit->xxlizers[i]);
|
||||
}
|
||||
VECEACH(unit->methods, i)
|
||||
{
|
||||
analyse_func_body(&context, unit->methods[i]);
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.3.65"
|
||||
#define COMPILER_VERSION "0.3.66"
|
||||
@@ -34,7 +34,7 @@ static finalize
|
||||
@llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 300, void ()* @.static_initialize.0, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @.static_initialize.1, i8* null }, { i32, void ()*, i8* } { i32 200, void ()* @.static_initialize.2, i8* null }]
|
||||
@llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @.static_finalize.0, i8* null }]
|
||||
|
||||
define void @.static_initialize.0() {
|
||||
define internal void @.static_initialize.0() {
|
||||
entry:
|
||||
call void @puts(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i32 0, i32 0))
|
||||
ret void
|
||||
@@ -43,19 +43,19 @@ entry:
|
||||
; Function Attrs: nounwind
|
||||
declare void @puts(i8*) #0
|
||||
|
||||
define void @.static_initialize.1() {
|
||||
define internal void @.static_initialize.1() {
|
||||
entry:
|
||||
call void @puts(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.1, i32 0, i32 0))
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @.static_initialize.2() {
|
||||
define internal void @.static_initialize.2() {
|
||||
entry:
|
||||
call void @puts(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.2, i32 0, i32 0))
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @.static_finalize.0() {
|
||||
define internal void @.static_finalize.0() {
|
||||
entry:
|
||||
call void @puts(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.3, i32 0, i32 0))
|
||||
ret void
|
||||
|
||||
@@ -18,7 +18,7 @@ fn char[] Foo.to_string(Foo* foo, Allocator* allocator = mem::current_allocator(
|
||||
|
||||
static initialize
|
||||
{
|
||||
io::printf_register_to_string(Foo);
|
||||
io::formatter_register_type(Foo);
|
||||
}
|
||||
|
||||
fn void main()
|
||||
@@ -58,9 +58,19 @@ fn void main()
|
||||
|
||||
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @.static_initialize.0, i8* null }]
|
||||
|
||||
define void @.static_initialize.0() {
|
||||
define internal void @.static_initialize.0() {
|
||||
entry:
|
||||
call void @std_io_printf_register(i64 ptrtoint (%.introspect* @"ct$test_Foo" to i64), { i8*, i64 } (i8*, %Allocator*)* bitcast ({ i8*, i64 } (%Foo*, %Allocator*)* @test_Foo_to_string to { i8*, i64 } (i8*, %Allocator*)*))
|
||||
%0 = load i64, i64* getelementptr inbounds (%HashMap, %HashMap* @std_io_tostring_functions, i32 0, i32 0, i32 1), align 8
|
||||
%not = icmp eq i64 %0, 0
|
||||
br i1 %not, label %if.then, label %if.exit
|
||||
|
||||
if.then: ; preds = %entry
|
||||
%1 = load %Allocator*, %Allocator** @std_core_mem_thread_allocator, align 8
|
||||
call void @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_init"(%HashMap* @std_io_tostring_functions, i32 512, float 7.500000e-01, %Allocator* %1)
|
||||
br label %if.exit
|
||||
|
||||
if.exit: ; preds = %if.then, %entry
|
||||
%2 = call i8 @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_set"(%HashMap* @std_io_tostring_functions, i64 ptrtoint (%.introspect* @"ct$test_Foo" to i64), { i8*, i64 } (i8*, %Allocator*)* bitcast ({ i8*, i64 } (%Foo*, %Allocator*)* @test_Foo_to_string to { i8*, i64 } (i8*, %Allocator*)*))
|
||||
ret void
|
||||
}
|
||||
|
||||
@@ -125,7 +135,7 @@ voiderr: ; preds = %after_check, %entry
|
||||
; Function Attrs: nounwind
|
||||
define void @test_main() #0 {
|
||||
entry:
|
||||
%map = alloca %HashMap, align 8
|
||||
%map = alloca %HashMap.0, align 8
|
||||
%retparam = alloca i64, align 8
|
||||
%taddr = alloca %"char[]", align 8
|
||||
%vararg = alloca %"variant[]", align 8
|
||||
@@ -161,7 +171,7 @@ entry:
|
||||
%vararg75 = alloca %"variant[]", align 8
|
||||
%varargslots76 = alloca [1 x %variant], align 16
|
||||
%result = alloca %"Foo[]", align 8
|
||||
%map2 = alloca %HashMap.0, align 8
|
||||
%map2 = alloca %HashMap.3, align 8
|
||||
%retparam82 = alloca i64, align 8
|
||||
%taddr83 = alloca %"char[]", align 8
|
||||
%vararg86 = alloca %"variant[]", align 8
|
||||
@@ -186,7 +196,7 @@ entry:
|
||||
%error_var = alloca i64, align 8
|
||||
%retparam130 = alloca %TempAllocator*, align 8
|
||||
%mark = alloca i64, align 8
|
||||
%map3 = alloca %HashMap.0, align 8
|
||||
%map3 = alloca %HashMap.3, align 8
|
||||
%error_var135 = alloca i64, align 8
|
||||
%retparam136 = alloca %TempAllocator*, align 8
|
||||
%retparam143 = alloca i64, align 8
|
||||
@@ -194,17 +204,17 @@ entry:
|
||||
%vararg147 = alloca %"variant[]", align 8
|
||||
%varargslots148 = alloca [1 x %variant], align 16
|
||||
%result149 = alloca %"int[]", align 8
|
||||
%0 = bitcast %HashMap* %map to i8*
|
||||
%0 = bitcast %HashMap.0* %map to i8*
|
||||
call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 40, i1 false)
|
||||
%1 = load %Allocator*, %Allocator** @std_core_mem_thread_allocator, align 8
|
||||
call void @"std_map$$int.test_Foo_HashMap_init"(%HashMap* %map, i32 16, float 7.500000e-01, %Allocator* %1)
|
||||
call void @"std_map$$int.test_Foo_HashMap_init"(%HashMap.0* %map, i32 16, float 7.500000e-01, %Allocator* %1)
|
||||
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0), i64 12 }, %"char[]"* %taddr, align 8
|
||||
%2 = bitcast %"char[]"* %taddr to { i8*, i64 }*
|
||||
%3 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %2, i32 0, i32 0
|
||||
%lo = load i8*, i8** %3, align 8
|
||||
%4 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %2, i32 0, i32 1
|
||||
%hi = load i64, i64* %4, align 8
|
||||
%5 = getelementptr inbounds %HashMap, %HashMap* %map, i32 0, i32 2
|
||||
%5 = getelementptr inbounds %HashMap.0, %HashMap.0* %map, i32 0, i32 2
|
||||
%6 = bitcast i32* %5 to i8*
|
||||
%7 = insertvalue %variant undef, i8* %6, 0
|
||||
%8 = insertvalue %variant %7, i64 ptrtoint (%.introspect* @"ct$uint" to i64), 1
|
||||
@@ -237,14 +247,14 @@ voiderr: ; preds = %after_check, %entry
|
||||
%lo3 = load i64, i64* %20, align 8
|
||||
%21 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %19, i32 0, i32 1
|
||||
%hi4 = load i8*, i8** %21, align 8
|
||||
%22 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap* %map, i32 1, i64 %lo3, i8* %hi4)
|
||||
%22 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap.0* %map, i32 1, i64 %lo3, i8* %hi4)
|
||||
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0), i64 12 }, %"char[]"* %taddr6, align 8
|
||||
%23 = bitcast %"char[]"* %taddr6 to { i8*, i64 }*
|
||||
%24 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %23, i32 0, i32 0
|
||||
%lo7 = load i8*, i8** %24, align 8
|
||||
%25 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %23, i32 0, i32 1
|
||||
%hi8 = load i64, i64* %25, align 8
|
||||
%26 = getelementptr inbounds %HashMap, %HashMap* %map, i32 0, i32 2
|
||||
%26 = getelementptr inbounds %HashMap.0, %HashMap.0* %map, i32 0, i32 2
|
||||
%27 = bitcast i32* %26 to i8*
|
||||
%28 = insertvalue %variant undef, i8* %27, 0
|
||||
%29 = insertvalue %variant %28, i64 ptrtoint (%.introspect* @"ct$uint" to i64), 1
|
||||
@@ -277,14 +287,14 @@ voiderr15: ; preds = %after_check14, %voi
|
||||
%lo17 = load i64, i64* %41, align 8
|
||||
%42 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %40, i32 0, i32 1
|
||||
%hi18 = load i8*, i8** %42, align 8
|
||||
%43 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap* %map, i32 1, i64 %lo17, i8* %hi18)
|
||||
%43 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap.0* %map, i32 1, i64 %lo17, i8* %hi18)
|
||||
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i32 0, i32 0), i64 12 }, %"char[]"* %taddr20, align 8
|
||||
%44 = bitcast %"char[]"* %taddr20 to { i8*, i64 }*
|
||||
%45 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %44, i32 0, i32 0
|
||||
%lo21 = load i8*, i8** %45, align 8
|
||||
%46 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %44, i32 0, i32 1
|
||||
%hi22 = load i64, i64* %46, align 8
|
||||
%47 = getelementptr inbounds %HashMap, %HashMap* %map, i32 0, i32 2
|
||||
%47 = getelementptr inbounds %HashMap.0, %HashMap.0* %map, i32 0, i32 2
|
||||
%48 = bitcast i32* %47 to i8*
|
||||
%49 = insertvalue %variant undef, i8* %48, 0
|
||||
%50 = insertvalue %variant %49, i64 ptrtoint (%.introspect* @"ct$uint" to i64), 1
|
||||
@@ -314,7 +324,7 @@ voiderr29: ; preds = %after_check28, %voi
|
||||
%lo32 = load i8*, i8** %60, align 8
|
||||
%61 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %59, i32 0, i32 1
|
||||
%hi33 = load i64, i64* %61, align 8
|
||||
%62 = call i64 @"std_map$$int.test_Foo_HashMap_get"(%Foo* %retparam36, %HashMap* %map, i32 1)
|
||||
%62 = call i64 @"std_map$$int.test_Foo_HashMap_get"(%Foo* %retparam36, %HashMap.0* %map, i32 1)
|
||||
%not_err37 = icmp eq i64 %62, 0
|
||||
br i1 %not_err37, label %after_check38, label %voiderr43
|
||||
|
||||
@@ -349,7 +359,7 @@ voiderr43: ; preds = %after_check42, %aft
|
||||
%lo46 = load i8*, i8** %76, align 8
|
||||
%77 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %75, i32 0, i32 1
|
||||
%hi47 = load i64, i64* %77, align 8
|
||||
%78 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(%HashMap* %map, i32 1)
|
||||
%78 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(%HashMap.0* %map, i32 1)
|
||||
store i8 %78, i8* %taddr50, align 1
|
||||
%79 = insertvalue %variant undef, i8* %taddr50, 0
|
||||
%80 = insertvalue %variant %79, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
|
||||
@@ -379,7 +389,7 @@ voiderr55: ; preds = %after_check54, %voi
|
||||
%lo58 = load i8*, i8** %90, align 8
|
||||
%91 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %89, i32 0, i32 1
|
||||
%hi59 = load i64, i64* %91, align 8
|
||||
%92 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(%HashMap* %map, i32 2)
|
||||
%92 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(%HashMap.0* %map, i32 2)
|
||||
store i8 %92, i8* %taddr62, align 1
|
||||
%93 = insertvalue %variant undef, i8* %taddr62, 0
|
||||
%94 = insertvalue %variant %93, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
|
||||
@@ -412,14 +422,14 @@ voiderr67: ; preds = %after_check66, %voi
|
||||
%lo69 = load i64, i64* %106, align 8
|
||||
%107 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %105, i32 0, i32 1
|
||||
%hi70 = load i8*, i8** %107, align 8
|
||||
%108 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap* %map, i32 7, i64 %lo69, i8* %hi70)
|
||||
%108 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap.0* %map, i32 7, i64 %lo69, i8* %hi70)
|
||||
store %"char[]" { i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.6, i32 0, i32 0), i64 10 }, %"char[]"* %taddr72, align 8
|
||||
%109 = bitcast %"char[]"* %taddr72 to { i8*, i64 }*
|
||||
%110 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %109, i32 0, i32 0
|
||||
%lo73 = load i8*, i8** %110, align 8
|
||||
%111 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %109, i32 0, i32 1
|
||||
%hi74 = load i64, i64* %111, align 8
|
||||
%112 = call { i8*, i64 } @"std_map$$int.test_Foo_HashMap_value_list"(%HashMap* %map, %Allocator* null)
|
||||
%112 = call { i8*, i64 } @"std_map$$int.test_Foo_HashMap_value_list"(%HashMap.0* %map, %Allocator* null)
|
||||
%113 = bitcast %"Foo[]"* %result to { i8*, i64 }*
|
||||
store { i8*, i64 } %112, { i8*, i64 }* %113, align 8
|
||||
%114 = bitcast %"Foo[]"* %result to i8*
|
||||
@@ -445,18 +455,18 @@ after_check80: ; preds = %voiderr67
|
||||
br label %voiderr81
|
||||
|
||||
voiderr81: ; preds = %after_check80, %voiderr67
|
||||
%125 = bitcast %HashMap.0* %map2 to i8*
|
||||
%125 = bitcast %HashMap.3* %map2 to i8*
|
||||
call void @llvm.memset.p0i8.i64(i8* align 8 %125, i8 0, i64 40, i1 false)
|
||||
%126 = load %Allocator*, %Allocator** @std_core_mem_thread_allocator, align 8
|
||||
call void @"std_map$$int.double_HashMap_init"(%HashMap.0* %map2, i32 16, float 7.500000e-01, %Allocator* %126)
|
||||
%127 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.0* %map2, i32 4, double 1.300000e+00)
|
||||
call void @"std_map$$int.double_HashMap_init"(%HashMap.3* %map2, i32 16, float 7.500000e-01, %Allocator* %126)
|
||||
%127 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.3* %map2, i32 4, double 1.300000e+00)
|
||||
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.7, i32 0, i32 0), i64 12 }, %"char[]"* %taddr83, align 8
|
||||
%128 = bitcast %"char[]"* %taddr83 to { i8*, i64 }*
|
||||
%129 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %128, i32 0, i32 0
|
||||
%lo84 = load i8*, i8** %129, align 8
|
||||
%130 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %128, i32 0, i32 1
|
||||
%hi85 = load i64, i64* %130, align 8
|
||||
%131 = call i8 @"std_map$$int.double_HashMap_has_value"(%HashMap.0* %map2, double 1.300000e+00)
|
||||
%131 = call i8 @"std_map$$int.double_HashMap_has_value"(%HashMap.3* %map2, double 1.300000e+00)
|
||||
store i8 %131, i8* %taddr88, align 1
|
||||
%132 = insertvalue %variant undef, i8* %taddr88, 0
|
||||
%133 = insertvalue %variant %132, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
|
||||
@@ -486,7 +496,7 @@ voiderr93: ; preds = %after_check92, %voi
|
||||
%lo96 = load i8*, i8** %143, align 8
|
||||
%144 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %142, i32 0, i32 1
|
||||
%hi97 = load i64, i64* %144, align 8
|
||||
%145 = call i8 @"std_map$$int.double_HashMap_has_value"(%HashMap.0* %map2, double 1.200000e+00)
|
||||
%145 = call i8 @"std_map$$int.double_HashMap_has_value"(%HashMap.3* %map2, double 1.200000e+00)
|
||||
store i8 %145, i8* %taddr100, align 1
|
||||
%146 = insertvalue %variant undef, i8* %taddr100, 0
|
||||
%147 = insertvalue %variant %146, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
|
||||
@@ -510,14 +520,14 @@ after_check104: ; preds = %voiderr93
|
||||
br label %voiderr105
|
||||
|
||||
voiderr105: ; preds = %after_check104, %voiderr93
|
||||
%156 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.0* %map2, i32 100, double 3.400000e+00)
|
||||
%156 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.3* %map2, i32 100, double 3.400000e+00)
|
||||
store %"char[]" { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.9, i32 0, i32 0), i64 2 }, %"char[]"* %taddr107, align 8
|
||||
%157 = bitcast %"char[]"* %taddr107 to { i8*, i64 }*
|
||||
%158 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %157, i32 0, i32 0
|
||||
%lo108 = load i8*, i8** %158, align 8
|
||||
%159 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %157, i32 0, i32 1
|
||||
%hi109 = load i64, i64* %159, align 8
|
||||
%160 = call { i8*, i64 } @"std_map$$int.double_HashMap_key_list"(%HashMap.0* %map2, %Allocator* null)
|
||||
%160 = call { i8*, i64 } @"std_map$$int.double_HashMap_key_list"(%HashMap.3* %map2, %Allocator* null)
|
||||
%161 = bitcast %"int[]"* %result112 to { i8*, i64 }*
|
||||
store { i8*, i64 } %160, { i8*, i64 }* %161, align 8
|
||||
%162 = bitcast %"int[]"* %result112 to i8*
|
||||
@@ -549,7 +559,7 @@ voiderr117: ; preds = %after_check116, %vo
|
||||
%lo120 = load i8*, i8** %174, align 8
|
||||
%175 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %173, i32 0, i32 1
|
||||
%hi121 = load i64, i64* %175, align 8
|
||||
%176 = call { i8*, i64 } @"std_map$$int.double_HashMap_value_list"(%HashMap.0* %map2, %Allocator* null)
|
||||
%176 = call { i8*, i64 } @"std_map$$int.double_HashMap_value_list"(%HashMap.3* %map2, %Allocator* null)
|
||||
%177 = bitcast %"double[]"* %result124 to { i8*, i64 }*
|
||||
store { i8*, i64 } %176, { i8*, i64 }* %177, align 8
|
||||
%178 = bitcast %"double[]"* %result124 to i8*
|
||||
@@ -607,7 +617,7 @@ if.exit: ; preds = %noerr_block, %voide
|
||||
%194 = getelementptr inbounds %TempAllocator, %TempAllocator* %193, i32 0, i32 3
|
||||
%195 = load i64, i64* %194, align 8
|
||||
store i64 %195, i64* %mark, align 8
|
||||
%196 = bitcast %HashMap.0* %map3 to i8*
|
||||
%196 = bitcast %HashMap.3* %map3 to i8*
|
||||
call void @llvm.memset.p0i8.i64(i8* align 8 %196, i8 0, i64 40, i1 false)
|
||||
%197 = load %TempAllocator*, %TempAllocator** @std_core_mem_thread_temp_allocator, align 8
|
||||
%not133 = icmp eq %TempAllocator* %197, null
|
||||
@@ -637,16 +647,16 @@ noerr_block141: ; preds = %after_check139
|
||||
if.exit142: ; preds = %noerr_block141, %if.exit
|
||||
%200 = load %TempAllocator*, %TempAllocator** @std_core_mem_thread_temp_allocator, align 8
|
||||
%ptrptr = bitcast %TempAllocator* %200 to %Allocator*
|
||||
call void @"std_map$$int.double_HashMap_init"(%HashMap.0* %map3, i32 16, float 7.500000e-01, %Allocator* %ptrptr)
|
||||
%201 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.0* %map3, i32 5, double 3.200000e+00)
|
||||
%202 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.0* %map3, i32 7, double 5.200000e+00)
|
||||
call void @"std_map$$int.double_HashMap_init"(%HashMap.3* %map3, i32 16, float 7.500000e-01, %Allocator* %ptrptr)
|
||||
%201 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.3* %map3, i32 5, double 3.200000e+00)
|
||||
%202 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.3* %map3, i32 7, double 5.200000e+00)
|
||||
store %"char[]" { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.16, i32 0, i32 0), i64 2 }, %"char[]"* %taddr144, align 8
|
||||
%203 = bitcast %"char[]"* %taddr144 to { i8*, i64 }*
|
||||
%204 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %203, i32 0, i32 0
|
||||
%lo145 = load i8*, i8** %204, align 8
|
||||
%205 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %203, i32 0, i32 1
|
||||
%hi146 = load i64, i64* %205, align 8
|
||||
%206 = call { i8*, i64 } @"std_map$$int.double_HashMap_key_tlist"(%HashMap.0* %map3)
|
||||
%206 = call { i8*, i64 } @"std_map$$int.double_HashMap_key_tlist"(%HashMap.3* %map3)
|
||||
%207 = bitcast %"int[]"* %result149 to { i8*, i64 }*
|
||||
store { i8*, i64 } %206, { i8*, i64 }* %207, align 8
|
||||
%208 = bitcast %"int[]"* %result149 to i8*
|
||||
|
||||
@@ -34,7 +34,7 @@ static finalize
|
||||
@llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 300, ptr @.static_initialize.0, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @.static_initialize.1, ptr null }, { i32, ptr, ptr } { i32 200, ptr @.static_initialize.2, ptr null }]
|
||||
@llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @.static_finalize.0, ptr null }]
|
||||
|
||||
define void @.static_initialize.0() {
|
||||
define internal void @.static_initialize.0() {
|
||||
entry:
|
||||
call void @puts(ptr @.str)
|
||||
ret void
|
||||
@@ -43,19 +43,19 @@ entry:
|
||||
; Function Attrs: nounwind
|
||||
declare void @puts(ptr) #0
|
||||
|
||||
define void @.static_initialize.1() {
|
||||
define internal void @.static_initialize.1() {
|
||||
entry:
|
||||
call void @puts(ptr @.str.1)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @.static_initialize.2() {
|
||||
define internal void @.static_initialize.2() {
|
||||
entry:
|
||||
call void @puts(ptr @.str.2)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @.static_finalize.0() {
|
||||
define internal void @.static_finalize.0() {
|
||||
entry:
|
||||
call void @puts(ptr @.str.3)
|
||||
ret void
|
||||
|
||||
@@ -18,7 +18,7 @@ fn char[] Foo.to_string(Foo* foo, Allocator* allocator = mem::current_allocator(
|
||||
|
||||
static initialize
|
||||
{
|
||||
io::printf_register_to_string(Foo);
|
||||
io::formatter_register_type(Foo);
|
||||
}
|
||||
|
||||
fn void main()
|
||||
@@ -54,13 +54,21 @@ fn void main()
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
|
||||
@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @.static_initialize.0, ptr null }]
|
||||
|
||||
define void @.static_initialize.0() {
|
||||
define internal void @.static_initialize.0() {
|
||||
entry:
|
||||
call void @std_io_printf_register(i64 ptrtoint (ptr @"ct$test_Foo" to i64), ptr @test_Foo_to_string)
|
||||
%0 = load i64, ptr getelementptr inbounds (%"Entry*[]", ptr @std_io_tostring_functions, i32 0, i32 1), align 8
|
||||
%not = icmp eq i64 %0, 0
|
||||
br i1 %not, label %if.then, label %if.exit
|
||||
|
||||
if.then: ; preds = %entry
|
||||
%1 = load ptr, ptr @std_core_mem_thread_allocator, align 8
|
||||
call void @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_init"(ptr @std_io_tostring_functions, i32 512, float 7.500000e-01, ptr %1)
|
||||
br label %if.exit
|
||||
|
||||
if.exit: ; preds = %if.then, %entry
|
||||
%2 = call i8 @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_set"(ptr @std_io_tostring_functions, i64 ptrtoint (ptr @"ct$test_Foo" to i64), ptr @test_Foo_to_string)
|
||||
ret void
|
||||
}
|
||||
|
||||
@@ -117,7 +125,7 @@ voiderr: ; preds = %after_check, %entry
|
||||
; Function Attrs: nounwind
|
||||
define void @test_main() #0 {
|
||||
entry:
|
||||
%map = alloca %HashMap, align 8
|
||||
%map = alloca %HashMap.0, align 8
|
||||
%retparam = alloca i64, align 8
|
||||
%taddr = alloca %"char[]", align 8
|
||||
%vararg = alloca %"variant[]", align 8
|
||||
@@ -153,7 +161,7 @@ entry:
|
||||
%vararg75 = alloca %"variant[]", align 8
|
||||
%varargslots76 = alloca [1 x %variant], align 16
|
||||
%result = alloca %"Foo[]", align 8
|
||||
%map2 = alloca %HashMap.0, align 8
|
||||
%map2 = alloca %HashMap.3, align 8
|
||||
%retparam82 = alloca i64, align 8
|
||||
%taddr83 = alloca %"char[]", align 8
|
||||
%vararg86 = alloca %"variant[]", align 8
|
||||
@@ -178,7 +186,7 @@ entry:
|
||||
%error_var = alloca i64, align 8
|
||||
%retparam130 = alloca ptr, align 8
|
||||
%mark = alloca i64, align 8
|
||||
%map3 = alloca %HashMap.0, align 8
|
||||
%map3 = alloca %HashMap.3, align 8
|
||||
%error_var135 = alloca i64, align 8
|
||||
%retparam136 = alloca ptr, align 8
|
||||
%retparam143 = alloca i64, align 8
|
||||
@@ -194,7 +202,7 @@ entry:
|
||||
%lo = load ptr, ptr %1, align 8
|
||||
%2 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 1
|
||||
%hi = load i64, ptr %2, align 8
|
||||
%3 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2
|
||||
%3 = getelementptr inbounds %HashMap.0, ptr %map, i32 0, i32 2
|
||||
%4 = insertvalue %variant undef, ptr %3, 0
|
||||
%5 = insertvalue %variant %4, i64 ptrtoint (ptr @"ct$uint" to i64), 1
|
||||
%6 = getelementptr inbounds [1 x %variant], ptr %varargslots, i64 0, i64 0
|
||||
@@ -229,7 +237,7 @@ voiderr: ; preds = %after_check, %entry
|
||||
%lo7 = load ptr, ptr %17, align 8
|
||||
%18 = getelementptr inbounds { ptr, i64 }, ptr %taddr6, i32 0, i32 1
|
||||
%hi8 = load i64, ptr %18, align 8
|
||||
%19 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2
|
||||
%19 = getelementptr inbounds %HashMap.0, ptr %map, i32 0, i32 2
|
||||
%20 = insertvalue %variant undef, ptr %19, 0
|
||||
%21 = insertvalue %variant %20, i64 ptrtoint (ptr @"ct$uint" to i64), 1
|
||||
%22 = getelementptr inbounds [1 x %variant], ptr %varargslots10, i64 0, i64 0
|
||||
@@ -264,7 +272,7 @@ voiderr15: ; preds = %after_check14, %voi
|
||||
%lo21 = load ptr, ptr %33, align 8
|
||||
%34 = getelementptr inbounds { ptr, i64 }, ptr %taddr20, i32 0, i32 1
|
||||
%hi22 = load i64, ptr %34, align 8
|
||||
%35 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2
|
||||
%35 = getelementptr inbounds %HashMap.0, ptr %map, i32 0, i32 2
|
||||
%36 = insertvalue %variant undef, ptr %35, 0
|
||||
%37 = insertvalue %variant %36, i64 ptrtoint (ptr @"ct$uint" to i64), 1
|
||||
%38 = getelementptr inbounds [1 x %variant], ptr %varargslots24, i64 0, i64 0
|
||||
|
||||
Reference in New Issue
Block a user