diff --git a/core/crypto/poly1305/poly1305.odin b/core/crypto/poly1305/poly1305.odin
index fa57c6c06..4ca4f75e1 100644
--- a/core/crypto/poly1305/poly1305.odin
+++ b/core/crypto/poly1305/poly1305.odin
@@ -9,6 +9,7 @@ package poly1305
import "core:crypto"
import field "core:crypto/_fiat/field_poly1305"
import "core:encoding/endian"
+import "core:math/bits"
import "core:mem"
// KEY_SIZE is the Poly1305 key size in bytes.
@@ -50,7 +51,7 @@ verify :: proc(tag, msg, key: []byte) -> bool {
Context :: struct {
_r: field.Tight_Field_Element,
_a: field.Tight_Field_Element,
- _s: field.Tight_Field_Element,
+ _s: [2]u64,
_buffer: [_BLOCK_SIZE]byte,
_leftover: int,
_is_initialized: bool,
@@ -66,11 +67,12 @@ init :: proc(ctx: ^Context, key: []byte) {
// r = le_bytes_to_num(key[0..15])
// r = clamp(r) (r &= 0xffffffc0ffffffc0ffffffc0fffffff)
tmp_lo := endian.unchecked_get_u64le(key[0:]) & 0x0ffffffc0fffffff
- tmp_hi := endian.unchecked_get_u64le(key[8:]) & 0xffffffc0ffffffc
+ tmp_hi := endian.unchecked_get_u64le(key[8:]) & 0x0ffffffc0ffffffc
field.fe_from_u64s(&ctx._r, tmp_lo, tmp_hi)
// s = le_bytes_to_num(key[16..31])
- field.fe_from_bytes(&ctx._s, key[16:32], 0)
+ ctx._s[0] = endian.unchecked_get_u64le(key[16:])
+ ctx._s[1] = endian.unchecked_get_u64le(key[24:])
// a = 0
field.fe_zero(&ctx._a)
@@ -138,14 +140,20 @@ final :: proc(ctx: ^Context, dst: []byte) {
_blocks(ctx, ctx._buffer[:], true)
}
- // a += s
- field.fe_add(field.fe_relax_cast(&ctx._a), &ctx._a, &ctx._s) // _a unreduced
- field.fe_carry(&ctx._a, field.fe_relax_cast(&ctx._a)) // _a reduced
-
- // return num_to_16_le_bytes(a)
+ // a += s (NOT mod p)
tmp: [32]byte = ---
field.fe_to_bytes(&tmp, &ctx._a)
- copy_slice(dst, tmp[0:16])
+
+ c: u64
+ lo := endian.unchecked_get_u64le(tmp[0:])
+ hi := endian.unchecked_get_u64le(tmp[8:])
+
+ lo, c = bits.add_u64(lo, ctx._s[0], 0)
+ hi, _ = bits.add_u64(hi, ctx._s[1], c)
+
+ // return num_to_16_le_bytes(a)
+ endian.unchecked_put_u64le(dst[0:], lo)
+ endian.unchecked_put_u64le(dst[8:], hi)
}
// reset sanitizes the Context. The Context must be re-initialized to
diff --git a/core/encoding/hxa/read.odin b/core/encoding/hxa/read.odin
index 8a8636f19..f37dc3193 100644
--- a/core/encoding/hxa/read.odin
+++ b/core/encoding/hxa/read.odin
@@ -177,7 +177,7 @@ read :: proc(data: []byte, filename := "", print_error := false, allocato
}
defer file.nodes = file.nodes[:node_count]
- for node_idx in 0.. max(Node_Type) {
diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin
index 985de6880..68d087a6e 100644
--- a/core/encoding/json/marshal.odin
+++ b/core/encoding/json/marshal.odin
@@ -246,7 +246,6 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
opt_write_end(w, opt, ']') or_return
case runtime.Type_Info_Enumerated_Array:
- index := runtime.type_info_base(info.index).variant.(runtime.Type_Info_Enum)
opt_write_start(w, opt, '[') or_return
for i in 0.. (err:
// check for string type
{
- v := any{key, info.key.id}
- ti := runtime.type_info_base(type_info_of(v.id))
- a := any{v.data, ti.id}
+ kv := any{key, info.key.id}
+ kti := runtime.type_info_base(type_info_of(kv.id))
+ ka := any{kv.data, kti.id}
name: string
- #partial switch info in ti.variant {
+ #partial switch info in kti.variant {
case runtime.Type_Info_String:
- switch s in a {
+ switch s in ka {
case string: name = s
case cstring: name = string(s)
}
@@ -336,13 +335,13 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
// check for string type
{
- v := any{key, info.key.id}
- ti := runtime.type_info_base(type_info_of(v.id))
- a := any{v.data, ti.id}
+ kv := any{key, info.key.id}
+ kti := runtime.type_info_base(type_info_of(kv.id))
+ ka := any{kv.data, kti.id}
- #partial switch info in ti.variant {
+ #partial switch info in kti.variant {
case runtime.Type_Info_String:
- switch s in a {
+ switch s in ka {
case string: name = s
case cstring: name = string(s)
}
diff --git a/core/encoding/json/unmarshal.odin b/core/encoding/json/unmarshal.odin
index 8c21098fb..edc4903a1 100644
--- a/core/encoding/json/unmarshal.odin
+++ b/core/encoding/json/unmarshal.odin
@@ -483,9 +483,9 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
mem.zero_slice(elem_backing)
- if err := unmarshal_value(p, map_backing_value); err != nil {
+ if uerr := unmarshal_value(p, map_backing_value); uerr != nil {
delete(key, p.allocator)
- return err
+ return uerr
}
key_ptr := rawptr(&key)
diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin
index 079c5b4be..ab3945ad7 100644
--- a/core/image/netpbm/netpbm.odin
+++ b/core/image/netpbm/netpbm.odin
@@ -199,8 +199,8 @@ save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context
for x in 0 ..< img.width {
i := y * img.width + x
for c in 0 ..< img.channels {
- i := i * img.channels + c
- fmt.sbprintf(&data, "%i ", pixels[i])
+ j := i * img.channels + c
+ fmt.sbprintf(&data, "%i ", pixels[j])
}
fmt.sbprint(&data, "\n")
}
@@ -213,8 +213,8 @@ save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context
for x in 0 ..< img.width {
i := y * img.width + x
for c in 0 ..< img.channels {
- i := i * img.channels + c
- fmt.sbprintf(&data, "%i ", pixels[i])
+ j := i * img.channels + c
+ fmt.sbprintf(&data, "%i ", pixels[j])
}
fmt.sbprint(&data, "\n")
}
@@ -283,7 +283,7 @@ _parse_header_pnm :: proc(data: []byte) -> (header: Header, length: int, err: Er
current_field := 0
current_value := header_fields[0]
- parse_loop: for d, i in data[SIG_LENGTH:] {
+ parse_loop: for d in data[SIG_LENGTH:] {
length += 1
// handle comments
@@ -728,4 +728,4 @@ _register :: proc() {
_ = destroy(img)
}
image.register(.NetPBM, loader, destroyer)
-}
\ No newline at end of file
+}
diff --git a/core/math/fixed/fixed.odin b/core/math/fixed/fixed.odin
index b8000a5c6..21fab5faf 100644
--- a/core/math/fixed/fixed.odin
+++ b/core/math/fixed/fixed.odin
@@ -39,7 +39,6 @@ init_from_f64 :: proc(x: ^$T/Fixed($Backing, $Fraction_Width), val: f64) {
}
init_from_parts :: proc(x: ^$T/Fixed($Backing, $Fraction_Width), integer, fraction: Backing) {
- i, f := math.modf(val)
x.i = fraction
x.i &= 1< Allocator_Error {
- if ptr == nil || allocator.procedure == nil {
- return nil
- }
- _, err := allocator.procedure(allocator.data, .Free, 0, 0, ptr, byte_count, loc)
- return err
+ return runtime.mem_free_with_size(ptr, byte_count, allocator, loc)
}
free_bytes :: proc(bytes: []byte, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
@@ -130,19 +126,19 @@ query_info :: proc(pointer: rawptr, allocator: Allocator, loc := #caller_locatio
delete_string :: proc(str: string, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
- return free_with_size(raw_data(str), len(str), allocator, loc)
+ return runtime.delete_string(str, allocator, loc)
}
delete_cstring :: proc(str: cstring, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
- return free((^byte)(str), allocator, loc)
+ return runtime.delete_cstring(str, allocator, loc)
}
delete_dynamic_array :: proc(array: $T/[dynamic]$E, loc := #caller_location) -> Allocator_Error {
- return free_with_size(raw_data(array), cap(array)*size_of(E), array.allocator, loc)
+ return runtime.delete_dynamic_array(array, loc)
}
delete_slice :: proc(array: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> Allocator_Error {
- return free_with_size(raw_data(array), len(array)*size_of(E), allocator, loc)
+ return runtime.delete_slice(array, allocator, loc)
}
delete_map :: proc(m: $T/map[$K]$V, loc := #caller_location) -> Allocator_Error {
- return runtime.map_free_dynamic(transmute(Raw_Map)m, runtime.map_info(T), loc)
+ return runtime.delete_map(m, loc)
}
@@ -161,71 +157,40 @@ new :: proc($T: typeid, allocator := context.allocator, loc := #caller_location)
}
@(require_results)
new_aligned :: proc($T: typeid, alignment: int, allocator := context.allocator, loc := #caller_location) -> (t: ^T, err: Allocator_Error) {
- data := alloc_bytes(size_of(T), alignment, allocator, loc) or_return
- t = (^T)(raw_data(data))
- return
+ return runtime.new_aligned(T, alignment, allocator, loc)
}
@(require_results)
new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_location) -> (t: ^T, err: Allocator_Error) {
- backing := alloc_bytes(size_of(T), align_of(T), allocator, loc) or_return
- t = (^T)(raw_data(backing))
- if t != nil {
- t^ = data
- return t, nil
- }
- return nil, .Out_Of_Memory
+ return runtime.new_clone(data, allocator, loc)
}
@(require_results)
make_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (slice: T, err: Allocator_Error) {
- runtime.make_slice_error_loc(loc, len)
- data := alloc_bytes(size_of(E)*len, alignment, allocator, loc) or_return
- if data == nil && size_of(E) != 0 {
- return
- }
- slice = transmute(T)Raw_Slice{raw_data(data), len}
- return
+ return runtime.make_aligned(T, len, alignment, allocator, loc)
}
@(require_results)
make_slice :: proc($T: typeid/[]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) {
- return make_aligned(T, len, align_of(E), allocator, loc)
+ return runtime.make_slice(T, len, allocator, loc)
}
@(require_results)
make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) {
- return make_dynamic_array_len_cap(T, 0, 16, allocator, loc)
+ return runtime.make_dynamic_array(T, allocator, loc)
}
@(require_results)
make_dynamic_array_len :: proc($T: typeid/[dynamic]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) {
- return make_dynamic_array_len_cap(T, len, len, allocator, loc)
+ return runtime.make_dynamic_array(T, len, allocator, loc)
}
@(require_results)
make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]$E, #any_int len: int, #any_int cap: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) {
- runtime.make_dynamic_array_error_loc(loc, len, cap)
- data := alloc_bytes(size_of(E)*cap, align_of(E), allocator, loc) or_return
- s := Raw_Dynamic_Array{raw_data(data), len, cap, allocator}
- if data == nil && size_of(E) != 0 {
- s.len, s.cap = 0, 0
- }
- array = transmute(T)s
- return
+ return runtime.make_dynamic_array(T, len, cap, allocator, loc)
}
@(require_results)
make_map :: proc($T: typeid/map[$K]$E, #any_int cap: int = 1< (m: T, err: Allocator_Error) {
- runtime.make_map_expr_error_loc(loc, cap)
- context.allocator = allocator
-
- err = reserve_map(&m, cap, loc)
- return
+ return runtime.make_map(T, cap, allocator, loc)
}
@(require_results)
make_multi_pointer :: proc($T: typeid/[^]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (mp: T, err: Allocator_Error) {
- runtime.make_slice_error_loc(loc, len)
- data := alloc_bytes(size_of(E)*len, align_of(E), allocator, loc) or_return
- if data == nil && size_of(E) != 0 {
- return
- }
- mp = cast(T)raw_data(data)
- return
+ return runtime.make_multi_pointer(T, len, allocator, loc)
}
make :: proc{
diff --git a/core/mem/mem.odin b/core/mem/mem.odin
index 0ea9d5b79..d423cc1eb 100644
--- a/core/mem/mem.odin
+++ b/core/mem/mem.odin
@@ -45,6 +45,8 @@ copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawpt
intrinsics.mem_copy_non_overlapping(dst, src, len)
return dst
}
+
+@(require_results)
compare :: proc "contextless" (a, b: []byte) -> int {
res := compare_byte_ptrs(raw_data(a), raw_data(b), min(len(a), len(b)))
if res == 0 && len(a) != len(b) {
diff --git a/core/net/addr.odin b/core/net/addr.odin
index 508399bf4..c01724d99 100644
--- a/core/net/addr.odin
+++ b/core/net/addr.odin
@@ -119,9 +119,9 @@ aton :: proc(address_and_maybe_port: string, family: Address_Family, allow_decim
}
a: [4]u8 = ---
- for v, i in buf {
+ for v, j in buf {
if v > 255 { return {}, false }
- a[i] = u8(v)
+ a[j] = u8(v)
}
return IP4_Address(a), true
diff --git a/core/net/dns.odin b/core/net/dns.odin
index c556450c6..48cd8bf29 100644
--- a/core/net/dns.odin
+++ b/core/net/dns.odin
@@ -816,7 +816,6 @@ parse_response :: proc(response: []u8, filter: DNS_Record_Type = nil, allocator
dq_sz :: 4
hn_sz := skip_hostname(response, cur_idx) or_return
- dns_query := mem.slice_data_cast([]u16be, response[cur_idx+hn_sz:cur_idx+hn_sz+dq_sz])
cur_idx += hn_sz + dq_sz
}
diff --git a/core/net/dns_windows.odin b/core/net/dns_windows.odin
index e54b067b6..ccec7ea4b 100644
--- a/core/net/dns_windows.odin
+++ b/core/net/dns_windows.odin
@@ -85,11 +85,9 @@ _get_dns_records_os :: proc(hostname: string, type: DNS_Record_Type, allocator :
append(&recs, record)
case .CNAME:
-
- hostname := strings.clone(string(r.Data.CNAME))
record := DNS_Record_CNAME{
base = base_record,
- host_name = hostname,
+ host_name = strings.clone(string(r.Data.CNAME)),
}
append(&recs, record)
@@ -107,10 +105,9 @@ _get_dns_records_os :: proc(hostname: string, type: DNS_Record_Type, allocator :
}
case .NS:
- hostname := strings.clone(string(r.Data.NS))
record := DNS_Record_NS{
base = base_record,
- host_name = hostname,
+ host_name = strings.clone(string(r.Data.NS)),
}
append(&recs, record)
diff --git a/core/net/socket.odin b/core/net/socket.odin
index 1bfa52257..5f137401e 100644
--- a/core/net/socket.odin
+++ b/core/net/socket.odin
@@ -161,11 +161,10 @@ recv_any :: proc(socket: Any_Socket, buf: []byte) -> (
) {
switch socktype in socket {
case TCP_Socket:
- bytes_read, err := recv_tcp(socktype, buf)
- return bytes_read, nil, err
+ bytes_read, err = recv_tcp(socktype, buf)
+ return
case UDP_Socket:
- bytes_read, endpoint, err := recv_udp(socktype, buf)
- return bytes_read, endpoint, err
+ return recv_udp(socktype, buf)
case: panic("Not supported")
}
}
diff --git a/core/odin/doc-format/doc_format.odin b/core/odin/doc-format/doc_format.odin
index f8e23d53a..c2d86a0ba 100644
--- a/core/odin/doc-format/doc_format.odin
+++ b/core/odin/doc-format/doc_format.odin
@@ -249,7 +249,6 @@ Type :: struct {
// .Bit_Set - <=2 types: 0=element type, 1=underlying type (Underlying_Type flag will be set)
// .Simd_Vector - 1 type: 0=element
// .Relative_Pointer - 2 types: 0=pointer type, 1=base integer
- // .Relative_Slice - 2 types: 0=slice type, 1=base integer
// .Multi_Pointer - 1 type: 0=element
// .Matrix - 1 type: 0=element
// .Soa_Pointer - 1 type: 0=element
diff --git a/core/odin/printer/printer.odin b/core/odin/printer/printer.odin
index 63a3b543d..ce75352bd 100644
--- a/core/odin/printer/printer.odin
+++ b/core/odin/printer/printer.odin
@@ -643,7 +643,7 @@ align_switch_stmt :: proc(p: ^Printer, index: int) {
format_tokens := make([dynamic]TokenAndLength, 0, brace_token.parameter_count, context.temp_allocator)
//find all the switch cases that are one lined
- for line, line_index in p.lines[brace_line + 1:] {
+ for line in p.lines[brace_line + 1:] {
case_found := false
colon_found := false
@@ -716,7 +716,7 @@ align_enum :: proc(p: ^Printer, index: int) {
format_tokens := make([dynamic]TokenAndLength, 0, brace_token.parameter_count, context.temp_allocator)
- for line, line_index in p.lines[brace_line + 1:] {
+ for line in p.lines[brace_line + 1:] {
length := 0
for format_token, i in line.format_tokens {
@@ -880,7 +880,7 @@ align_comments :: proc(p: ^Printer) {
length := 0
- for format_token, i in line.format_tokens {
+ for format_token in line.format_tokens {
if format_token.kind == .Comment {
current_info.length = max(current_info.length, length)
current_info.end = line_index
diff --git a/core/odin/printer/visit.odin b/core/odin/printer/visit.odin
index 1aefcf967..7dd208a49 100644
--- a/core/odin/printer/visit.odin
+++ b/core/odin/printer/visit.odin
@@ -1462,9 +1462,9 @@ visit_binary_expr :: proc(p: ^Printer, binary: ^ast.Binary_Expr) {
}
either_implicit_selector := false
- if _, ok := binary.left.derived.(^ast.Implicit_Selector_Expr); ok {
+ if _, lok := binary.left.derived.(^ast.Implicit_Selector_Expr); lok {
either_implicit_selector = true
- } else if _, ok := binary.right.derived.(^ast.Implicit_Selector_Expr); ok {
+ } else if _, rok := binary.right.derived.(^ast.Implicit_Selector_Expr); rok {
either_implicit_selector = true
}
diff --git a/core/os/os2/errors.odin b/core/os/os2/errors.odin
index 426375a5a..d76b2d549 100644
--- a/core/os/os2/errors.odin
+++ b/core/os/os2/errors.odin
@@ -13,6 +13,12 @@ General_Error :: enum u32 {
Timeout,
+ Broken_Pipe,
+
+ // Indicates that an attempt to retrieve a file's size was made, but the
+ // file doesn't have a size.
+ No_Size,
+
Invalid_File,
Invalid_Dir,
Invalid_Path,
@@ -51,6 +57,8 @@ error_string :: proc(ferr: Error) -> string {
case .Not_Exist: return "file does not exist"
case .Closed: return "file already closed"
case .Timeout: return "i/o timeout"
+ case .Broken_Pipe: return "Broken pipe"
+ case .No_Size: return "file has no definite size"
case .Invalid_File: return "invalid file"
case .Invalid_Dir: return "invalid directory"
case .Invalid_Path: return "invalid path"
diff --git a/core/os/os2/file_util.odin b/core/os/os2/file_util.odin
index 459544fc0..0708f708e 100644
--- a/core/os/os2/file_util.odin
+++ b/core/os/os2/file_util.odin
@@ -87,26 +87,50 @@ read_entire_file_from_path :: proc(name: string, allocator: runtime.Allocator) -
read_entire_file_from_file :: proc(f: ^File, allocator: runtime.Allocator) -> (data: []byte, err: Error) {
size: int
+ has_size := true
if size64, err := file_size(f); err == nil {
if i64(int(size64)) != size64 {
size = int(size64)
}
+ } else if err == .No_Size {
+ has_size = false
+ } else {
+ return
}
size += 1 // for EOF
// TODO(bill): Is this correct logic?
- total: int
- data = make([]byte, size, allocator) or_return
- for {
- n: int
- n, err = read(f, data[total:])
- total += n
- if err != nil {
- if err == .EOF {
- err = nil
+ if has_size {
+ total: int
+ data = make([]byte, size, allocator) or_return
+ for {
+ n: int
+ n, err = read(f, data[total:])
+ total += n
+ if err != nil {
+ if err == .EOF {
+ err = nil
+ }
+ data = data[:total]
+ return
+ }
+ }
+ } else {
+ buffer: [1024]u8
+ out_buffer := make([dynamic]u8, 0, 0, allocator)
+ total := 0
+ for {
+ n: int = ---
+ n, err = read(f, buffer[:])
+ total += n
+ append_elems(&out_buffer, ..buffer[:total])
+ if err != nil {
+ if err == .EOF || err == .Broken_Pipe {
+ err = nil
+ }
+ data = out_buffer[:total]
+ return
}
- data = data[:total]
- return
}
}
}
diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin
index 8cb040a0a..fc3cebaea 100644
--- a/core/os/os2/file_windows.odin
+++ b/core/os/os2/file_windows.odin
@@ -434,6 +434,9 @@ _write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: i64, err: Error) {
_file_size :: proc(f: ^File) -> (n: i64, err: Error) {
length: win32.LARGE_INTEGER
+ if f.impl.kind == .Pipe {
+ return 0, .No_Size
+ }
handle := _handle(f)
if !win32.GetFileSizeEx(handle, &length) {
err = _get_platform_error()
@@ -766,7 +769,6 @@ _is_dir :: proc(path: string) -> bool {
_file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
f := (^File)(stream_data)
ferr: Error
- i: int
switch mode {
case .Read:
n, ferr = _read(f, p)
diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin
index 43e0efc0a..716397475 100644
--- a/core/os/os_darwin.odin
+++ b/core/os/os_darwin.odin
@@ -456,6 +456,7 @@ foreign libc {
@(link_name="fstat64") _unix_fstat :: proc(fd: Handle, stat: ^OS_Stat) -> c.int ---
@(link_name="readlink") _unix_readlink :: proc(path: cstring, buf: ^byte, bufsiz: c.size_t) -> c.ssize_t ---
@(link_name="access") _unix_access :: proc(path: cstring, mask: int) -> int ---
+ @(link_name="fsync") _unix_fsync :: proc(handle: Handle) -> c.int ---
@(link_name="fdopendir$INODE64") _unix_fdopendir_amd64 :: proc(fd: Handle) -> Dir ---
@(link_name="readdir_r$INODE64") _unix_readdir_r_amd64 :: proc(dirp: Dir, entry: ^Dirent, result: ^^Dirent) -> c.int ---
@@ -565,8 +566,8 @@ fchmod :: proc(fd: Handle, mode: u16) -> Errno {
return cast(Errno)_unix_fchmod(fd, mode)
}
-close :: proc(fd: Handle) -> bool {
- return _unix_close(fd) == 0
+close :: proc(fd: Handle) -> Errno {
+ return cast(Errno)_unix_close(fd)
}
// If you read or write more than `SSIZE_MAX` bytes, most darwin implementations will return `EINVAL`
@@ -894,6 +895,10 @@ access :: proc(path: string, mask: int) -> bool {
return _unix_access(cstr, mask) == 0
}
+flush :: proc(fd: Handle) -> Errno {
+ return cast(Errno)_unix_fsync(fd)
+}
+
lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == allocator)
path_str := strings.clone_to_cstring(key, context.temp_allocator)
diff --git a/core/strconv/strconv.odin b/core/strconv/strconv.odin
index eae9f9504..f23e619dc 100644
--- a/core/strconv/strconv.odin
+++ b/core/strconv/strconv.odin
@@ -878,7 +878,7 @@ parse_f64_prefix :: proc(str: string) -> (value: f64, nr: int, ok: bool) {
s = s[1:]
fallthrough
case 'i', 'I':
- n := common_prefix_len_ignore_case(s, "infinity")
+ n = common_prefix_len_ignore_case(s, "infinity")
if 3 < n && n < 8 { // "inf" or "infinity"
n = 3
}
diff --git a/core/strings/strings.odin b/core/strings/strings.odin
index 5cee25a66..13c53f48e 100644
--- a/core/strings/strings.odin
+++ b/core/strings/strings.odin
@@ -809,7 +809,7 @@ _split :: proc(s_, sep: string, sep_save, n_: int, allocator := context.allocato
n = l
}
- res := make([]string, n, allocator, loc) or_return
+ res = make([]string, n, allocator, loc) or_return
for i := 0; i < n-1; i += 1 {
_, w := utf8.decode_rune_in_string(s)
res[i] = s[:w]
diff --git a/core/sys/info/platform_linux.odin b/core/sys/info/platform_linux.odin
index 93770a460..89b1204a7 100644
--- a/core/sys/info/platform_linux.odin
+++ b/core/sys/info/platform_linux.odin
@@ -18,8 +18,8 @@ init_os_version :: proc () {
fd, errno := linux.open("/etc/os-release", {.RDONLY}, {})
assert(errno == .NONE, "Failed to read /etc/os-release")
defer {
- errno := linux.close(fd)
- assert(errno == .NONE, "Failed to close the file descriptor")
+ cerrno := linux.close(fd)
+ assert(cerrno == .NONE, "Failed to close the file descriptor")
}
os_release_buf: [2048]u8
n, read_errno := linux.read(fd, os_release_buf[:])
diff --git a/core/sys/linux/constants.odin b/core/sys/linux/constants.odin
index 6294602e9..51f7db68f 100644
--- a/core/sys/linux/constants.odin
+++ b/core/sys/linux/constants.odin
@@ -1,4 +1,3 @@
-
package linux
/*
diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin
index 952d5bb31..10cc80041 100644
--- a/core/sys/windows/kernel32.odin
+++ b/core/sys/windows/kernel32.odin
@@ -324,6 +324,7 @@ foreign kernel32 {
lpName: LPCWSTR,
) -> HANDLE ---
ResetEvent :: proc(hEvent: HANDLE) -> BOOL ---
+ SetEvent :: proc(hEvent: HANDLE) -> BOOL ---
WaitForMultipleObjects :: proc(
nCount: DWORD,
lpHandles: ^HANDLE,
@@ -545,6 +546,10 @@ FILE_MAP_RESERVE :: DWORD(0x80000000)
FILE_MAP_TARGETS_INVALID :: DWORD(0x40000000)
FILE_MAP_LARGE_PAGES :: DWORD(0x20000000)
+// Flags for `SetFileCompletionNotificationModes`.
+FILE_SKIP_COMPLETION_PORT_ON_SUCCESS :: 0x1
+FILE_SKIP_SET_EVENT_ON_HANDLE :: 0x2
+
PAGE_NOACCESS :: 0x01
PAGE_READONLY :: 0x02
PAGE_READWRITE :: 0x04
diff --git a/core/sys/windows/ole32.odin b/core/sys/windows/ole32.odin
index 6fa398d46..d344db5f0 100644
--- a/core/sys/windows/ole32.odin
+++ b/core/sys/windows/ole32.odin
@@ -3,9 +3,24 @@ package sys_windows
foreign import "system:Ole32.lib"
//objbase.h
+// Note(Dragos): https://learn.microsoft.com/en-us/windows/win32/api/objbase/ne-objbase-coinit makes you believe that MULTITHREADED == 3. That is wrong. See definition of objbase.h
+/*
+typedef enum tagCOINIT
+{
+ COINIT_APARTMENTTHREADED = 0x2, // Apartment model
+
+#if (_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM) // DCOM
+ // These constants are only valid on Windows NT 4.0
+ COINIT_MULTITHREADED = COINITBASE_MULTITHREADED,
+ COINIT_DISABLE_OLE1DDE = 0x4, // Don't use DDE for Ole1 support.
+ COINIT_SPEED_OVER_MEMORY = 0x8, // Trade memory for speed.
+#endif // DCOM
+} COINIT;
+*/
+// Where COINITBASE_MULTITHREADED == 0x00
COINIT :: enum DWORD {
APARTMENTTHREADED = 0x2,
- MULTITHREADED,
+ MULTITHREADED = 0,
DISABLE_OLE1DDE = 0x4,
SPEED_OVER_MEMORY = 0x8,
}
diff --git a/core/sys/windows/ws2_32.odin b/core/sys/windows/ws2_32.odin
index c60a21a36..e9bf8abc9 100644
--- a/core/sys/windows/ws2_32.odin
+++ b/core/sys/windows/ws2_32.odin
@@ -2,12 +2,12 @@
package sys_windows
// Define flags to be used with the WSAAsyncSelect() call.
-FD_READ :: 0x01
-FD_WRITE :: 0x02
-FD_OOB :: 0x04
-FD_ACCEPT :: 0x08
-FD_CONNECT :: 0x10
-FD_CLOSE :: 0x20
+FD_READ :: 0x01
+FD_WRITE :: 0x02
+FD_OOB :: 0x04
+FD_ACCEPT :: 0x08
+FD_CONNECT :: 0x10
+FD_CLOSE :: 0x20
FD_MAX_EVENTS :: 10
INADDR_LOOPBACK :: 0x7f000001
@@ -24,10 +24,10 @@ POLLERR :: 0x0001
POLLHUP :: 0x0002
POLLNVAL :: 0x0004
-WSA_POLLFD::struct{
- fd:SOCKET,
- events:c_short,
- revents:c_short,
+WSA_POLLFD :: struct{
+ fd: SOCKET,
+ events: c_short,
+ revents: c_short,
}
WSANETWORKEVENTS :: struct {
@@ -37,16 +37,43 @@ WSANETWORKEVENTS :: struct {
WSAEVENT :: HANDLE
-WSAID_ACCEPTEX :: GUID{0xb5367df1, 0xcbac, 0x11cf, {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
+WSAID_ACCEPTEX :: GUID{0xb5367df1, 0xcbac, 0x11cf, {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
WSAID_GETACCEPTEXSOCKADDRS :: GUID{0xb5367df2, 0xcbac, 0x11cf, {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
+WSAID_CONNECTX :: GUID{0x25a207b9, 0xddf3, 0x4660, {0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}}
+
SIO_GET_EXTENSION_FUNCTION_POINTER :: IOC_INOUT | IOC_WS2 | 6
-IOC_OUT :: 0x40000000
-IOC_IN :: 0x80000000
+
+IOC_OUT :: 0x40000000
+IOC_IN :: 0x80000000
IOC_INOUT :: (IOC_IN | IOC_OUT)
-IOC_WS2 :: 0x08000000
+IOC_WS2 :: 0x08000000
+
+SO_UPDATE_ACCEPT_CONTEXT :: 28683
+
+LPFN_CONNECTEX :: #type proc "system" (
+ s: SOCKET,
+ sockaddr: ^SOCKADDR_STORAGE_LH,
+ namelen: c_int,
+ lpSendBuffer: PVOID,
+ dwSendDataLength: DWORD,
+ lpdwBytesSent: LPDWORD,
+ lpOverlapped: LPOVERLAPPED,
+) -> BOOL
+
+LPFN_ACCEPTEX :: #type proc "system" (
+ sListenSocket: SOCKET,
+ sAcceptSocket: SOCKET,
+ lpOutputBuffer: PVOID,
+ dwReceiveDataLength: DWORD,
+ dwLocalAddressLength: DWORD,
+ dwRemoteAddressLength: DWORD,
+ lpdwBytesReceived: LPDWORD,
+ lpOverlapped: LPOVERLAPPED,
+) -> BOOL
+
/*
Example Load:
- load_accept_ex :: proc(listener: SOCKET, fn_acceptex: rawptr) {
+ load_accept_ex :: proc(listener: SOCKET, fn_acceptex: ^LPFN_ACCEPTEX) {
bytes: u32
guid_accept_ex := WSAID_ACCEPTEX
rc := WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid_accept_ex, size_of(guid_accept_ex),
diff --git a/core/text/i18n/qt_linguist.odin b/core/text/i18n/qt_linguist.odin
index fa05a6dc1..0e75df873 100644
--- a/core/text/i18n/qt_linguist.odin
+++ b/core/text/i18n/qt_linguist.odin
@@ -128,7 +128,7 @@ parse_qt_linguist_from_bytes :: proc(data: []byte, options := DEFAULT_PARSE_OPTI
num_plurals: int
for {
- numerus_id := xml.find_child_by_ident(ts, translation_id, "numerusform", num_plurals) or_break
+ xml.find_child_by_ident(ts, translation_id, "numerusform", num_plurals) or_break
num_plurals += 1
}
diff --git a/core/unicode/utf8/utf8.odin b/core/unicode/utf8/utf8.odin
index 3642b8078..67f8a8be9 100644
--- a/core/unicode/utf8/utf8.odin
+++ b/core/unicode/utf8/utf8.odin
@@ -45,18 +45,18 @@ accept_ranges := [5]Accept_Range{
{0x80, 0x8f},
}
-accept_sizes := [256]u8{
- 0x00..=0x7f = 0xf0,
- 0x80..=0xc1 = 0xf1,
- 0xc2..=0xdf = 0x02,
- 0xe0 = 0x13,
- 0xe1..=0xec = 0x03,
- 0xed = 0x23,
- 0xee..=0xef = 0x03,
- 0xf0 = 0x34,
- 0xf1..=0xf3 = 0x04,
- 0xf4 = 0x44,
- 0xf5..=0xff = 0xf1,
+accept_sizes := [256]u8{
+ 0x00..=0x7f = 0xf0, // ascii, size 1
+ 0x80..=0xc1 = 0xf1, // invalid, size 1
+ 0xc2..=0xdf = 0x02, // accept 1, size 2
+ 0xe0 = 0x13, // accept 1, size 3
+ 0xe1..=0xec = 0x03, // accept 0, size 3
+ 0xed = 0x23, // accept 2, size 3
+ 0xee..=0xef = 0x03, // accept 0, size 3
+ 0xf0 = 0x34, // accept 3, size 4
+ 0xf1..=0xf3 = 0x04, // accept 0, size 4
+ 0xf4 = 0x44, // accept 4, size 4
+ 0xf5..=0xff = 0xf1, // ascii, size 1
}
encode_rune :: proc "contextless" (c: rune) -> ([4]u8, int) {
@@ -385,7 +385,7 @@ full_rune_in_bytes :: proc "contextless" (b: []byte) -> bool {
if n == 0 {
return false
}
- x := _first[b[0]]
+ x := accept_sizes[b[0]]
if n >= int(x & 7) {
return true
}
@@ -403,18 +403,3 @@ full_rune_in_bytes :: proc "contextless" (b: []byte) -> bool {
full_rune_in_string :: proc "contextless" (s: string) -> bool {
return full_rune_in_bytes(transmute([]byte)s)
}
-
-
-_first := [256]u8{
- 0x00..=0x7f = 0xf0, // ascii, size 1
- 0x80..=0xc1 = 0xf1, // invalid, size 1
- 0xc2..=0xdf = 0x02, // accept 1, size 2
- 0xe0 = 0x13, // accept 1, size 3
- 0xe1..=0xec = 0x03, // accept 0, size 3
- 0xed = 0x23, // accept 2, size 3
- 0xee..=0xef = 0x03, // accept 0, size 3
- 0xf0 = 0x34, // accept 3, size 4
- 0xf1..=0xf3 = 0x04, // accept 0, size 4
- 0xf4 = 0x44, // accept 4, size 4
- 0xf5..=0xff = 0xf1, // ascii, size 1
-}
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index 1ac9e451f..30d6f0b3c 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -412,7 +412,9 @@ struct BuildContext {
bool dynamic_map_calls;
- bool obfuscate_source_code_locations;
+ bool obfuscate_source_code_locations;
+
+ bool min_link_libs;
RelocMode reloc_mode;
bool disable_red_zone;
@@ -519,7 +521,7 @@ gb_global TargetMetrics target_darwin_amd64 = {
gb_global TargetMetrics target_darwin_arm64 = {
TargetOs_darwin,
TargetArch_arm64,
- 8, 8, 8, 16,
+ 8, 8, 16, 16,
str_lit("arm64-apple-macosx"), // NOTE: Changes during initialization based on build flags.
str_lit("e-m:o-i64:64-i128:128-n32:64-S128"),
};
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index c7a1b460a..c80b08695 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -2428,7 +2428,7 @@ gb_internal void check_old_for_or_switch_value_usage(Ast *expr) {
if ((e->flags & EntityFlag_ForValue) != 0) {
Type *parent_type = type_deref(e->Variable.for_loop_parent_type);
- error(expr, "Assuming a for-in defined value is addressable as the iterable is passed by value has been disallowed with '-strict-style'.");
+ error(expr, "Assuming a for-in defined value is addressable as the iterable is passed by value has been disallowed.");
if (is_type_map(parent_type)) {
error_line("\tSuggestion: Prefer doing 'for key, &%.*s in ...'\n", LIT(e->token.string));
@@ -2438,7 +2438,7 @@ gb_internal void check_old_for_or_switch_value_usage(Ast *expr) {
} else {
GB_ASSERT((e->flags & EntityFlag_SwitchValue) != 0);
- error(expr, "Assuming a switch-in defined value is addressable as the iterable is passed by value has been disallowed with '-strict-style'.");
+ error(expr, "Assuming a switch-in defined value is addressable as the iterable is passed by value has been disallowed.");
error_line("\tSuggestion: Prefer doing 'switch &%.*s in ...'\n", LIT(e->token.string));
}
}
@@ -4129,7 +4129,7 @@ gb_internal void update_untyped_expr_value(CheckerContext *c, Ast *e, ExactValue
}
}
-gb_internal void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_type) {
+gb_internal void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_type, bool ignore_error_block=false) {
gbString expr_str = expr_to_string(operand->expr);
gbString type_str = type_to_string(target_type);
gbString from_type_str = type_to_string(operand->type);
@@ -4143,7 +4143,9 @@ gb_internal void convert_untyped_error(CheckerContext *c, Operand *operand, Type
}
}
}
- ERROR_BLOCK();
+ if (!ignore_error_block) {
+ begin_error_block();
+ }
error(operand->expr, "Cannot convert untyped value '%s' to '%s' from '%s'%s", expr_str, type_str, from_type_str, extra_text);
if (operand->value.kind == ExactValue_String) {
@@ -4158,6 +4160,11 @@ gb_internal void convert_untyped_error(CheckerContext *c, Operand *operand, Type
gb_string_free(type_str);
gb_string_free(expr_str);
operand->mode = Addressing_Invalid;
+
+ if (!ignore_error_block) {
+ end_error_block();
+ }
+
}
gb_internal ExactValue convert_exact_value_for_type(ExactValue v, Type *type) {
@@ -4287,7 +4294,7 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar
operand->mode = Addressing_Invalid;
ERROR_BLOCK();
- convert_untyped_error(c, operand, target_type);
+ convert_untyped_error(c, operand, target_type, true);
error_line("\tNote: Only a square matrix types can be initialized with a scalar value\n");
return;
} else {
@@ -4350,7 +4357,7 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar
GB_ASSERT(first_success_index >= 0);
operand->mode = Addressing_Invalid;
- convert_untyped_error(c, operand, target_type);
+ convert_untyped_error(c, operand, target_type, true);
error_line("Ambiguous type conversion to '%s', which variant did you mean:\n\t", type_str);
i32 j = 0;
@@ -4375,9 +4382,10 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar
ERROR_BLOCK();
operand->mode = Addressing_Invalid;
- convert_untyped_error(c, operand, target_type);
+ convert_untyped_error(c, operand, target_type, true);
if (count > 0) {
error_line("'%s' is a union which only excepts the following types:\n", type_str);
+
error_line("\t");
for (i32 i = 0; i < count; i++) {
Type *v = t->Union.variants[i];
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp
index 1d7e7d4e9..fc3b9aa43 100644
--- a/src/check_stmt.cpp
+++ b/src/check_stmt.cpp
@@ -740,6 +740,25 @@ gb_internal bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us,
return true;
}
+gb_internal void error_var_decl_identifier(Ast *name) {
+ GB_ASSERT(name != nullptr);
+ GB_ASSERT(name->kind != Ast_Ident);
+
+ ERROR_BLOCK();
+ gbString s = expr_to_string(name);
+ defer (gb_string_free(s));
+
+ error(name, "A variable declaration must be an identifier, got '%s'", s);
+ if (name->kind == Ast_Implicit) {
+ String imp = name->Implicit.string;
+ if (imp == "context") {
+ error_line("\tSuggestion: '%.*s' is a reserved keyword, would 'ctx' suffice?\n", LIT(imp));
+ } else {
+ error_line("\tNote: '%.*s' is a reserved keyword\n", LIT(imp));
+ }
+ }
+}
+
gb_internal void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
ast_node(irs, UnrollRangeStmt, node);
check_open_scope(ctx, node);
@@ -851,7 +870,7 @@ gb_internal void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod
entity = found;
}
} else {
- error(name, "A variable declaration must be an identifier");
+ error_var_decl_identifier(name);
}
if (entity == nullptr) {
@@ -1479,6 +1498,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
auto vals = array_make(temporary_allocator(), 0, 2);
auto entities = array_make(temporary_allocator(), 0, 2);
bool is_map = false;
+ bool is_bit_set = false;
bool use_by_reference_for_value = false;
bool is_soa = false;
bool is_reverse = rs->reverse;
@@ -1524,6 +1544,9 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
array_add(&vals, operand.type);
array_add(&vals, t_int);
add_type_info_type(ctx, operand.type);
+ if (build_context.no_rtti) {
+ error(node, "Iteration over an enum type is not allowed runtime type information (RTTI) has been disallowed");
+ }
goto skip_expr_range_stmt;
}
} else if (operand.mode != Addressing_Invalid) {
@@ -1554,6 +1577,17 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
}
break;
+ case Type_BitSet:
+ array_add(&vals, t->BitSet.elem);
+ max_val_count = 1;
+ is_bit_set = true;
+ is_possibly_addressable = false;
+ add_type_info_type(ctx, operand.type);
+ if (build_context.no_rtti && is_type_enum(t->BitSet.elem)) {
+ error(node, "Iteration over a bit_set of an enum is not allowed runtime type information (RTTI) has been disallowed");
+ }
+ break;
+
case Type_EnumeratedArray:
if (is_ptr) use_by_reference_for_value = true;
array_add(&vals, t->EnumeratedArray.elem);
@@ -1709,7 +1743,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
if (is_possibly_addressable && i == addressable_index) {
entity->flags &= ~EntityFlag_Value;
} else {
- char const *idx_name = is_map ? "key" : "index";
+ char const *idx_name = is_map ? "key" : is_bit_set ? "element" : "index";
error(token, "The %s variable '%.*s' cannot be made addressable", idx_name, LIT(str));
}
} else if (i == addressable_index && use_by_reference_for_value) {
@@ -1732,9 +1766,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
entity = found;
}
} else {
- gbString s = expr_to_string(lhs[i]);
- error(name, "A variable declaration must be an identifier, got %s", s);
- gb_string_free(s);
+ error_var_decl_identifier(name);
}
if (entity == nullptr) {
@@ -1786,7 +1818,7 @@ gb_internal void check_value_decl_stmt(CheckerContext *ctx, Ast *node, u32 mod_f
for (Ast *name : vd->names) {
Entity *entity = nullptr;
if (name->kind != Ast_Ident) {
- error(name, "A variable declaration must be an identifier");
+ error_var_decl_identifier(name);
} else {
Token token = name->Ident.token;
String str = token.string;
@@ -2043,13 +2075,13 @@ gb_internal void check_expr_stmt(CheckerContext *ctx, Ast *node) {
}
Ast *expr = strip_or_return_expr(operand.expr);
- if (expr->kind == Ast_CallExpr) {
+ if (expr && expr->kind == Ast_CallExpr) {
BuiltinProcId builtin_id = BuiltinProc_Invalid;
bool do_require = false;
AstCallExpr *ce = &expr->CallExpr;
Type *t = base_type(type_of_expr(ce->proc));
- if (t->kind == Type_Proc) {
+ if (t && t->kind == Type_Proc) {
do_require = t->Proc.require_results;
} else if (check_stmt_internal_builtin_proc_id(ce->proc, &builtin_id)) {
auto const &bp = builtin_procs[builtin_id];
@@ -2061,7 +2093,7 @@ gb_internal void check_expr_stmt(CheckerContext *ctx, Ast *node) {
gb_string_free(expr_str);
}
return;
- } else if (expr->kind == Ast_SelectorCallExpr) {
+ } else if (expr && expr->kind == Ast_SelectorCallExpr) {
BuiltinProcId builtin_id = BuiltinProc_Invalid;
bool do_require = false;
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 609b73229..81e67f261 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -790,6 +790,9 @@ gb_internal void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *nam
ast_node(et, EnumType, node);
GB_ASSERT(is_type_enum(enum_type));
+ enum_type->Enum.base_type = t_int;
+ enum_type->Enum.scope = ctx->scope;
+
Type *base_type = t_int;
if (et->base_type != nullptr) {
base_type = check_type(ctx, et->base_type);
@@ -811,7 +814,6 @@ gb_internal void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *nam
// NOTE(bill): Must be up here for the 'check_init_constant' system
enum_type->Enum.base_type = base_type;
- enum_type->Enum.scope = ctx->scope;
auto fields = array_make(permanent_allocator(), 0, et->fields.count);
diff --git a/src/checker.cpp b/src/checker.cpp
index 100b53315..244e7efbd 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -224,7 +224,7 @@ gb_internal Scope *create_scope(CheckerInfo *info, Scope *parent) {
if (parent != nullptr && parent != builtin_pkg->scope) {
Scope *prev_head_child = parent->head_child.exchange(s, std::memory_order_acq_rel);
if (prev_head_child) {
- prev_head_child->next.store(s, std::memory_order_release);
+ s->next.store(prev_head_child, std::memory_order_release);
}
}
@@ -703,6 +703,15 @@ gb_internal void check_scope_usage(Checker *c, Scope *scope, u64 vet_flags) {
array_add(&vetted_entities, ve_unused);
} else if (is_shadowed) {
array_add(&vetted_entities, ve_shadowed);
+ } else if (e->kind == Entity_Variable && (e->flags & (EntityFlag_Param|EntityFlag_Using)) == 0) {
+ i64 sz = type_size_of(e->type);
+ // TODO(bill): When is a good size warn?
+ // Is 128 KiB good enough?
+ if (sz >= 1ll<<17) {
+ gbString type_str = type_to_string(e->type);
+ warning(e->token, "Declaration of '%.*s' may cause a stack overflow due to its type '%s' having a size of %lld bytes", LIT(e->token.string), type_str, cast(long long)sz);
+ gb_string_free(type_str);
+ }
}
}
rw_mutex_shared_unlock(&scope->mutex);
@@ -734,17 +743,6 @@ gb_internal void check_scope_usage(Checker *c, Scope *scope, u64 vet_flags) {
break;
}
}
-
- if (e->kind == Entity_Variable && (e->flags & (EntityFlag_Param|EntityFlag_Using)) == 0) {
- i64 sz = type_size_of(e->type);
- // TODO(bill): When is a good size warn?
- // Is 128 KiB good enough?
- if (sz >= 1ll<<17) {
- gbString type_str = type_to_string(e->type);
- warning(e->token, "Declaration of '%.*s' may cause a stack overflow due to its type '%s' having a size of %lld bytes", LIT(name), type_str, cast(long long)sz);
- gb_string_free(type_str);
- }
- }
}
array_free(&vetted_entities);
diff --git a/src/error.cpp b/src/error.cpp
index b18df79b7..c92392dce 100644
--- a/src/error.cpp
+++ b/src/error.cpp
@@ -62,7 +62,9 @@ gb_internal ErrorValue *get_error_value(void) {
gb_internal bool any_errors(void) {
return global_error_collector.count.load() != 0;
}
-
+gb_internal bool any_warnings(void) {
+ return global_error_collector.warning_count.load() != 0;
+}
gb_internal void init_global_error_collector(void) {
@@ -600,7 +602,7 @@ gb_internal void syntax_error_with_verbose(TokenPos pos, TokenPos end, char cons
gb_internal void compiler_error(char const *fmt, ...) {
- if (any_errors()) {
+ if (any_errors() || any_warnings()) {
print_all_errors();
}
@@ -616,7 +618,7 @@ gb_internal void compiler_error(char const *fmt, ...) {
gb_internal void exit_with_errors(void) {
- if (any_errors()) {
+ if (any_errors() || any_warnings()) {
print_all_errors();
}
gb_exit(1);
@@ -650,7 +652,7 @@ gb_internal void print_all_errors(void) {
}
};
- GB_ASSERT(any_errors());
+ GB_ASSERT(any_errors() || any_warnings());
gbFile *f = gb_file_get_standard(gbFileStandard_Error);
array_sort(global_error_collector.error_values, error_value_cmp);
diff --git a/src/linker.cpp b/src/linker.cpp
index 0e3169b22..aa36b3278 100644
--- a/src/linker.cpp
+++ b/src/linker.cpp
@@ -139,9 +139,11 @@ gb_internal i32 linker_stage(LinkerData *gen) {
}
- StringSet libs = {};
- string_set_init(&libs, 64);
- defer (string_set_destroy(&libs));
+ StringSet min_libs_set = {};
+ string_set_init(&min_libs_set, 64);
+ defer (string_set_destroy(&min_libs_set));
+
+ String prev_lib = {};
StringSet asm_files = {};
string_set_init(&asm_files, 64);
@@ -149,6 +151,11 @@ gb_internal i32 linker_stage(LinkerData *gen) {
for (Entity *e : gen->foreign_libraries) {
GB_ASSERT(e->kind == Entity_LibraryName);
+ // NOTE(bill): Add these before the linking values
+ String extra_linker_flags = string_trim_whitespace(e->LibraryName.extra_linker_flags);
+ if (extra_linker_flags.len != 0) {
+ lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(extra_linker_flags));
+ }
for_array(i, e->LibraryName.paths) {
String lib = string_trim_whitespace(e->LibraryName.paths[i]);
// IMPORTANT NOTE(bill): calling `string_to_lower` here is not an issue because
@@ -162,12 +169,11 @@ gb_internal i32 linker_stage(LinkerData *gen) {
if (!string_set_update(&asm_files, lib)) {
String asm_file = asm_files.entries[i].value;
String obj_file = concatenate_strings(permanent_allocator(), asm_file, str_lit(".obj"));
- String obj_format;
-#if defined(GB_ARCH_64_BIT)
- obj_format = str_lit("win64");
-#elif defined(GB_ARCH_32_BIT)
+ String obj_format = str_lit("win64");
+ #if defined(GB_ARCH_32_BIT)
obj_format = str_lit("win32");
-#endif // GB_ARCH_*_BIT
+ #endif
+
result = system_exec_command_line_app("nasm",
"\"%.*s\\bin\\nasm\\windows\\nasm.exe\" \"%.*s\" "
"-f \"%.*s\" "
@@ -185,21 +191,16 @@ gb_internal i32 linker_stage(LinkerData *gen) {
}
array_add(&gen->output_object_paths, obj_file);
}
- } else {
- if (!string_set_update(&libs, lib)) {
+ } else if (!string_set_update(&min_libs_set, lib) ||
+ !build_context.min_link_libs) {
+ if (prev_lib != lib) {
lib_str = gb_string_append_fmt(lib_str, " \"%.*s\"", LIT(lib));
}
+ prev_lib = lib;
}
}
}
- for (Entity *e : gen->foreign_libraries) {
- GB_ASSERT(e->kind == Entity_LibraryName);
- if (e->LibraryName.extra_linker_flags.len != 0) {
- lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(e->LibraryName.extra_linker_flags));
- }
- }
-
if (build_context.build_mode == BuildMode_DynamicLibrary) {
link_settings = gb_string_append_fmt(link_settings, " /DLL");
} else {
@@ -318,12 +319,19 @@ gb_internal i32 linker_stage(LinkerData *gen) {
string_set_init(&asm_files, 64);
defer (string_set_destroy(&asm_files));
- StringSet libs = {};
- string_set_init(&libs, 64);
- defer (string_set_destroy(&libs));
+ StringSet min_libs_set = {};
+ string_set_init(&min_libs_set, 64);
+ defer (string_set_destroy(&min_libs_set));
+
+ String prev_lib = {};
for (Entity *e : gen->foreign_libraries) {
GB_ASSERT(e->kind == Entity_LibraryName);
+ // NOTE(bill): Add these before the linking values
+ String extra_linker_flags = string_trim_whitespace(e->LibraryName.extra_linker_flags);
+ if (extra_linker_flags.len != 0) {
+ lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(extra_linker_flags));
+ }
for (String lib : e->LibraryName.paths) {
lib = string_trim_whitespace(lib);
if (lib.len == 0) {
@@ -336,19 +344,19 @@ gb_internal i32 linker_stage(LinkerData *gen) {
String asm_file = lib;
String obj_file = concatenate_strings(permanent_allocator(), asm_file, str_lit(".o"));
String obj_format;
-#if defined(GB_ARCH_64_BIT)
+ #if defined(GB_ARCH_64_BIT)
if (is_osx) {
obj_format = str_lit("macho64");
} else {
obj_format = str_lit("elf64");
}
-#elif defined(GB_ARCH_32_BIT)
+ #elif defined(GB_ARCH_32_BIT)
if (is_osx) {
obj_format = str_lit("macho32");
} else {
obj_format = str_lit("elf32");
}
-#endif // GB_ARCH_*_BIT
+ #endif // GB_ARCH_*_BIT
if (is_osx) {
// `as` comes with MacOS.
@@ -383,10 +391,15 @@ gb_internal i32 linker_stage(LinkerData *gen) {
}
array_add(&gen->output_object_paths, obj_file);
} else {
- if (string_set_update(&libs, lib)) {
+ if (string_set_update(&min_libs_set, lib) && build_context.min_link_libs) {
continue;
}
+ if (prev_lib == lib) {
+ continue;
+ }
+ prev_lib = lib;
+
// Do not add libc again, this is added later already, and omitted with
// the `-no-crt` flag, not skipping here would cause duplicate library
// warnings when linking on darwin and might link libc silently even with `-no-crt`.
@@ -433,13 +446,6 @@ gb_internal i32 linker_stage(LinkerData *gen) {
}
}
- for (Entity *e : gen->foreign_libraries) {
- GB_ASSERT(e->kind == Entity_LibraryName);
- if (e->LibraryName.extra_linker_flags.len != 0) {
- lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(e->LibraryName.extra_linker_flags));
- }
- }
-
gbString object_files = gb_string_make(heap_allocator(), "");
defer (gb_string_free(object_files));
for (String object_path : gen->output_object_paths) {
diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp
index 724e4e35a..88bb58c55 100644
--- a/src/llvm_abi.cpp
+++ b/src/llvm_abi.cpp
@@ -192,7 +192,7 @@ gb_internal void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType
// }
LLVMSetFunctionCallConv(fn, cc_kind);
if (calling_convention == ProcCC_Odin) {
- unsigned context_index = offset+arg_count;
+ unsigned context_index = arg_index;
LLVMAddAttributeAtIndex(fn, context_index, noalias_attr);
LLVMAddAttributeAtIndex(fn, context_index, nonnull_attr);
LLVMAddAttributeAtIndex(fn, context_index, nocapture_attr);
@@ -275,7 +275,7 @@ gb_internal i64 lb_alignof(LLVMTypeRef type) {
case LLVMIntegerTypeKind:
{
unsigned w = LLVMGetIntTypeWidth(type);
- return gb_clamp((w + 7)/8, 1, build_context.ptr_size);
+ return gb_clamp((w + 7)/8, 1, build_context.max_align);
}
case LLVMHalfTypeKind:
return 2;
@@ -558,7 +558,6 @@ namespace lbAbiAmd64SysV {
Amd64TypeAttribute_StructRect,
};
- gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
gb_internal void classify_with(LLVMTypeRef t, Array *cls, i64 ix, i64 off);
gb_internal void fixup(LLVMTypeRef t, Array *cls);
gb_internal lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention);
@@ -796,10 +795,10 @@ namespace lbAbiAmd64SysV {
}
}
+ i64 sz = lb_sizeof(type);
if (all_ints) {
- i64 sz = lb_sizeof(type);
for_array(i, reg_classes) {
- GB_ASSERT(sz != 0);
+ GB_ASSERT(sz > 0);
// TODO(bill): is this even correct? BECAUSE LLVM DOES NOT DOCUMENT ANY OF THIS!!!
if (sz >= 8) {
array_add(&types, LLVMIntTypeInContext(c, 64));
@@ -811,12 +810,16 @@ namespace lbAbiAmd64SysV {
}
} else {
for (isize i = 0; i < reg_classes.count; /**/) {
+ GB_ASSERT(sz > 0);
RegClass reg_class = reg_classes[i];
switch (reg_class) {
case RegClass_Int:
- // TODO(bill): is this even correct? BECAUSE LLVM DOES NOT DOCUMENT ANY OF THIS!!!
- array_add(&types, LLVMIntTypeInContext(c, 64));
- break;
+ {
+ i64 rs = gb_min(sz, 8);
+ array_add(&types, LLVMIntTypeInContext(c, cast(unsigned)(rs*8)));
+ sz -= rs;
+ break;
+ }
case RegClass_SSEFv:
case RegClass_SSEDv:
case RegClass_SSEInt8:
@@ -856,15 +859,18 @@ namespace lbAbiAmd64SysV {
unsigned vec_len = llvec_len(reg_classes, i+1);
LLVMTypeRef vec_type = LLVMVectorType(elem_type, vec_len * elems_per_word);
array_add(&types, vec_type);
+ sz -= lb_sizeof(vec_type);
i += vec_len;
continue;
}
break;
case RegClass_SSEFs:
array_add(&types, LLVMFloatTypeInContext(c));
+ sz -= 4;
break;
case RegClass_SSEDs:
array_add(&types, LLVMDoubleTypeInContext(c));
+ sz -= 8;
break;
default:
GB_PANIC("Unhandled RegClass");
@@ -876,8 +882,8 @@ namespace lbAbiAmd64SysV {
if (types.count == 1) {
return types[0];
}
- // TODO(bill): this should be packed but it causes code generation issues
- return LLVMStructTypeInContext(c, types.data, cast(unsigned)types.count, false);
+
+ return LLVMStructTypeInContext(c, types.data, cast(unsigned)types.count, sz == 0);
}
gb_internal void classify_with(LLVMTypeRef t, Array *cls, i64 ix, i64 off) {
@@ -980,28 +986,6 @@ namespace lbAbiAmd64SysV {
break;
}
}
-
- gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type) {
- if (!return_is_defined) {
- return lb_arg_type_direct(LLVMVoidTypeInContext(c));
- } else if (lb_is_type_kind(return_type, LLVMStructTypeKind)) {
- i64 sz = lb_sizeof(return_type);
- switch (sz) {
- case 1: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 8), nullptr, nullptr);
- case 2: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 16), nullptr, nullptr);
- case 4: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 32), nullptr, nullptr);
- case 8: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 64), nullptr, nullptr);
- }
-
- LB_ABI_MODIFY_RETURN_IF_TUPLE_MACRO();
-
- LLVMAttributeRef attr = lb_create_enum_attribute_with_type(c, "sret", return_type);
- return lb_arg_type_indirect(return_type, attr);
- } else if (build_context.metrics.os == TargetOs_windows && lb_is_type_kind(return_type, LLVMIntegerTypeKind) && lb_sizeof(return_type) == 16) {
- return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 128), nullptr, nullptr);
- }
- return non_struct(c, return_type);
- }
};
@@ -1166,8 +1150,7 @@ namespace lbAbiArm64 {
size_copy -= 8;
}
GB_ASSERT(size_copy <= 0);
- // TODO(bill): this should be packed but it causes code generation issues
- cast_type = LLVMStructTypeInContext(c, types, count, false);
+ cast_type = LLVMStructTypeInContext(c, types, count, true);
}
return lb_arg_type_direct(return_type, cast_type, nullptr, nullptr);
} else {
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index cc9b3ac5d..645a091b0 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -1975,12 +1975,6 @@ gb_internal void lb_generate_missing_procedures(lbGenerator *gen, bool do_thread
}
gb_internal void lb_debug_info_complete_types_and_finalize(lbGenerator *gen) {
- for (auto const &entry : gen->modules) {
- lbModule *m = entry.value;
- if (m->debug_builder != nullptr) {
- lb_debug_complete_types(m);
- }
- }
for (auto const &entry : gen->modules) {
lbModule *m = entry.value;
if (m->debug_builder != nullptr) {
diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp
index 6000be32d..c4bf2691d 100644
--- a/src/llvm_backend.hpp
+++ b/src/llvm_backend.hpp
@@ -199,8 +199,6 @@ struct lbModule {
RecursiveMutex debug_values_mutex;
PtrMap debug_values;
- Array debug_incomplete_types;
-
StringMap objc_classes;
StringMap objc_selectors;
diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp
index 048f5f933..511ff0475 100644
--- a/src/llvm_backend_debug.cpp
+++ b/src/llvm_backend_debug.cpp
@@ -114,6 +114,415 @@ gb_internal LLVMMetadataRef lb_debug_basic_struct(lbModule *m, String const &nam
return LLVMDIBuilderCreateStructType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, 1, size_in_bits, align_in_bits, LLVMDIFlagZero, nullptr, elements, element_count, 0, nullptr, "", 0);
}
+gb_internal LLVMMetadataRef lb_debug_struct(lbModule *m, Type *type, Type *bt, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) {
+ GB_ASSERT(bt->kind == Type_Struct);
+
+ unsigned tag = DW_TAG_structure_type;
+ if (is_type_raw_union(bt)) {
+ tag = DW_TAG_union_type;
+ }
+
+ u64 size_in_bits = 8*type_size_of(bt);
+ u32 align_in_bits = 8*cast(u32)type_align_of(bt);
+
+ LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType(
+ m->debug_builder, tag,
+ cast(char const *)name.text, cast(size_t)name.len,
+ scope, file, line, 0, size_in_bits, align_in_bits, LLVMDIFlagZero, "", 0
+ );
+
+ lb_set_llvm_metadata(m, type, temp_forward_decl);
+
+ type_set_offsets(bt);
+
+ unsigned element_count = cast(unsigned)(bt->Struct.fields.count);
+ LLVMMetadataRef *elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
+
+ LLVMMetadataRef member_scope = lb_get_llvm_metadata(m, bt->Struct.scope);
+
+ for_array(j, bt->Struct.fields) {
+ Entity *f = bt->Struct.fields[j];
+ String fname = f->token.string;
+
+ unsigned field_line = 0;
+ LLVMDIFlags field_flags = LLVMDIFlagZero;
+ GB_ASSERT(bt->Struct.offsets != nullptr);
+ u64 offset_in_bits = 8*cast(u64)bt->Struct.offsets[j];
+
+ elements[j] = LLVMDIBuilderCreateMemberType(
+ m->debug_builder,
+ member_scope,
+ cast(char const *)fname.text, cast(size_t)fname.len,
+ file, field_line,
+ 8*cast(u64)type_size_of(f->type), 8*cast(u32)type_align_of(f->type),
+ offset_in_bits,
+ field_flags,
+ lb_debug_type(m, f->type)
+ );
+ }
+
+ LLVMMetadataRef final_decl = nullptr;
+ if (tag == DW_TAG_union_type) {
+ final_decl = LLVMDIBuilderCreateUnionType(
+ m->debug_builder, scope,
+ cast(char const*)name.text, cast(size_t)name.len,
+ file, line,
+ size_in_bits, align_in_bits,
+ LLVMDIFlagZero,
+ elements, element_count,
+ 0,
+ "", 0
+ );
+ } else {
+ final_decl = LLVMDIBuilderCreateStructType(
+ m->debug_builder, scope,
+ cast(char const *)name.text, cast(size_t)name.len,
+ file, line,
+ size_in_bits, align_in_bits,
+ LLVMDIFlagZero,
+ nullptr,
+ elements, element_count,
+ 0,
+ nullptr,
+ "", 0
+ );
+ }
+
+ LLVMMetadataReplaceAllUsesWith(temp_forward_decl, final_decl);
+ lb_set_llvm_metadata(m, type, final_decl);
+ return final_decl;
+}
+
+gb_internal LLVMMetadataRef lb_debug_slice(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) {
+ Type *bt = base_type(type);
+ GB_ASSERT(bt->kind == Type_Slice);
+
+ unsigned const ptr_bits = cast(unsigned)(8*build_context.ptr_size);
+
+ u64 size_in_bits = 8*type_size_of(bt);
+ u32 align_in_bits = 8*cast(u32)type_align_of(bt);
+
+ LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType(
+ m->debug_builder, DW_TAG_structure_type,
+ cast(char const *)name.text, cast(size_t)name.len,
+ scope, file, line, 0, size_in_bits, align_in_bits, LLVMDIFlagZero, "", 0
+ );
+
+ lb_set_llvm_metadata(m, type, temp_forward_decl);
+
+ unsigned element_count = 2;
+ LLVMMetadataRef elements[2];
+
+ // LLVMMetadataRef member_scope = lb_get_llvm_metadata(m, bt->Slice.scope);
+ LLVMMetadataRef member_scope = nullptr;
+
+ Type *elem_type = alloc_type_pointer(bt->Slice.elem);
+ elements[0] = LLVMDIBuilderCreateMemberType(
+ m->debug_builder, member_scope,
+ "data", 4,
+ file, line,
+ 8*cast(u64)type_size_of(elem_type), 8*cast(u32)type_align_of(elem_type),
+ 0,
+ LLVMDIFlagZero, lb_debug_type(m, elem_type)
+ );
+
+ elements[1] = LLVMDIBuilderCreateMemberType(
+ m->debug_builder, member_scope,
+ "len", 3,
+ file, line,
+ 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
+ ptr_bits,
+ LLVMDIFlagZero, lb_debug_type(m, t_int)
+ );
+
+ LLVMMetadataRef final_decl = LLVMDIBuilderCreateStructType(
+ m->debug_builder, scope,
+ cast(char const *)name.text, cast(size_t)name.len,
+ file, line,
+ size_in_bits, align_in_bits,
+ LLVMDIFlagZero,
+ nullptr,
+ elements, element_count,
+ 0,
+ nullptr,
+ "", 0
+ );
+
+ LLVMMetadataReplaceAllUsesWith(temp_forward_decl, final_decl);
+ lb_set_llvm_metadata(m, type, final_decl);
+ return final_decl;
+}
+
+gb_internal LLVMMetadataRef lb_debug_dynamic_array(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) {
+ Type *bt = base_type(type);
+ GB_ASSERT(bt->kind == Type_DynamicArray);
+
+ unsigned const ptr_bits = cast(unsigned)(8*build_context.ptr_size);
+ unsigned const int_bits = cast(unsigned)(8*build_context.int_size);
+
+ u64 size_in_bits = 8*type_size_of(bt);
+ u32 align_in_bits = 8*cast(u32)type_align_of(bt);
+
+ LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType(
+ m->debug_builder, DW_TAG_structure_type,
+ cast(char const *)name.text, cast(size_t)name.len,
+ scope, file, line, 0, size_in_bits, align_in_bits, LLVMDIFlagZero, "", 0
+ );
+
+ lb_set_llvm_metadata(m, type, temp_forward_decl);
+
+ unsigned element_count = 4;
+ LLVMMetadataRef elements[4];
+
+ // LLVMMetadataRef member_scope = lb_get_llvm_metadata(m, bt->DynamicArray.scope);
+ LLVMMetadataRef member_scope = nullptr;
+
+ Type *elem_type = alloc_type_pointer(bt->DynamicArray.elem);
+ elements[0] = LLVMDIBuilderCreateMemberType(
+ m->debug_builder, member_scope,
+ "data", 4,
+ file, line,
+ 8*cast(u64)type_size_of(elem_type), 8*cast(u32)type_align_of(elem_type),
+ 0,
+ LLVMDIFlagZero, lb_debug_type(m, elem_type)
+ );
+
+ elements[1] = LLVMDIBuilderCreateMemberType(
+ m->debug_builder, member_scope,
+ "len", 3,
+ file, line,
+ 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
+ ptr_bits,
+ LLVMDIFlagZero, lb_debug_type(m, t_int)
+ );
+
+ elements[2] = LLVMDIBuilderCreateMemberType(
+ m->debug_builder, member_scope,
+ "cap", 3,
+ file, line,
+ 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
+ ptr_bits+int_bits,
+ LLVMDIFlagZero, lb_debug_type(m, t_int)
+ );
+
+ elements[3] = LLVMDIBuilderCreateMemberType(
+ m->debug_builder, member_scope,
+ "allocator", 9,
+ file, line,
+ 8*cast(u64)type_size_of(t_allocator), 8*cast(u32)type_align_of(t_allocator),
+ ptr_bits+int_bits+int_bits,
+ LLVMDIFlagZero, lb_debug_type(m, t_allocator)
+ );
+
+ LLVMMetadataRef final_decl = LLVMDIBuilderCreateStructType(
+ m->debug_builder, scope,
+ cast(char const *)name.text, cast(size_t)name.len,
+ file, line,
+ size_in_bits, align_in_bits,
+ LLVMDIFlagZero,
+ nullptr,
+ elements, element_count,
+ 0,
+ nullptr,
+ "", 0
+ );
+
+ LLVMMetadataReplaceAllUsesWith(temp_forward_decl, final_decl);
+ lb_set_llvm_metadata(m, type, final_decl);
+ return final_decl;
+}
+
+gb_internal LLVMMetadataRef lb_debug_union(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) {
+ Type *bt = base_type(type);
+ GB_ASSERT(bt->kind == Type_Union);
+
+ u64 size_in_bits = 8*type_size_of(bt);
+ u32 align_in_bits = 8*cast(u32)type_align_of(bt);
+
+ LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType(
+ m->debug_builder, DW_TAG_union_type,
+ cast(char const *)name.text, cast(size_t)name.len,
+ scope, file, line, 0, size_in_bits, align_in_bits, LLVMDIFlagZero, "", 0
+ );
+
+ lb_set_llvm_metadata(m, type, temp_forward_decl);
+
+ isize index_offset = 1;
+ if (is_type_union_maybe_pointer(bt)) {
+ index_offset = 0;
+ }
+
+ LLVMMetadataRef member_scope = lb_get_llvm_metadata(m, bt->Union.scope);
+ unsigned element_count = cast(unsigned)bt->Union.variants.count;
+ if (index_offset > 0) {
+ element_count += 1;
+ }
+
+ LLVMMetadataRef *elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
+
+ if (index_offset > 0) {
+ Type *tag_type = union_tag_type(bt);
+ u64 offset_in_bits = 8*cast(u64)bt->Union.variant_block_size;
+
+ elements[0] = LLVMDIBuilderCreateMemberType(
+ m->debug_builder, member_scope,
+ "tag", 3,
+ file, line,
+ 8*cast(u64)type_size_of(tag_type), 8*cast(u32)type_align_of(tag_type),
+ offset_in_bits,
+ LLVMDIFlagZero, lb_debug_type(m, tag_type)
+ );
+ }
+
+ for_array(j, bt->Union.variants) {
+ Type *variant = bt->Union.variants[j];
+
+ unsigned field_index = cast(unsigned)(index_offset+j);
+
+ char name[16] = {};
+ gb_snprintf(name, gb_size_of(name), "v%u", field_index);
+ isize name_len = gb_strlen(name);
+
+ elements[field_index] = LLVMDIBuilderCreateMemberType(
+ m->debug_builder, member_scope,
+ name, name_len,
+ file, line,
+ 8*cast(u64)type_size_of(variant), 8*cast(u32)type_align_of(variant),
+ 0,
+ LLVMDIFlagZero, lb_debug_type(m, variant)
+ );
+ }
+
+ LLVMMetadataRef final_decl = LLVMDIBuilderCreateUnionType(
+ m->debug_builder,
+ scope,
+ cast(char const *)name.text, cast(size_t)name.len,
+ file, line,
+ size_in_bits, align_in_bits,
+ LLVMDIFlagZero,
+ elements,
+ element_count,
+ 0,
+ "", 0
+ );
+
+ LLVMMetadataReplaceAllUsesWith(temp_forward_decl, final_decl);
+ lb_set_llvm_metadata(m, type, final_decl);
+ return final_decl;
+}
+
+gb_internal LLVMMetadataRef lb_debug_bitset(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) {
+ Type *bt = base_type(type);
+ GB_ASSERT(bt->kind == Type_BitSet);
+
+ u64 size_in_bits = 8*type_size_of(bt);
+ u32 align_in_bits = 8*cast(u32)type_align_of(bt);
+
+ LLVMMetadataRef bit_set_field_type = lb_debug_type(m, t_bool);
+
+ unsigned element_count = 0;
+ LLVMMetadataRef *elements = nullptr;
+
+ Type *elem = base_type(bt->BitSet.elem);
+ if (elem->kind == Type_Enum) {
+ element_count = cast(unsigned)elem->Enum.fields.count;
+ elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
+
+ for_array(i, elem->Enum.fields) {
+ Entity *f = elem->Enum.fields[i];
+ GB_ASSERT(f->kind == Entity_Constant);
+ i64 val = exact_value_to_i64(f->Constant.value);
+ String field_name = f->token.string;
+ u64 offset_in_bits = cast(u64)(val - bt->BitSet.lower);
+ elements[i] = LLVMDIBuilderCreateBitFieldMemberType(
+ m->debug_builder,
+ scope,
+ cast(char const *)field_name.text, field_name.len,
+ file, line,
+ 1,
+ offset_in_bits,
+ 0,
+ LLVMDIFlagZero,
+ bit_set_field_type
+ );
+ }
+ } else {
+ char name[32] = {};
+
+ GB_ASSERT(is_type_integer(elem));
+ i64 count = bt->BitSet.upper - bt->BitSet.lower + 1;
+ GB_ASSERT(0 <= count);
+
+ element_count = cast(unsigned)count;
+ elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
+
+ for (unsigned i = 0; i < element_count; i++) {
+ u64 offset_in_bits = i;
+ i64 val = bt->BitSet.lower + cast(i64)i;
+ gb_snprintf(name, gb_count_of(name), "%lld", cast(long long)val);
+ elements[i] = LLVMDIBuilderCreateBitFieldMemberType(
+ m->debug_builder,
+ scope,
+ name, gb_strlen(name),
+ file, line,
+ 1,
+ offset_in_bits,
+ 0,
+ LLVMDIFlagZero,
+ bit_set_field_type
+ );
+ }
+ }
+
+ LLVMMetadataRef final_decl = LLVMDIBuilderCreateUnionType(
+ m->debug_builder,
+ scope,
+ cast(char const *)name.text, cast(size_t)name.len,
+ file, line,
+ size_in_bits, align_in_bits,
+ LLVMDIFlagZero,
+ elements,
+ element_count,
+ 0,
+ "", 0
+ );
+ lb_set_llvm_metadata(m, type, final_decl);
+ return final_decl;
+}
+
+gb_internal LLVMMetadataRef lb_debug_enum(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) {
+ Type *bt = base_type(type);
+ GB_ASSERT(bt->kind == Type_Enum);
+
+ u64 size_in_bits = 8*type_size_of(bt);
+ u32 align_in_bits = 8*cast(u32)type_align_of(bt);
+
+ unsigned element_count = cast(unsigned)bt->Enum.fields.count;
+ LLVMMetadataRef *elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
+
+ Type *bt_enum = base_enum_type(bt);
+ LLVMBool is_unsigned = is_type_unsigned(bt_enum);
+ for (unsigned i = 0; i < element_count; i++) {
+ Entity *f = bt->Enum.fields[i];
+ GB_ASSERT(f->kind == Entity_Constant);
+ String enum_name = f->token.string;
+ i64 value = exact_value_to_i64(f->Constant.value);
+ elements[i] = LLVMDIBuilderCreateEnumerator(m->debug_builder, cast(char const *)enum_name.text, cast(size_t)enum_name.len, value, is_unsigned);
+ }
+
+ LLVMMetadataRef class_type = lb_debug_type(m, bt_enum);
+ LLVMMetadataRef final_decl = LLVMDIBuilderCreateEnumerationType(
+ m->debug_builder,
+ scope,
+ cast(char const *)name.text, cast(size_t)name.len,
+ file, line,
+ size_in_bits, align_in_bits,
+ elements, element_count,
+ class_type
+ );
+ lb_set_llvm_metadata(m, type, final_decl);
+ return final_decl;
+}
gb_internal LLVMMetadataRef lb_debug_type_basic_type(lbModule *m, String const &name, u64 size_in_bits, LLVMDWARFTypeEncoding encoding, LLVMDIFlags flags = LLVMDIFlagZero) {
LLVMMetadataRef basic_type = LLVMDIBuilderCreateBasicType(m->debug_builder, cast(char const *)name.text, name.len, size_in_bits, encoding, flags);
@@ -329,53 +738,19 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
return LLVMDIBuilderCreateTypedef(m->debug_builder, array_type, name, gb_string_length(name), nullptr, 0, nullptr, cast(u32)(8*type_align_of(type)));
}
+ case Type_Map: {
+ Type *bt = base_type(type->Map.debug_metadata_type);
+ GB_ASSERT(bt->kind == Type_Struct);
- case Type_Struct:
- case Type_Union:
- case Type_Slice:
- case Type_DynamicArray:
- case Type_Map:
- case Type_BitSet:
- {
- unsigned tag = DW_TAG_structure_type;
- if (is_type_raw_union(type) || is_type_union(type)) {
- tag = DW_TAG_union_type;
- }
- u64 size_in_bits = cast(u64)(8*type_size_of(type));
- u32 align_in_bits = cast(u32)(8*type_size_of(type));
- LLVMDIFlags flags = LLVMDIFlagZero;
+ return lb_debug_struct(m, type, bt, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0);
+ }
- LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType(
- m->debug_builder, tag, "", 0, nullptr, nullptr, 0, 0, size_in_bits, align_in_bits, flags, "", 0
- );
- lbIncompleteDebugType idt = {};
- idt.type = type;
- idt.metadata = temp_forward_decl;
-
- array_add(&m->debug_incomplete_types, idt);
- lb_set_llvm_metadata(m, type, temp_forward_decl);
- return temp_forward_decl;
- }
-
- case Type_Enum:
- {
- LLVMMetadataRef scope = nullptr;
- LLVMMetadataRef file = nullptr;
- unsigned line = 0;
- unsigned element_count = cast(unsigned)type->Enum.fields.count;
- LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count);
- Type *bt = base_enum_type(type);
- LLVMBool is_unsigned = is_type_unsigned(bt);
- for (unsigned i = 0; i < element_count; i++) {
- Entity *f = type->Enum.fields[i];
- GB_ASSERT(f->kind == Entity_Constant);
- String name = f->token.string;
- i64 value = exact_value_to_i64(f->Constant.value);
- elements[i] = LLVMDIBuilderCreateEnumerator(m->debug_builder, cast(char const *)name.text, cast(size_t)name.len, value, is_unsigned);
- }
- LLVMMetadataRef class_type = lb_debug_type(m, bt);
- return LLVMDIBuilderCreateEnumerationType(m->debug_builder, scope, "", 0, file, line, 8*type_size_of(type), 8*cast(unsigned)type_align_of(type), elements, element_count, class_type);
- }
+ case Type_Struct: return lb_debug_struct( m, type, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0);
+ case Type_Slice: return lb_debug_slice( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0);
+ case Type_DynamicArray: return lb_debug_dynamic_array(m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0);
+ case Type_Union: return lb_debug_union( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0);
+ case Type_BitSet: return lb_debug_bitset( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0);
+ case Type_Enum: return lb_debug_enum( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0);
case Type_Tuple:
if (type->Tuple.variables.count == 1) {
@@ -539,7 +914,6 @@ gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
unsigned line = 0;
LLVMMetadataRef scope = nullptr;
-
if (type->Named.type_name != nullptr) {
Entity *e = type->Named.type_name;
scope = lb_get_base_scope_metadata(m, e->scope);
@@ -548,456 +922,48 @@ gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
}
line = cast(unsigned)e->token.pos.line;
}
- // TODO(bill): location data for Type_Named
- u64 size_in_bits = 8*type_size_of(type);
- u32 align_in_bits = 8*cast(u32)type_align_of(type);
String name = type->Named.name;
- char const *name_text = cast(char const *)name.text;
- size_t name_len = cast(size_t)name.len;
- unsigned tag = DW_TAG_structure_type;
- if (is_type_raw_union(type) || is_type_union(type)) {
- tag = DW_TAG_union_type;
+ if (type->Named.type_name && type->Named.type_name->pkg && type->Named.type_name->pkg->name.len != 0) {
+ name = concatenate3_strings(temporary_allocator(), type->Named.type_name->pkg->name, str_lit("."), type->Named.name);
}
- LLVMDIFlags flags = LLVMDIFlagZero;
Type *bt = base_type(type->Named.base);
- lbIncompleteDebugType idt = {};
- idt.type = type;
-
switch (bt->kind) {
- case Type_Enum:
- {
- unsigned line = 0;
- unsigned element_count = cast(unsigned)bt->Enum.fields.count;
- LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count);
- Type *ct = base_enum_type(type);
- LLVMBool is_unsigned = is_type_unsigned(ct);
- for (unsigned i = 0; i < element_count; i++) {
- Entity *f = bt->Enum.fields[i];
- GB_ASSERT(f->kind == Entity_Constant);
- String name = f->token.string;
- i64 value = exact_value_to_i64(f->Constant.value);
- elements[i] = LLVMDIBuilderCreateEnumerator(m->debug_builder, cast(char const *)name.text, cast(size_t)name.len, value, is_unsigned);
- }
- LLVMMetadataRef class_type = lb_debug_type(m, ct);
- return LLVMDIBuilderCreateEnumerationType(m->debug_builder, scope, name_text, name_len, file, line, 8*type_size_of(type), 8*cast(unsigned)type_align_of(type), elements, element_count, class_type);
- }
+ default: {
+ u32 align_in_bits = 8*cast(u32)type_align_of(type);
+ LLVMMetadataRef debug_bt = lb_debug_type(m, bt);
+ LLVMMetadataRef final_decl = LLVMDIBuilderCreateTypedef(
+ m->debug_builder,
+ debug_bt,
+ cast(char const *)name.text, cast(size_t)name.len,
+ file, line, scope, align_in_bits
+ );
+ lb_set_llvm_metadata(m, type, final_decl);
+ return final_decl;
+ }
+ case Type_Map: {
+ bt = base_type(bt->Map.debug_metadata_type);
+ GB_ASSERT(bt->kind == Type_Struct);
+ return lb_debug_struct(m, type, bt, name, scope, file, line);
+ }
- default:
- {
- LLVMMetadataRef debug_bt = lb_debug_type(m, bt);
- LLVMMetadataRef final_decl = LLVMDIBuilderCreateTypedef(m->debug_builder, debug_bt, name_text, name_len, file, line, scope, align_in_bits);
- lb_set_llvm_metadata(m, type, final_decl);
- return final_decl;
- }
-
- case Type_Slice:
- case Type_DynamicArray:
- case Type_Map:
- case Type_Struct:
- case Type_Union:
- case Type_BitSet:
- {
- LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType(
- m->debug_builder, tag, name_text, name_len, nullptr, nullptr, 0, 0, size_in_bits, align_in_bits, flags, "", 0
- );
- idt.metadata = temp_forward_decl;
-
- array_add(&m->debug_incomplete_types, idt);
- lb_set_llvm_metadata(m, type, temp_forward_decl);
-
- LLVMMetadataRef dummy = nullptr;
- switch (bt->kind) {
- case Type_Slice:
- dummy = lb_debug_type(m, bt->Slice.elem);
- dummy = lb_debug_type(m, alloc_type_pointer(bt->Slice.elem));
- dummy = lb_debug_type(m, t_int);
- break;
- case Type_DynamicArray:
- dummy = lb_debug_type(m, bt->DynamicArray.elem);
- dummy = lb_debug_type(m, alloc_type_pointer(bt->DynamicArray.elem));
- dummy = lb_debug_type(m, t_int);
- dummy = lb_debug_type(m, t_allocator);
- break;
- case Type_Map:
- dummy = lb_debug_type(m, bt->Map.key);
- dummy = lb_debug_type(m, bt->Map.value);
- dummy = lb_debug_type(m, t_int);
- dummy = lb_debug_type(m, t_allocator);
- dummy = lb_debug_type(m, t_uintptr);
- break;
- case Type_BitSet:
- if (bt->BitSet.elem) dummy = lb_debug_type(m, bt->BitSet.elem);
- if (bt->BitSet.underlying) dummy = lb_debug_type(m, bt->BitSet.underlying);
- break;
- }
-
- return temp_forward_decl;
- }
+ case Type_Struct: return lb_debug_struct(m, type, base_type(type), name, scope, file, line);
+ case Type_Slice: return lb_debug_slice(m, type, name, scope, file, line);
+ case Type_DynamicArray: return lb_debug_dynamic_array(m, type, name, scope, file, line);
+ case Type_Union: return lb_debug_union(m, type, name, scope, file, line);
+ case Type_BitSet: return lb_debug_bitset(m, type, name, scope, file, line);
+ case Type_Enum: return lb_debug_enum(m, type, name, scope, file, line);
}
}
-
LLVMMetadataRef dt = lb_debug_type_internal(m, type);
lb_set_llvm_metadata(m, type, dt);
return dt;
}
-gb_internal void lb_debug_complete_types(lbModule *m) {
- unsigned const int_bits = cast(unsigned)(8*build_context.int_size);
-
- for_array(debug_incomplete_type_index, m->debug_incomplete_types) {
- TEMPORARY_ALLOCATOR_GUARD();
-
- // NOTE(laytan): don't make this a pointer, the array could resize while in this iteration
- // and cause a use-after-free at the end.
- auto const idt = m->debug_incomplete_types[debug_incomplete_type_index];
- GB_ASSERT(idt.type != nullptr);
- GB_ASSERT(idt.metadata != nullptr);
-
- Type *t = idt.type;
- Type *bt = base_type(t);
-
- LLVMMetadataRef parent_scope = nullptr;
- LLVMMetadataRef file = nullptr;
- unsigned line_number = 0;
- u64 size_in_bits = 8*type_size_of(t);
- u32 align_in_bits = cast(u32)(8*type_align_of(t));
- LLVMDIFlags flags = LLVMDIFlagZero;
-
- LLVMMetadataRef derived_from = nullptr;
-
- LLVMMetadataRef *elements = nullptr;
- unsigned element_count = 0;
-
-
- unsigned runtime_lang = 0; // Objective-C runtime version
- char const *unique_id = "";
- LLVMMetadataRef vtable_holder = nullptr;
- size_t unique_id_len = 0;
-
-
- LLVMMetadataRef record_scope = nullptr;
-
- switch (bt->kind) {
- case Type_Slice:
- case Type_DynamicArray:
- case Type_Map:
- case Type_Struct:
- case Type_Union:
- case Type_BitSet: {
- bool is_union = is_type_raw_union(bt) || is_type_union(bt);
-
- String name = str_lit("");
- if (t->kind == Type_Named) {
- name = t->Named.name;
- if (t->Named.type_name && t->Named.type_name->pkg && t->Named.type_name->pkg->name.len != 0) {
- name = concatenate3_strings(temporary_allocator(), t->Named.type_name->pkg->name, str_lit("."), t->Named.name);
- }
-
- LLVMMetadataRef file = nullptr;
- unsigned line = 0;
- LLVMMetadataRef file_scope = nullptr;
-
- if (t->Named.type_name != nullptr) {
- Entity *e = t->Named.type_name;
- file_scope = lb_get_llvm_metadata(m, e->scope);
- if (file_scope != nullptr) {
- file = LLVMDIScopeGetFile(file_scope);
- }
- line = cast(unsigned)e->token.pos.line;
- }
- // TODO(bill): location data for Type_Named
-
- } else {
- name = make_string_c(type_to_string(t, temporary_allocator()));
- }
-
-
-
- switch (bt->kind) {
- case Type_Slice:
- element_count = 2;
- elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
- #if defined(GB_SYSTEM_WINDOWS)
- elements[0] = lb_debug_struct_field(m, str_lit("data"), alloc_type_pointer(bt->Slice.elem), 0*int_bits);
- #else
- // FIX HACK TODO(bill): For some reason this causes a crash in *nix systems due to the reference counting
- // of the debug type information
- elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0*int_bits);
- #endif
- elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, 1*int_bits);
- break;
- case Type_DynamicArray:
- element_count = 4;
- elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
- #if defined(GB_SYSTEM_WINDOWS)
- elements[0] = lb_debug_struct_field(m, str_lit("data"), alloc_type_pointer(bt->DynamicArray.elem), 0*int_bits);
- #else
- // FIX HACK TODO(bill): For some reason this causes a crash in *nix systems due to the reference counting
- // of the debug type information
- elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0*int_bits);
- #endif
- elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, 1*int_bits);
- elements[2] = lb_debug_struct_field(m, str_lit("cap"), t_int, 2*int_bits);
- elements[3] = lb_debug_struct_field(m, str_lit("allocator"), t_allocator, 3*int_bits);
- break;
-
- case Type_Map:
- GB_ASSERT(t_raw_map != nullptr);
- bt = base_type(bt->Map.debug_metadata_type);
- // bt = base_type(t_raw_map);
- GB_ASSERT(bt->kind == Type_Struct);
- /*fallthrough*/
- case Type_Struct:
- if (file == nullptr) {
- if (bt->Struct.node) {
- file = lb_get_llvm_metadata(m, bt->Struct.node->file());
- line_number = cast(unsigned)ast_token(bt->Struct.node).pos.line;
- }
- }
-
- type_set_offsets(bt);
- {
- isize element_offset = 0;
- record_scope = lb_get_llvm_metadata(m, bt->Struct.scope);
- switch (bt->Struct.soa_kind) {
- case StructSoa_Slice: element_offset = 1; break;
- case StructSoa_Dynamic: element_offset = 3; break;
- }
- element_count = cast(unsigned)(bt->Struct.fields.count + element_offset);
- elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
-
- isize field_size_bits = 8*type_size_of(bt) - element_offset*int_bits;
-
- switch (bt->Struct.soa_kind) {
- case StructSoa_Slice:
- elements[0] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- ".len", 4,
- file, 0,
- 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
- field_size_bits,
- LLVMDIFlagZero, lb_debug_type(m, t_int)
- );
- break;
- case StructSoa_Dynamic:
- elements[0] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- ".len", 4,
- file, 0,
- 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
- field_size_bits + 0*int_bits,
- LLVMDIFlagZero, lb_debug_type(m, t_int)
- );
- elements[1] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- ".cap", 4,
- file, 0,
- 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
- field_size_bits + 1*int_bits,
- LLVMDIFlagZero, lb_debug_type(m, t_int)
- );
- elements[2] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- ".allocator", 10,
- file, 0,
- 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
- field_size_bits + 2*int_bits,
- LLVMDIFlagZero, lb_debug_type(m, t_allocator)
- );
- break;
- }
-
- for_array(j, bt->Struct.fields) {
- Entity *f = bt->Struct.fields[j];
- String fname = f->token.string;
-
- unsigned field_line = 0;
- LLVMDIFlags field_flags = LLVMDIFlagZero;
- GB_ASSERT(bt->Struct.offsets != nullptr);
- u64 offset_in_bits = 8*cast(u64)bt->Struct.offsets[j];
-
- elements[element_offset+j] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- cast(char const *)fname.text, cast(size_t)fname.len,
- file, field_line,
- 8*cast(u64)type_size_of(f->type), 8*cast(u32)type_align_of(f->type),
- offset_in_bits,
- field_flags, lb_debug_type(m, f->type)
- );
- }
- }
- break;
- case Type_Union:
- {
- if (file == nullptr) {
- GB_ASSERT(bt->Union.node != nullptr);
- file = lb_get_llvm_metadata(m, bt->Union.node->file());
- line_number = cast(unsigned)ast_token(bt->Union.node).pos.line;
- }
-
- isize index_offset = 1;
- if (is_type_union_maybe_pointer(bt)) {
- index_offset = 0;
- }
- record_scope = lb_get_llvm_metadata(m, bt->Union.scope);
- element_count = cast(unsigned)bt->Union.variants.count;
- if (index_offset > 0) {
- element_count += 1;
- }
-
- elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
- if (index_offset > 0) {
- Type *tag_type = union_tag_type(bt);
- unsigned field_line = 0;
- u64 offset_in_bits = 8*cast(u64)bt->Union.variant_block_size;
- LLVMDIFlags field_flags = LLVMDIFlagZero;
-
- elements[0] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- "tag", 3,
- file, field_line,
- 8*cast(u64)type_size_of(tag_type), 8*cast(u32)type_align_of(tag_type),
- offset_in_bits,
- field_flags, lb_debug_type(m, tag_type)
- );
- }
-
- for_array(j, bt->Union.variants) {
- Type *variant = bt->Union.variants[j];
-
- unsigned field_index = cast(unsigned)(index_offset+j);
-
- char name[16] = {};
- gb_snprintf(name, gb_size_of(name), "v%u", field_index);
- isize name_len = gb_strlen(name);
-
- unsigned field_line = 0;
- LLVMDIFlags field_flags = LLVMDIFlagZero;
- u64 offset_in_bits = 0;
-
- elements[field_index] = LLVMDIBuilderCreateMemberType(
- m->debug_builder, record_scope,
- name, name_len,
- file, field_line,
- 8*cast(u64)type_size_of(variant), 8*cast(u32)type_align_of(variant),
- offset_in_bits,
- field_flags, lb_debug_type(m, variant)
- );
- }
- }
- break;
-
- case Type_BitSet:
- {
- if (file == nullptr) {
- GB_ASSERT(bt->BitSet.node != nullptr);
- file = lb_get_llvm_metadata(m, bt->BitSet.node->file());
- line_number = cast(unsigned)ast_token(bt->BitSet.node).pos.line;
- }
-
- LLVMMetadataRef bit_set_field_type = lb_debug_type(m, t_bool);
- LLVMMetadataRef scope = file;
-
- Type *elem = base_type(bt->BitSet.elem);
- if (elem->kind == Type_Enum) {
- element_count = cast(unsigned)elem->Enum.fields.count;
- elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
- for_array(i, elem->Enum.fields) {
- Entity *f = elem->Enum.fields[i];
- GB_ASSERT(f->kind == Entity_Constant);
- i64 val = exact_value_to_i64(f->Constant.value);
- String name = f->token.string;
- u64 offset_in_bits = cast(u64)(val - bt->BitSet.lower);
- elements[i] = LLVMDIBuilderCreateBitFieldMemberType(
- m->debug_builder,
- scope,
- cast(char const *)name.text, name.len,
- file, line_number,
- 1,
- offset_in_bits,
- 0,
- LLVMDIFlagZero,
- bit_set_field_type
- );
- }
- } else {
-
- char name[32] = {};
-
- GB_ASSERT(is_type_integer(elem));
- i64 count = bt->BitSet.upper - bt->BitSet.lower + 1;
- GB_ASSERT(0 <= count);
-
- element_count = cast(unsigned)count;
- elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
- for (unsigned i = 0; i < element_count; i++) {
- u64 offset_in_bits = i;
- i64 val = bt->BitSet.lower + cast(i64)i;
- gb_snprintf(name, gb_count_of(name), "%lld", cast(long long)val);
- elements[i] = LLVMDIBuilderCreateBitFieldMemberType(
- m->debug_builder,
- scope,
- name, gb_strlen(name),
- file, line_number,
- 1,
- offset_in_bits,
- 0,
- LLVMDIFlagZero,
- bit_set_field_type
- );
- }
- }
- }
- }
-
-
- LLVMMetadataRef final_metadata = nullptr;
- if (is_union) {
- final_metadata = LLVMDIBuilderCreateUnionType(
- m->debug_builder,
- parent_scope,
- cast(char const *)name.text, cast(size_t)name.len,
- file, line_number,
- size_in_bits, align_in_bits,
- flags,
- elements, element_count,
- runtime_lang,
- unique_id, unique_id_len
- );
- } else {
- final_metadata = LLVMDIBuilderCreateStructType(
- m->debug_builder,
- parent_scope,
- cast(char const *)name.text, cast(size_t)name.len,
- file, line_number,
- size_in_bits, align_in_bits,
- flags,
- derived_from,
- elements, element_count,
- runtime_lang,
- vtable_holder,
- unique_id, unique_id_len
- );
- }
-
- LLVMMetadataReplaceAllUsesWith(idt.metadata, final_metadata);
- lb_set_llvm_metadata(m, idt.type, final_metadata);
- } break;
- default:
- GB_PANIC("invalid incomplete debug type");
- break;
- }
- }
- array_clear(&m->debug_incomplete_types);
-}
-
-
-
gb_internal void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token) {
if (p->debug_info == nullptr) {
return;
@@ -1267,4 +1233,4 @@ gb_internal void add_debug_info_for_global_constant_from_entity(lbGenerator *gen
add_debug_info_for_global_constant_internal_i64(m, e, dtype, v);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp
index 12949f0ab..0649150ca 100644
--- a/src/llvm_backend_expr.cpp
+++ b/src/llvm_backend_expr.cpp
@@ -1373,6 +1373,57 @@ gb_internal bool lb_is_empty_string_constant(Ast *expr) {
return false;
}
+gb_internal lbValue lb_build_binary_in(lbProcedure *p, lbValue left, lbValue right, TokenKind op) {
+ Type *rt = base_type(right.type);
+ if (is_type_pointer(rt)) {
+ right = lb_emit_load(p, right);
+ rt = base_type(type_deref(rt));
+ }
+
+ switch (rt->kind) {
+ case Type_Map:
+ {
+ lbValue map_ptr = lb_address_from_load_or_generate_local(p, right);
+ lbValue key = left;
+ lbValue ptr = lb_internal_dynamic_map_get_ptr(p, map_ptr, key);
+ if (op == Token_in) {
+ return lb_emit_conv(p, lb_emit_comp_against_nil(p, Token_NotEq, ptr), t_bool);
+ } else {
+ return lb_emit_conv(p, lb_emit_comp_against_nil(p, Token_CmpEq, ptr), t_bool);
+ }
+ }
+ break;
+ case Type_BitSet:
+ {
+ Type *key_type = rt->BitSet.elem;
+ GB_ASSERT(are_types_identical(left.type, key_type));
+
+ Type *it = bit_set_to_int(rt);
+ left = lb_emit_conv(p, left, it);
+ if (is_type_different_to_arch_endianness(it)) {
+ left = lb_emit_byte_swap(p, left, integer_endian_type_to_platform_type(it));
+ }
+
+ lbValue lower = lb_const_value(p->module, left.type, exact_value_i64(rt->BitSet.lower));
+ lbValue key = lb_emit_arith(p, Token_Sub, left, lower, left.type);
+ lbValue bit = lb_emit_arith(p, Token_Shl, lb_const_int(p->module, left.type, 1), key, left.type);
+ bit = lb_emit_conv(p, bit, it);
+
+ lbValue old_value = lb_emit_transmute(p, right, it);
+ lbValue new_value = lb_emit_arith(p, Token_And, old_value, bit, it);
+
+ if (op == Token_in) {
+ return lb_emit_conv(p, lb_emit_comp(p, Token_NotEq, new_value, lb_const_int(p->module, new_value.type, 0)), t_bool);
+ } else {
+ return lb_emit_conv(p, lb_emit_comp(p, Token_CmpEq, new_value, lb_const_int(p->module, new_value.type, 0)), t_bool);
+ }
+ }
+ break;
+ }
+ GB_PANIC("Invalid 'in' type");
+ return {};
+}
+
gb_internal lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) {
ast_node(be, BinaryExpr, expr);
@@ -1480,57 +1531,8 @@ gb_internal lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) {
{
lbValue left = lb_build_expr(p, be->left);
lbValue right = lb_build_expr(p, be->right);
- Type *rt = base_type(right.type);
- if (is_type_pointer(rt)) {
- right = lb_emit_load(p, right);
- rt = base_type(type_deref(rt));
- }
-
- switch (rt->kind) {
- case Type_Map:
- {
- lbValue map_ptr = lb_address_from_load_or_generate_local(p, right);
- lbValue key = left;
- lbValue ptr = lb_internal_dynamic_map_get_ptr(p, map_ptr, key);
- if (be->op.kind == Token_in) {
- return lb_emit_conv(p, lb_emit_comp_against_nil(p, Token_NotEq, ptr), t_bool);
- } else {
- return lb_emit_conv(p, lb_emit_comp_against_nil(p, Token_CmpEq, ptr), t_bool);
- }
- }
- break;
- case Type_BitSet:
- {
- Type *key_type = rt->BitSet.elem;
- GB_ASSERT(are_types_identical(left.type, key_type));
-
- Type *it = bit_set_to_int(rt);
- left = lb_emit_conv(p, left, it);
- if (is_type_different_to_arch_endianness(it)) {
- left = lb_emit_byte_swap(p, left, integer_endian_type_to_platform_type(it));
- }
-
- lbValue lower = lb_const_value(p->module, left.type, exact_value_i64(rt->BitSet.lower));
- lbValue key = lb_emit_arith(p, Token_Sub, left, lower, left.type);
- lbValue bit = lb_emit_arith(p, Token_Shl, lb_const_int(p->module, left.type, 1), key, left.type);
- bit = lb_emit_conv(p, bit, it);
-
- lbValue old_value = lb_emit_transmute(p, right, it);
- lbValue new_value = lb_emit_arith(p, Token_And, old_value, bit, it);
-
- if (be->op.kind == Token_in) {
- return lb_emit_conv(p, lb_emit_comp(p, Token_NotEq, new_value, lb_const_int(p->module, new_value.type, 0)), t_bool);
- } else {
- return lb_emit_conv(p, lb_emit_comp(p, Token_CmpEq, new_value, lb_const_int(p->module, new_value.type, 0)), t_bool);
- }
- }
- break;
- default:
- GB_PANIC("Invalid 'in' type");
- }
- break;
+ return lb_build_binary_in(p, left, right, be->op.kind);
}
- break;
default:
GB_PANIC("Invalid binary expression");
break;
@@ -4675,8 +4677,10 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
if (tav.mode == Addressing_Type) { // Addressing_Type
Selection sel = lookup_field(tav.type, selector, true);
if (sel.pseudo_field) {
- GB_ASSERT(sel.entity->kind == Entity_Procedure);
- return lb_addr(lb_find_value_from_entity(p->module, sel.entity));
+ GB_ASSERT(sel.entity->kind == Entity_Procedure || sel.entity->kind == Entity_ProcGroup);
+ Entity *e = entity_of_node(sel_node);
+ GB_ASSERT(e->kind == Entity_Procedure);
+ return lb_addr(lb_find_value_from_entity(p->module, e));
}
GB_PANIC("Unreachable %.*s", LIT(selector));
}
diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp
index a77e2ad15..889cb8822 100644
--- a/src/llvm_backend_general.cpp
+++ b/src/llvm_backend_general.cpp
@@ -81,7 +81,6 @@ gb_internal void lb_init_module(lbModule *m, Checker *c) {
array_init(&m->global_procedures_and_types_to_create, a, 0, 1024);
array_init(&m->missing_procedures_to_check, a, 0, 16);
map_init(&m->debug_values);
- array_init(&m->debug_incomplete_types, a, 0, 1024);
string_map_init(&m->objc_classes);
string_map_init(&m->objc_selectors);
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index fba7eb381..8ce116715 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -578,7 +578,10 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) {
defer (param_index += 1);
if (arg_type->kind == lbArg_Ignore) {
- continue;
+ // Even though it is an ignored argument, it might still be referenced in the
+ // body.
+ lbValue dummy = lb_add_local_generated(p, e->type, false).addr;
+ lb_add_entity(p->module, e, dummy);
} else if (arg_type->kind == lbArg_Direct) {
if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) {
LLVMTypeRef param_type = lb_type(p->module, e->type);
@@ -1051,6 +1054,7 @@ gb_internal lbValue lb_emit_call(lbProcedure *p, lbValue value, Array c
Type *original_type = e->type;
lbArgType *arg = &ft->args[param_index];
if (arg->kind == lbArg_Ignore) {
+ param_index += 1;
continue;
}
@@ -3359,6 +3363,9 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) {
for (Ast *var_arg : variadic) {
lbValue arg = lb_build_expr(p, var_arg);
if (is_type_any(elem_type)) {
+ if (is_type_untyped_nil(arg.type)) {
+ arg = lb_const_nil(p->module, t_rawptr);
+ }
array_add(&args, lb_emit_conv(p, arg, c_vararg_promote_type(default_type(arg.type))));
} else {
array_add(&args, lb_emit_conv(p, arg, c_vararg_promote_type(elem_type)));
@@ -3423,6 +3430,30 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) {
if (e->kind == Entity_TypeName) {
lbValue value = lb_const_nil(p->module, e->type);
args[param_index] = value;
+ } else if (is_c_vararg && pt->variadic && pt->variadic_index == param_index) {
+ GB_ASSERT(param_index == pt->param_count-1);
+ Type *slice_type = e->type;
+ GB_ASSERT(slice_type->kind == Type_Slice);
+ Type *elem_type = slice_type->Slice.elem;
+
+ if (fv->value->kind == Ast_CompoundLit) {
+ ast_node(literal, CompoundLit, fv->value);
+ for (Ast *var_arg : literal->elems) {
+ lbValue arg = lb_build_expr(p, var_arg);
+ if (is_type_any(elem_type)) {
+ if (is_type_untyped_nil(arg.type)) {
+ arg = lb_const_nil(p->module, t_rawptr);
+ }
+ array_add(&args, lb_emit_conv(p, arg, c_vararg_promote_type(default_type(arg.type))));
+ } else {
+ array_add(&args, lb_emit_conv(p, arg, c_vararg_promote_type(elem_type)));
+ }
+ }
+ } else {
+ lbValue value = lb_build_expr(p, fv->value);
+ GB_ASSERT(!is_type_tuple(value.type));
+ array_add(&args, lb_emit_conv(p, value, c_vararg_promote_type(value.type)));
+ }
} else {
lbValue value = lb_build_expr(p, fv->value);
GB_ASSERT(!is_type_tuple(value.type));
diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp
index 4ecf70ec4..24dd321f6 100644
--- a/src/llvm_backend_stmt.cpp
+++ b/src/llvm_backend_stmt.cpp
@@ -737,6 +737,22 @@ gb_internal void lb_build_range_interval(lbProcedure *p, AstBinaryExpr *node,
lb_start_block(p, done);
}
+gb_internal lbValue lb_enum_values_slice(lbProcedure *p, Type *enum_type, i64 *enum_count_) {
+ Type *t = enum_type;
+ GB_ASSERT(is_type_enum(t));
+ t = base_type(t);
+ GB_ASSERT(t->kind == Type_Enum);
+ i64 enum_count = t->Enum.fields.count;
+
+ if (enum_count_) *enum_count_ = enum_count;
+
+ lbValue ti = lb_type_info(p, t);
+ lbValue variant = lb_emit_struct_ep(p, ti, 4);
+ lbValue eti_ptr = lb_emit_conv(p, variant, t_type_info_enum_ptr);
+ lbValue values = lb_emit_load(p, lb_emit_struct_ep(p, eti_ptr, 2));
+ return values;
+}
+
gb_internal void lb_build_range_enum(lbProcedure *p, Type *enum_type, Type *val_type, lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
lbModule *m = p->module;
@@ -744,15 +760,11 @@ gb_internal void lb_build_range_enum(lbProcedure *p, Type *enum_type, Type *val_
GB_ASSERT(is_type_enum(t));
t = base_type(t);
Type *core_elem = core_type(t);
- GB_ASSERT(t->kind == Type_Enum);
- i64 enum_count = t->Enum.fields.count;
- lbValue max_count = lb_const_int(m, t_int, enum_count);
+ i64 enum_count = 0;
- lbValue ti = lb_type_info(p, t);
- lbValue variant = lb_emit_struct_ep(p, ti, 4);
- lbValue eti_ptr = lb_emit_conv(p, variant, t_type_info_enum_ptr);
- lbValue values = lb_emit_load(p, lb_emit_struct_ep(p, eti_ptr, 2));
+ lbValue values = lb_enum_values_slice(p, enum_type, &enum_count);
lbValue values_data = lb_slice_elem(p, values);
+ lbValue max_count = lb_const_int(m, t_int, enum_count);
lbAddr offset_ = lb_add_local_generated(p, t_int, false);
lb_addr_store(p, offset_, lb_const_int(m, t_int, 0));
@@ -1052,6 +1064,74 @@ gb_internal void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *sc
case Type_Tuple:
lb_build_range_tuple(p, expr, val0_type, val1_type, &val, &key, &loop, &done);
break;
+
+ case Type_BitSet: {
+ lbModule *m = p->module;
+
+ lbValue the_set = lb_build_expr(p, expr);
+ if (is_type_pointer(type_deref(the_set.type))) {
+ the_set = lb_emit_load(p, the_set);
+ }
+
+ Type *elem = et->BitSet.elem;
+ if (is_type_enum(elem)) {
+ i64 enum_count = 0;
+ lbValue values = lb_enum_values_slice(p, elem, &enum_count);
+ lbValue values_data = lb_slice_elem(p, values);
+ lbValue max_count = lb_const_int(m, t_int, enum_count);
+
+ lbAddr offset_ = lb_add_local_generated(p, t_int, false);
+ lb_addr_store(p, offset_, lb_const_int(m, t_int, 0));
+
+ loop = lb_create_block(p, "for.bit_set.enum.loop");
+ lb_emit_jump(p, loop);
+ lb_start_block(p, loop);
+
+ lbBlock *body_check = lb_create_block(p, "for.bit_set.enum.body-check");
+ lbBlock *body = lb_create_block(p, "for.bit_set.enum.body");
+ done = lb_create_block(p, "for.bit_set.enum.done");
+
+ lbValue offset = lb_addr_load(p, offset_);
+ lbValue cond = lb_emit_comp(p, Token_Lt, offset, max_count);
+ lb_emit_if(p, cond, body_check, done);
+ lb_start_block(p, body_check);
+
+ lbValue val_ptr = lb_emit_ptr_offset(p, values_data, offset);
+ lb_emit_increment(p, offset_.addr);
+ val = lb_emit_load(p, val_ptr);
+ val = lb_emit_conv(p, val, elem);
+
+ lbValue check = lb_build_binary_in(p, val, the_set, Token_in);
+ lb_emit_if(p, check, body, loop);
+ lb_start_block(p, body);
+ } else {
+ lbAddr offset_ = lb_add_local_generated(p, t_int, false);
+ lb_addr_store(p, offset_, lb_const_int(m, t_int, et->BitSet.lower));
+
+ lbValue max_count = lb_const_int(m, t_int, et->BitSet.upper);
+
+ loop = lb_create_block(p, "for.bit_set.range.loop");
+ lb_emit_jump(p, loop);
+ lb_start_block(p, loop);
+
+ lbBlock *body_check = lb_create_block(p, "for.bit_set.range.body-check");
+ lbBlock *body = lb_create_block(p, "for.bit_set.range.body");
+ done = lb_create_block(p, "for.bit_set.range.done");
+
+ lbValue offset = lb_addr_load(p, offset_);
+ lbValue cond = lb_emit_comp(p, Token_LtEq, offset, max_count);
+ lb_emit_if(p, cond, body_check, done);
+ lb_start_block(p, body_check);
+
+ val = lb_emit_conv(p, offset, elem);
+ lb_emit_increment(p, offset_.addr);
+
+ lbValue check = lb_build_binary_in(p, val, the_set, Token_in);
+ lb_emit_if(p, check, body, loop);
+ lb_start_block(p, body);
+ }
+ break;
+ }
default:
GB_PANIC("Cannot range over %s", type_to_string(expr_type));
break;
diff --git a/src/main.cpp b/src/main.cpp
index 79c3a1670..2dbb72ca2 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -296,6 +296,8 @@ enum BuildFlagKind {
BuildFlag_ErrorPosStyle,
BuildFlag_MaxErrorCount,
+ BuildFlag_MinLinkLibs,
+
// internal use only
BuildFlag_InternalIgnoreLazy,
BuildFlag_InternalIgnoreLLVMBuild,
@@ -485,6 +487,8 @@ gb_internal bool parse_build_flags(Array args) {
add_flag(&build_flags, BuildFlag_ErrorPosStyle, str_lit("error-pos-style"), BuildFlagParam_String, Command_all);
add_flag(&build_flags, BuildFlag_MaxErrorCount, str_lit("max-error-count"), BuildFlagParam_Integer, Command_all);
+ add_flag(&build_flags, BuildFlag_MinLinkLibs, str_lit("min-link-libs"), BuildFlagParam_None, Command__does_build);
+
add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all);
add_flag(&build_flags, BuildFlag_InternalIgnoreLLVMBuild, str_lit("internal-ignore-llvm-build"),BuildFlagParam_None, Command_all);
@@ -1215,6 +1219,10 @@ gb_internal bool parse_build_flags(Array args) {
break;
}
+ case BuildFlag_MinLinkLibs:
+ build_context.min_link_libs = true;
+ break;
+
case BuildFlag_InternalIgnoreLazy:
build_context.ignore_lazy = true;
break;
@@ -2008,6 +2016,11 @@ gb_internal void print_show_help(String const arg0, String const &command) {
print_usage_line(2, "If not set, the default max error count is %d.", DEFAULT_MAX_ERROR_COLLECTOR_COUNT);
print_usage_line(0, "");
+ print_usage_line(1, "-min-link-libs");
+ print_usage_line(2, "If set, the number of linked libraries will be minimized to prevent duplications.");
+ print_usage_line(2, "This is useful for so called \"dumb\" linkers compared to \"smart\" linkers.");
+ print_usage_line(0, "");
+
print_usage_line(1, "-foreign-error-procedures");
print_usage_line(2, "States that the error procedures used in the runtime are defined in a separate translation unit.");
print_usage_line(0, "");
@@ -2694,6 +2707,9 @@ int main(int arg_count, char const **arg_ptr) {
print_all_errors();
return 1;
}
+ if (any_warnings()) {
+ print_all_errors();
+ }
MAIN_TIME_SECTION("type check");
@@ -2706,6 +2722,10 @@ int main(int arg_count, char const **arg_ptr) {
print_all_errors();
return 1;
}
+ if (any_warnings()) {
+ print_all_errors();
+ }
+
if (build_context.command_kind == Command_strip_semicolon) {
return strip_semicolons(parser);
diff --git a/src/parser.cpp b/src/parser.cpp
index 13225f622..bf16f5c9f 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -1482,7 +1482,16 @@ gb_internal Token expect_token(AstFile *f, TokenKind kind) {
if (prev.kind != kind) {
String c = token_strings[kind];
String p = token_to_string(prev);
+ begin_error_block();
syntax_error(f->curr_token, "Expected '%.*s', got '%.*s'", LIT(c), LIT(p));
+ if (kind == Token_Ident) switch (prev.kind) {
+ case Token_context:
+ error_line("\tSuggestion: 'context' is a reserved keyword, would 'ctx' suffice?\n");
+ break;
+ }
+
+ end_error_block();
+
if (prev.kind == Token_EOF) {
exit_with_errors();
}
@@ -4055,7 +4064,12 @@ gb_internal Array convert_to_ident_list(AstFile *f, Array li
case Ast_BadExpr:
break;
case Ast_Implicit:
+ begin_error_block();
syntax_error(ident, "Expected an identifier, '%.*s' which is a keyword", LIT(ident->Implicit.string));
+ if (ident->Implicit.kind == Token_context) {
+ error_line("\tSuggestion: Would 'ctx' suffice as an alternative name?\n");
+ }
+ end_error_block();
ident = ast_ident(f, blank_token);
break;
diff --git a/src/types.cpp b/src/types.cpp
index 256c654ac..97512d29b 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -768,6 +768,7 @@ gb_internal i64 type_offset_of (Type *t, i64 index, Type **field_type_=null
gb_internal gbString type_to_string (Type *type, bool shorthand=true);
gb_internal gbString type_to_string (Type *type, gbAllocator allocator, bool shorthand=true);
gb_internal i64 type_size_of_internal(Type *t, TypePath *path);
+gb_internal i64 type_align_of_internal(Type *t, TypePath *path);
gb_internal void init_map_internal_types(Type *type);
gb_internal Type * bit_set_to_int(Type *t);
gb_internal bool are_types_identical(Type *x, Type *y);
@@ -780,9 +781,6 @@ gb_internal bool is_type_slice(Type *t);
gb_internal bool is_type_integer(Type *t);
gb_internal bool type_set_offsets(Type *t);
-gb_internal i64 type_size_of_internal(Type *t, TypePath *path);
-gb_internal i64 type_align_of_internal(Type *t, TypePath *path);
-
// IMPORTANT TODO(bill): SHould this TypePath code be removed since type cycle checking is handled much earlier on?
@@ -3160,7 +3158,7 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name
mutex_lock(md->mutex);
defer (mutex_unlock(md->mutex));
for (TypeNameObjCMetadataEntry const &entry : md->type_entries) {
- GB_ASSERT(entry.entity->kind == Entity_Procedure);
+ GB_ASSERT(entry.entity->kind == Entity_Procedure || entry.entity->kind == Entity_ProcGroup);
if (entry.name == field_name) {
sel.entity = entry.entity;
sel.pseudo_field = true;
@@ -3576,8 +3574,6 @@ gb_internal Slice struct_fields_index_by_increasing_offset(gbAllocator allo
-gb_internal i64 type_size_of_internal (Type *t, TypePath *path);
-gb_internal i64 type_align_of_internal(Type *t, TypePath *path);
gb_internal i64 type_size_of(Type *t);
gb_internal i64 type_align_of(Type *t);
diff --git a/tests/core/download_assets.py b/tests/core/download_assets.py
index 50137f563..7874b7e91 100644
--- a/tests/core/download_assets.py
+++ b/tests/core/download_assets.py
@@ -4,49 +4,201 @@ import shutil
import sys
import os
import zipfile
+import hashlib
+import hmac
TEST_SUITES = ['PNG', 'XML']
DOWNLOAD_BASE_PATH = "assets/{}"
ASSETS_BASE_URL = "https://raw.githubusercontent.com/odin-lang/test-assets/master/{}/{}"
-PNG_IMAGES = [
- "basi0g01.png", "basi0g02.png", "basi0g04.png", "basi0g08.png", "basi0g16.png", "basi2c08.png",
- "basi2c16.png", "basi3p01.png", "basi3p02.png", "basi3p04.png", "basi3p08.png", "basi4a08.png",
- "basi4a16.png", "basi6a08.png", "basi6a16.png", "basn0g01.png", "basn0g02.png", "basn0g04.png",
- "basn0g08.png", "basn0g16.png", "basn2c08.png", "basn2c16.png", "basn3p01.png", "basn3p02.png",
- "basn3p04.png", "basn3p08.png", "basn4a08.png", "basn4a16.png", "basn6a08.png", "basn6a16.png",
- "bgai4a08.png", "bgai4a16.png", "bgan6a08.png", "bgan6a16.png", "bgbn4a08.png", "bggn4a16.png",
- "bgwn6a08.png", "bgyn6a16.png", "ccwn2c08.png", "ccwn3p08.png", "cdfn2c08.png", "cdhn2c08.png",
- "cdsn2c08.png", "cdun2c08.png", "ch1n3p04.png", "ch2n3p08.png", "cm0n0g04.png", "cm7n0g04.png",
- "cm9n0g04.png", "cs3n2c16.png", "cs3n3p08.png", "cs5n2c08.png", "cs5n3p08.png", "cs8n2c08.png",
- "cs8n3p08.png", "ct0n0g04.png", "ct1n0g04.png", "cten0g04.png", "ctfn0g04.png", "ctgn0g04.png",
- "cthn0g04.png", "ctjn0g04.png", "ctzn0g04.png", "exif2c08.png", "f00n0g08.png", "f00n2c08.png",
- "f01n0g08.png", "f01n2c08.png", "f02n0g08.png", "f02n2c08.png", "f03n0g08.png", "f03n2c08.png",
- "f04n0g08.png", "f04n2c08.png", "f99n0g04.png", "g03n0g16.png", "g03n2c08.png", "g03n3p04.png",
- "g04n0g16.png", "g04n2c08.png", "g04n3p04.png", "g05n0g16.png", "g05n2c08.png", "g05n3p04.png",
- "g07n0g16.png", "g07n2c08.png", "g07n3p04.png", "g10n0g16.png", "g10n2c08.png", "g10n3p04.png",
- "g25n0g16.png", "g25n2c08.png", "g25n3p04.png", "oi1n0g16.png", "oi1n2c16.png", "oi2n0g16.png",
- "oi2n2c16.png", "oi4n0g16.png", "oi4n2c16.png", "oi9n0g16.png", "oi9n2c16.png", "pp0n2c16.png",
- "pp0n6a08.png", "ps1n0g08.png", "ps1n2c16.png", "ps2n0g08.png", "ps2n2c16.png", "s01i3p01.png",
- "s01n3p01.png", "s02i3p01.png", "s02n3p01.png", "s03i3p01.png", "s03n3p01.png", "s04i3p01.png",
- "s04n3p01.png", "s05i3p02.png", "s05n3p02.png", "s06i3p02.png", "s06n3p02.png", "s07i3p02.png",
- "s07n3p02.png", "s08i3p02.png", "s08n3p02.png", "s09i3p02.png", "s09n3p02.png", "s32i3p04.png",
- "s32n3p04.png", "s33i3p04.png", "s33n3p04.png", "s34i3p04.png", "s34n3p04.png", "s35i3p04.png",
- "s35n3p04.png", "s36i3p04.png", "s36n3p04.png", "s37i3p04.png", "s37n3p04.png", "s38i3p04.png",
- "s38n3p04.png", "s39i3p04.png", "s39n3p04.png", "s40i3p04.png", "s40n3p04.png", "tbbn0g04.png",
- "tbbn2c16.png", "tbbn3p08.png", "tbgn2c16.png", "tbgn3p08.png", "tbrn2c08.png", "tbwn0g16.png",
- "tbwn3p08.png", "tbyn3p08.png", "tm3n3p02.png", "tp0n0g08.png", "tp0n2c08.png", "tp0n3p08.png",
- "tp1n3p08.png", "xc1n0g08.png", "xc9n2c08.png", "xcrn0g04.png", "xcsn0g01.png", "xd0n2c08.png",
- "xd3n2c08.png", "xd9n2c08.png", "xdtn0g01.png", "xhdn0g08.png", "xlfn0g04.png", "xs1n0g01.png",
- "xs2n0g01.png", "xs4n0g01.png", "xs7n0g01.png", "z00n2c08.png", "z03n2c08.png", "z06n2c08.png",
- "z09n2c08.png",
- "PngSuite.png", "logo-slim.png", "emblem-1024.png"
-]
+HMAC_KEY = "https://odin-lang.org"
+HMAC_HASH = hashlib.sha3_512
+HMAC_DIGESTS = {
+ 'basi0g01.png': "eb26159a783a4dcf27878754e34db6960e992072fc565b12360c894746bc6369101df579e3b9a5c478167f0435e89efb2ab5484056f66c7104f07267f043c82d",
+ 'basi0g02.png': "f0f74d33ee4b3d3c9f1f4aacf8b0620a33cf1d5c6e9f409e11b4a6e95f2ab1c9159c1bd0bcf6f9553397bf670f4c92712b703d496665d4c6e88fdaf6a0c98620",
+ 'basi0g04.png': "7b81665f353ff6347304b761d26b4f1baa6118daefc4790f4b0e690150a4e6306514f2aef87e2c39e83e56a0b704df987b10a5366244da58697cda4d5d2745c1",
+ 'basi0g08.png': "6c809574674494d10eb04c58191c4e0b35813c45962ecafe36a9fe5ba44e5d74ba098e0a524a30c1508eb2dad601f04d5230dceb61a307ef1120f07a8bcbc92f",
+ 'basi0g16.png': "dd439069fb704b8deff3de822314c012e91a0bd84984d2e79888c6394b78557a0ae6197a7b0a4d64eb4e16fc758946c4f1f13d0d06e512ed9743c4a355b02488",
+ 'basi2c08.png': "e851fb030f88ead2541a01591882dde5fd9f5dea6bb2b11b374394ed86abc7289e72c4c90808b261aceac13111d3c05b39033168b42ffd1c7ea367314b3a8dc5",
+ 'basi2c16.png': "e0f81dd459860f7eaf04a2c54932547f41cdc9903a1295a26cc4a2087fd79c98a2e5d5e74f22345dba08b1eb12f3f53c9b904c88b756cbae0c19f9d680e2f1e8",
+ 'basi3p01.png': "aa21cbcd5d64e6e88056af907509f3b98b00d105198ea2a669fcb25b6966f06d5e4e3afc160b2382935e8ab8e7ccf61733424dfb39b9e864306b82f8355bbb58",
+ 'basi3p02.png': "d6182370236630d42fd75eed7dc54079ddb7fa9bd601eba22a8dc3331dce31b9a9465027145c29bd56cf778ab0ac029df6aa6481ef65c9464a1ce1d89423faa5",
+ 'basi3p04.png': "2b35fb98884da370f25833d25f0ab4b188cc26440321e95519131c675818c128b2029d38b3477ef94d88052ec6e9f8b1f7410c5576ce0b47b2fb7a5ba771ce48",
+ 'basi3p08.png': "7415890831958ca34c73de3e33a9c88980e788d10c983c3a00967886f05053d359499bf0bad386af8ee1bfdb73f666e1d541b0ab682c6092ebdbad3d93e145b1",
+ 'basi4a08.png': "22ab23a3070d9f1316e8c65b333745e4abf6dcbe63d9d0ada7f6881604b498a92e5b49eb8c1e32f453f4319d94d3d0f48441bac2e79ea528fd7ace0dbbacea9f",
+ 'basi4a16.png': "2b1436a619f91cf4045e18acf03201b5e9c7774fc77e4c3f38d668984d98543fe64978e80854f30adfecd89b71632945250508bea9eb1ce8e9145e3e55bdeece",
+ 'basi6a08.png': "aea929866edc5e607d7dc90fcd871f4b6d548abb379b9427fce75a773705e0d8c3ed03bb64e530482b72973eb09844638db5db93666ca1605ff6bbaf194f70e8",
+ 'basi6a16.png': "29b6ce7c2469e24587b87559f85551334c51bd9d7867f4066c0f7dcb01d710e11e87ee8654c91dc986454cd70f8bd6021e2086ea40e48a28d68a9bdf2283573f",
+ 'basn0g01.png': "52da610af6f97b03fd8e9f8e52276227f57a97e2bc7e47ae9484b2a37472330f8f5ecef2d6de7fde8f7eb8f144f233bdcf8a3d716c5d193e44d9590af2709cea",
+ 'basn0g02.png': "676c727faf143af658ed6c6333b15e50387c566c1846a4dda636ed4a2dbb1c0d6d32f0db635479f6851047a32c6d9c52898cfda004ea986853f3ee13750ed90a",
+ 'basn0g04.png': "123a6652b56f5b858373836509f6b7433221e6ff4eb9ce8a68d0d12bfb27cad0c1bb0cb159523ef1ae5997cb07f994bfbfeabcf0a813aa83495f8269a7a6c4e5",
+ 'basn0g08.png': "ad5ff30613a462a9b61242d42bb7c854b8247d80a1d03a3919dfdfe8a91c8a962ff51932b2411f714f1be7b803cbd4605c1d4441882cad7e8f44dd8d927198a4",
+ 'basn0g16.png': "40a96ed10ad5cc58180701e0bb6d6f36c1752c8b8329a80be2960535ad9e168469efbd8f3dc825b57bf65e78a3b61835f19697f2a22511f79c06ce2c6a0034c0",
+ 'basn2c08.png': "fd92ba13d2038c632fd8bdd3e33971cc69f561bee1eb04ff7920625c6771e0cf7fdda29e48b8a6ca71702c0624ebbca232793f28bb2073b0247d30ce0c549ad5",
+ 'basn2c16.png': "f6b3cfbc70ae502edbeabde828823dc079dc4e9a586a7fc326c70caec3033124121e3ee2e6481e6ce966efcdef9376cb3ec3edb8e677e91563f510bd6f6e83e6",
+ 'basn3p01.png': "d262c97549cd1d43e36f5990dac051ead80f1456693c8b1e19a8a48796195831a6ddd5c4a0ac44d22fee51ce4d9392c1c40a0be05571b1b2a961691636d69cd3",
+ 'basn3p02.png': "a00e375e1fbcc23de38b3b11a0fda4d0204f55473f74e37e0bb5c5f391b37c019293ccddbb99196b9457cd0b7fe5b9e34a55dc6b8167b6909b38813e37a95e46",
+ 'basn3p04.png': "1a6ab4c567e75b20ee6cdb400dd1f7764a05679c35010e6144fede5a55767dd1861df8e6240e1e59d4166e25d972ff05a41cdfd527818b6ec960a0f9d57d0939",
+ 'basn3p08.png': "b8f99f6410cc1ac0ceb366e93fc1008f45fb2499e39c489fafa143e8e881f334735e118eec93dde687bf4ea524b4548741c520d770ba6d7071e8fdce576644de",
+ 'basn4a08.png': "4b7758d4fce3bba95ef3d09cff0ab28c21b8bf568156730fd4e3bcea1c1c2d3ff77f53fe3551f617bd01c8c96e929eb20bf04f5c1a84f37c3cd6bacd4730e6eb",
+ 'basn4a16.png': "aa0c411f8bb15fc801b072f1048de2fd08761fe245ad267e8503eef8ffe1c39be845e99c04245771afe9b102328129f6375869a4e6cec60eeca641b3e5df3a8b",
+ 'basn6a08.png': "78d7c811c5463ce53a50874baed840ba70c811513e0ff98fda15a08f01ac6a7c7139a9979cb3688451af6b7e2981699be3c27a386d77af5e60d1acc9e23cb103",
+ 'basn6a16.png': "e1ad0ed2bf5774b2733d23f2ea9570c6edc933298572933010144ef07bfe6a7878f7367a76f2affbf9845d5b69ea3c84b885f9415e18e752fb1bf21d0dd9d9a2",
+ 'bgai4a08.png': "22ab23a3070d9f1316e8c65b333745e4abf6dcbe63d9d0ada7f6881604b498a92e5b49eb8c1e32f453f4319d94d3d0f48441bac2e79ea528fd7ace0dbbacea9f",
+ 'bgai4a16.png': "2b1436a619f91cf4045e18acf03201b5e9c7774fc77e4c3f38d668984d98543fe64978e80854f30adfecd89b71632945250508bea9eb1ce8e9145e3e55bdeece",
+ 'bgan6a08.png': "78d7c811c5463ce53a50874baed840ba70c811513e0ff98fda15a08f01ac6a7c7139a9979cb3688451af6b7e2981699be3c27a386d77af5e60d1acc9e23cb103",
+ 'bgan6a16.png': "e1ad0ed2bf5774b2733d23f2ea9570c6edc933298572933010144ef07bfe6a7878f7367a76f2affbf9845d5b69ea3c84b885f9415e18e752fb1bf21d0dd9d9a2",
+ 'bgbn4a08.png': "4fb9b1023c8c7accb93cf42bd345846c787735df01f7db0df4233737f144e2d5348afaededcdd8c2bcf2e53ce00e2ff095c91de14d7818b4b41c396ab85c9137",
+ 'bggn4a16.png': "302d7c02ddb0be62aeffeeda46957102c13a2701b841a757486cb3eec7b5456cfabc6ee1954f334ad525badc7c607621a72559b01ce338a0f39e2426d0a03fce",
+ 'bgwn6a08.png': "d380c477775d102288b43c387dbd7b931f85520f2f6151e3ccc5a25764169312d98fcebf69fb86d3d12520edc3de9bfced559ddf73366f0679e52defb9116424",
+ 'bgyn6a16.png': "b688d395552eb2a8506fa539ee9159b40a57d02c81860bcf76176213504eb10bdd89de7ce9da452e43f2a46c15290755cdc4816738620b27aed45b3ea7f7ee84",
+ 'ccwn2c08.png': "c4d58269ef360e42870cce5fb0b1134bfe5706f172c5ff916a338978798fc541a463ab4fdb7c91c424fa385f0ac5d6f576967f178b858d7503f609b2daeacb64",
+ 'ccwn3p08.png': "d89becf7d24dc57c931a8af1b9dc03ae10302785cc67028cec7255e1aa0ffb0d508d894023a98c10a24cf145aa60b93f977acb8231c8fee9d3f0934484757c30",
+ 'cdfn2c08.png': "a5faf9cfd284d3750ce2c2f8e15d0ff1bca09da4a9d46b8797c7a1a9f2ebe79d7a7a552bad3c3c049d6186460e81e1e7f9b94e7bb98a3c79d2516f6fb7ac6aa6",
+ 'cdhn2c08.png': "396eec14e76c00d22ee153171243ac531dcf7adad830948dfd5d6f0a84155734b90407e74f8c1ab8cfb0af5084c03f511530739751f8da070379c826545d0237",
+ 'cdsn2c08.png': "051b0defa4363ceb3fbc44f460f99a10cdd7c15797ea6d8aa62513b8b6fc5000fe542899db464db30eac56d0c9cd2a5d3778c6962f3aaa85a20881951a7f963a",
+ 'cdun2c08.png': "946074446fb99f0b790146df0f6e362c68e79b46ec7cbc4ce3d3dc9f75f66e58715caac4b3d7aa8fe8360c32abd2702e7228f9c03b4ba2a0d7f2f970a7ba8f32",
+ 'ch1n3p04.png': "6680e895195295989850129bcf9d0d0c47efca1c3bc363e4ea822c688707955cdcd07ae92e6e213ee388a62e14b51e036f9a9e075ad7b0f736b0cbc5cc4a108d",
+ 'ch2n3p08.png': "778ba389d9d0bcbe188e2501c7c1d047f1287179b3760b43da0053f0853e77a0575c7179a02f2442b83efa6cc0951b32d09bd7ea3b6848f261f10b8127e4b0e0",
+ 'cm0n0g04.png': "9e7e94d201a1222383294bd60e2627207b7b99c0bd80aecd677a1b7d8b372de4981b781fb794811d29a4b2c4db4f5a40c953039c31084f8f3de9aff13fbd1dc9",
+ 'cm7n0g04.png': "33bb0ffdfe54d655683e4e1bd6d963b9a35a6500129b5dd574245e78971de8d19f27b86a76d42056716b90c2bfc950241bfdc6c4b52ee0e125571de36ba61904",
+ 'cm9n0g04.png': "fd59386d15a1a324c5ff32f574484c1209afe4ad99f7dc12dce45b2a9bfefd33311ec93211fea3a8e61d1ad2f98220b0c15d151be304bdaa7f88126d54299f68",
+ 'cs3n2c16.png': "93ca3eeba9aef67de15f943fb2383d208ad1a68518ab78c9fa5ea306ad077b789e873f9e453f0354535167aa4e3d3fec715df05e827bf510948bf0e6fa0dacad",
+ 'cs3n3p08.png': "e8ddabbf0b17db03bcd7ff0c61d08cc971b3b88e3b3ecd2d4a296da8cf7d7708fa5b42ff3d5813d936ab7f5b4bafbf5842fa4c0fcf0cff15258548d2d26882f3",
+ 'cs5n2c08.png': "4e3eae53e8c27d4c58d8ad8cdff2c06b00a61d1528a41f5566694f10ef33c4a66f40d3d9fc247731c3ba6dfb734c9f2f90ef031c64486fbdf8a825e354fd67b9",
+ 'cs5n3p08.png': "31ee0f7f789c1203a9b0e81da34960a47017f3fce37bf2b711738ebd535bb3003ef60c2b0b1fca16587a59955c1ae24b9d186d7ead1d3ece6ada2bbfbc5aee85",
+ 'cs8n2c08.png': "11bbc80c3168f632deb4453f9199c7994255a0f4f2d7d2d2b06a00931fda4c56985b5a2ca8e969893ff2d65bf330c3d3148b80cbf72aacfe0054b612e6ae05e6",
+ 'cs8n3p08.png': "49ae3a9050487f6cae826407d421f32a8c67977dd057a6e36f1b2e1ec6abdf5cd46c8929ef4d7b565921ed6c9ae0dde89e243714fdf1510503c7d7b8af6d66e3",
+ 'ct0n0g04.png': "b6a66fda9ad82cb3287a1ef54702926204bbd4186969cdc2e0741a28dae1869ed76939199f44fd7dd78332753cb8b20a53c4bf740e353f2cc4247870cf576848",
+ 'ct1n0g04.png': "7cdbaebb6be5d9165972b5fa24f2b64ab437f5337f0548f3d212be8aa95e5dee6ff9abd76ec232faafedc4a41ab8825221b6ced2ecab81c1b3ab20042ceb81a3",
+ 'cten0g04.png': "648769788c3eb4acd06784dc428bab9e7868328aa3cfe3718ee6656e13e40c4502ca5ac1fe6d4baccb666d4a4f6b3a5d3c97d489f9919ae0d26c2dcdc62e526c",
+ 'ctfn0g04.png': "c40768807f13dee8dd80ab012bf82b7e8551cb20bde3c7b5c4c45ed19c764cb981945ef036292bd9a2838d34b1b52284295133fea326aea9fc391708bf1d1fbe",
+ 'ctgn0g04.png': "e0cb7a2d983f1c1c38054b02aabeec657e3f85dba3a52b4878798664c8c6db77cef84d01f042368de6e77cd07b7c2cc6e324aa70bd44c2c8a3642f0cc8fc6a65",
+ 'cthn0g04.png': "b8614c14bc8c32bb3b29d3b0ac9f3d04c0fcaa40818ab86866e2a8ba1e0c6a87a989f499f208a776d47bff8ab09bfa09352d52089b3cd5bf599faf27627a630b",
+ 'ctjn0g04.png': "02e2e0a5fa8054e7c7e1c583945da06fb31eff9a3fdd1a7c9f76ba3333f20ce60aec8fafe07f608e9d65a6543e97bab0ff8ae66f3995e8035c05a7c53168ca9a",
+ 'ctzn0g04.png': "ac35974bd1182e339327245ffa1c0afde634b3a67ee9d6e4e22deee983d6d31054e7843cf1720087b88f6510ed70276e9b0bf43deaf861bd16ceb166140352f9",
+ 'emblem-1024.png': "5b2e174847274069fc8f4e30c32870ddc7c0e3616a3f04fd41583543aa99ac6d9b7d5a63ed1da672c551b4d193568bb58ddac5e87a101b73367c7c3b01e36fa9",
+ 'exif2c08.png': "e81b85aa36c9aab55754dd8b73d42497c38eddf9ff3c2981529eb62993d8c0ab33d1b5146a350dd8a1c528d42a967733b2f86248ac615e0254fed53d66d0d895",
+ 'f00n0g08.png': "fa362f0262ce522297ce52bd7d18b1dc28a2eee3e099b4104c2fb6bdc3fbce0b70303e6df31b709b4033b41e8acec29c81d456c67cde741243c9a54f1ba17f17",
+ 'f00n2c08.png': "040e95e05152c4bb30608556c828f453c46253c7e0ab18984076cde29b5b6afea7b6658cb019a2723af02a5aabadb1af3b1190655256f3477cd54b9ebdd4df91",
+ 'f01n0g08.png': "5c60761dc803de1509ef33b4e0ee350d15488d73f4b4e2f93311beb19667626f42d91af39873cd078617c5a2e7c46cceb831d53299c3ff2e7486b43a02ce4967",
+ 'f01n2c08.png': "a2762a0c4905d05469178176966e86ed4f14c3fcf5c88336209cb923d76e73acc94c619947be87b9183afc20bcd002ab2cc84d81897ec8fc0a4bdeb02a2b7863",
+ 'f02n0g08.png': "adf640a6f60662ad1b47b5666d2ce86489c685284e50d47344af7cda37f4a42697b5e249f5140413bb3c3e563cca09b2693dcea8bd9ad9adad1adf654ce00bb1",
+ 'f02n2c08.png': "5f70f19d318ff1d9de4c2f728d83952b12b59bfebac213766ef835dd19f8214f56fa92318041eff25e720503542d067bc9fdf91d86016713c68eb1c52870bad4",
+ 'f03n0g08.png': "742efed3d25ada0449ed60e4fe1dc94abbe494870536946810cc0eef5c3bfbebefd9bb6d1a482cd5e2c2ee0f34a74b2ea796772254d05accb6739c1ab4d19cdd",
+ 'f03n2c08.png': "adfac7d6dcc7354467cb3f65742e30ecd44a09b5913ffb656664c9c4730e9cfab9c5e0df2ff8995d412b1ea9cd30ec061eead939546bf795e50a2d49cd10bf92",
+ 'f04n0g08.png': "9f229c609e87e6c3b83fa82f4f59d7b6494b70c7f85cc807b3611a12d5c59953f11c163228f2bb8b2e7ce77ad204e0da099ab06f8fc480d3ab0ca99fef83c23d",
+ 'f04n2c08.png': "2dd8b926d1f370b3d3ebaa982491fbe446f3c22b89e635c76eeab60c9ccd3ee7cf39773108d2cec647e480d40de88c4173369b4a12a3fccfba9e4040752cfb4b",
+ 'f99n0g04.png': "b41996ddf1b770d01900c309cfd2f96d6e60df8313cfda3585a731f32166aa447bcf66ef4af907d6417528024961408d06ca0894fbd6a63fd47ee5a9ed541b51",
+ 'g03n0g16.png': "02a49b9735063a4d1888b550ed961251b150794422b00ca3800ebba09cd55bdcba15cc8dfe0c41e5a99b2f4d3976b32b1cd08aba92f3dfc3960c71e28ec6cb51",
+ 'g03n2c08.png': "70b3d643218e033959c51279439d80982f338016b4355aff12be51e7bc59a79f5a5d519c0fa5f13db072cc667fb9635654766af2a11ea25c1b6673f554ceb1f4",
+ 'g03n3p04.png': "7bfab2aef6f2c04063c438a8f5cda38f3221892ec22a83ab3d3441a900b97c0a7184336ffc2e0c6748e4d931fc80855eed5d6b208ba6ac0709ef02bfbab3e8f2",
+ 'g04n0g16.png': "9a1d60c89bd63e1f2c81adf1ce7025b7f465e00f0c5142d8a67b5a92e2b042d41a352704969f237883e376bf50c911db196d46f8c28c30ef5763e1e717710c8a",
+ 'g04n2c08.png': "8e482c99cbc90e6e4aa678e5dbdc39f5b432d740ff260ab1ec04ffa199d97ed2e06491cf88eb0bbbda2f4133f174cf3741474305d9645e0268916aaaab43299d",
+ 'g04n3p04.png': "d95a52bdc83db74dd19aaa56b40bcbcea268492498c7b2348882a4a5ea70c2b258462c3d5cef85e5372188f21001f719afeb2fac635006486c8fc84b96cc4622",
+ 'g05n0g16.png': "75954c2e19aa2ba43f7011adecded403035ecb21595a5d116896d2bfc1b71eac42c9b6f008a748cd21b70004921832b3e0dafa1fc0fda4c51ad44cd2b4d782c9",
+ 'g05n2c08.png': "272baa8dc73cbd63f4fb9545288cfdfcee544e266c9074b73b401895188a123960a6000959f9c034f7b5abe2bfa5e6185253447bac82e9fbfa9634d7e9981d95",
+ 'g05n3p04.png': "81105d25df2bbbdce60e90cb9a7d0784326bc3c2857fdca4f1f3ef7ab301627685057b97b8d0c0c725d92bc0b48aa1b156dadf5e302ca35917f0b407689ba054",
+ 'g07n0g16.png': "cb6babe4e25f4cc7e0c3602d9f0e9e538f46a4c4e40420c29521799c528da31afd07b614ae64fbc0e9d0904c9f3e7395b31452abdc69c6a03bf1b5817035b669",
+ 'g07n2c08.png': "c61e8f936afda939d6497687597d3381485b7cc00716101fc4d6f3abf44df63659b762c77ee252a8735f8e0be0809961db17abbd42c5deab5bad10d0b6b28a55",
+ 'g07n3p04.png': "8151fa9e9ccd1991a05ea129a7363e23de80688c65d0554c7f3142ed7099d01d82d8ef122986693718f221202657ff965b1b6387a237b36ae741e3d4ea693280",
+ 'g10n0g16.png': "28ad93f3bebed928c3b0bb4beecaa1b1b55e480c7922d2a36c8f92fc0de012adab523c42f22871b82c6683a7ae74864ed1c35a76cfad92dc6692be0b78c22f50",
+ 'g10n2c08.png': "4b922386b48c0dd51aee3852da4e52c5c4f3eabe3fcb000e4cfdf0c0e8b27d6a6f77fed944932726fe884f468ac24d89c5c46d65db99be1ae797bc4bbee4cd01",
+ 'g10n3p04.png': "9b106a0db8ea7e4bc3876beed0f13d83b6f3d6d7d7211441379dd8d18db080f5dc81c6d15312cc3c8ae569b991852ad48f167229dec033f1a974d2a95c83cb3c",
+ 'g25n0g16.png': "0910ee601a4c4cb546c3bf2b5e8a799d199e34e1434c58c75ddad17f2b295920cf3dde9fe05eee19689705f76b11474b4edc73f4ff346b6ab2d02ec40a13d3cb",
+ 'g25n2c08.png': "080ed57fd4185c00c6c70e48c27612621393a6ef3987aefd1481611f74d0aebc58d1a90386e4e7bb0321eca961e97cd403a7e727f7324196c5a3cf0e07bffce3",
+ 'g25n3p04.png': "1deb4281d9792af858e715c39ef7e6756f3004845d87f52054efc9f02c679b2b1b6c2a548a5e6a3f31604b115469ba4bb81510470a47ff9a22b133427375a8db",
+ 'logo-slim.png': "0104624a95b1b8a97bb5013927cb8fbe330a8c9e7197814147702702cd1d44cdde956404786bb0e69927c6b03ed8031bab566599b1291b995ce747f7cb2135eb",
+ 'oi1n0g16.png': "40a96ed10ad5cc58180701e0bb6d6f36c1752c8b8329a80be2960535ad9e168469efbd8f3dc825b57bf65e78a3b61835f19697f2a22511f79c06ce2c6a0034c0",
+ 'oi1n2c16.png': "f6b3cfbc70ae502edbeabde828823dc079dc4e9a586a7fc326c70caec3033124121e3ee2e6481e6ce966efcdef9376cb3ec3edb8e677e91563f510bd6f6e83e6",
+ 'oi2n0g16.png': "aab1bbfc7b711ba66260985bd8bda6ffaa1e09a0a546b2fe8869b508d823a9e5a412ba6337355a81d87f010e9db8c95eee5f5084b21ddd5cca5d7db7725603b0",
+ 'oi2n2c16.png': "8d1dd257f3b1bf44ef0bf38338a1e3f2ff78670ac779959751a56231109ca1ed82414f50a221aa45333263073e1e1a950ac8df8e5318e2ed695422d49400c540",
+ 'oi4n0g16.png': "7675dfa4cff547c3029b21cc892b90a8647199dc9290add932535b04b4eaadaedbc338704f98a075f4690b87815eec8cc0f90a3dbaa2a7809aa03f238ebc5815",
+ 'oi4n2c16.png': "66313c9d4731e2a9fa006ee9e43c6ac4a3034ce2826c6213f67bfa349bb8bb3cfd8acd2c4553fd1fcd4b2f43993a54539ec8b7fb7f07b3a406adfe919f17b065",
+ 'oi9n0g16.png': "5615cd4c277be96b21031827d08c8fb2971fda090a0031fd34594f77f7cc558bc68917542597a32bc39c0cd29f7759f0f0429203aa285c163bba8c8f78894e72",
+ 'oi9n2c16.png': "e2184c00b952a3aa53078a5f995715fa683718a9cbe42705fae3a7c77b236ee6ad706f6dbf2c243aeea17e2c53e84724907724634545e065dd16ff400f5677ab",
+ 'PngSuite.png': "af1d473e986b3f5cb1006340f8f99156e980e2f8c9f804f0e27c57a51d0dec332a81d99c6e50162f63792d89da44857a6072f8431aa735f1e8f86c06520eff4e",
+ 'pp0n2c16.png': "82ee5674861b5f9bdab6cf41910d980fc33b5188e191b8892b051dc3b3bbceb4c6d421cbed7bc9b71a9a14db43991c0458ed2cbe5166939f1cbb1e20e445e8b1",
+ 'pp0n6a08.png': "71c0d4c87b6b2644a4529cd240c8d583c25d45e79fd8bb71ca850dada37e46571052b2da28b926a8194169b82da505c9a3e3a701816d91ac968ad6ff41132b70",
+ 'ps1n0g08.png': "b273e94c2f826640b10b27b50c605be06541b397ea1289be6f4ea821dff6c7b4b209ec8817a315db442de04c975b7cfecba07b51c6cec965ab9062c05ba04edd",
+ 'ps1n2c16.png': "833993b81801432eb3a9dbca81f4fdd8ab720c76f8d99a2d298fa1dc4ebd19759c158dd10a68f690f999ea643f62fb7e779e916df86aeb05c43bc4db62aa520b",
+ 'ps2n0g08.png': "4abea03946d751f03e1438e5987ae691607e528c577db52e893051b54a5d147969dd965e44aaf5540fea75baad873327d76aa71a07c81de31f04f3b781d01e3c",
+ 'ps2n2c16.png': "bfea51d7be49c04293de034c7649472d34becb663169608490916795fe988df7b812ff8950a3f8d896ee27756effcf9fb525d8d455226cf3965595ee85188581",
+ 's01i3p01.png': "18b405c902977d2553aab1738a3c00e602e40d11c121a7007c9b7b4cc499aba1fab12fc12aecbdbd5b5cd2638ec5ca5157b5d8fce5dad3cdc3bea02b0904c9cf",
+ 's01n3p01.png': "8e3e1c9754ebde8c687355b80eee4bf0e0ee8e37b39b784f1997cd2eb60ece7f077b40c8027b0d7f4b7e8f242c22173a244f4e599db33985187439bd918d4486",
+ 's02i3p01.png': "3e26a8cf35e3df1650adc1656f2d3e7c9b5e1c7932826cf792cbe2cc538c1283ff145f66e4682d459bb0b4f2a2f9ce7209f1997e336e06ca49a83f75270ccad1",
+ 's02n3p01.png': "d34685ade19ee550ba52e81657627832cb9ba3655f6fe336ebb5fdc4d35c380e819efc1556e1bd1ca2b4e456727dbc5312eb513e7254dfd057a25963e57f0ff4",
+ 's03i3p01.png': "818a2c91d6c0f96b13806d945d1fc1b4c64f17a9b6a2ede2658c84e20269cd80289312a163761165f0d99e1824f283844f1b4696af314c05714fd349acf7609e",
+ 's03n3p01.png': "fe847a62eb64bf9db4d9751600b19333f057b626f2f2eb80ee78a3374ae562944c2ebc9c2712f3bbf862798ef9205f38297cad44e8df5dcd96c158ca2e9d9233",
+ 's04i3p01.png': "1c63332a0d2f31b3a6457038ec2b8c5b4bd3192320fb1c44873947375dcaa028ea07151853e53c6f3fff6878cf90adedea35ae819e5a1b2dbf92399b29464d56",
+ 's04n3p01.png': "1312d9f3e5bb07b6cbf0c6798c3ae9b0a6cebae465ae6d4ba115ef585616b3b1f7723c6481fcfaa00626d6c62e4fbff7023faf1e92eedeb5354b9805542d43b6",
+ 's05i3p02.png': "13225a16a79579c4040cdc03f11c71d8589ab322a4f3926e32d9499fe4ca8503a43870e532b2da2597a6c3dd89c3904428cf89c25a8637d40bb3a353017cad5e",
+ 's05n3p02.png': "d07f2ef30c06a29b9c5c6a52ce1485a3bb9dacb5f119c2829c4cfd69c8fa272d6065eab21a5acd016bdb4f4c724214e8a737c2b76e0f0151e6afcbe5586a37ad",
+ 's06i3p02.png': "b386f0387e8496849b6d325e710440f7937a403b123886a52af8327e69e411fd632db19daaecfe2e712d49279630515d7217533112acde73cb429e2cfa465b63",
+ 's06n3p02.png': "df0968c77975f350a86fc09c047d9e3a0a2b71890a0ae67bdfedb23e7f0ce303ff883a463668e10df1dcf2e57cea8cf1fc7c836f5d13a73c1ecd8d66284fc0c5",
+ 's07i3p02.png': "0f67816f188ce11f15d0f345d2695f1920a322d84be3f332d542c5d20d10a9cef2cebf1e8ae778b25677beeda229c06221eb3450b851ea0e8cd102e5cad14e66",
+ 's07n3p02.png': "0af60c935e2da2a8a3173edf614085ad0df095c882a140437bdf93ecd5494cfeb5c068dc7ea4d49e181c67d26dd9cf8c969bb2d95f2fbce212ddf5817dd7f642",
+ 's08i3p02.png': "3204dd0879b6b1284f197a0437e674c4280adad180d4a1d37dff1555be1924d6234dad5d02266aa575d782c53fa52fd4580d452482ba939c732c09709075306f",
+ 's08n3p02.png': "135039621ce2079465ef49c1b7e5a5aeab299993d2bac864d822ff0669843df1e733a729ca5226ec05c94ddfebdcb2f4b78699fb3adb741db993d9757b4ca71c",
+ 's09i3p02.png': "dc4d8ed06a81fcd604f949f43e7d5f482c3ad9efd113d220b709de38ca0ca1a340f4cce7e929ca6323390b4ea7c4399cf2f1f2e34c1ef1b38c8296b51d7e8f4b",
+ 's09n3p02.png': "96b8204f7008899993d8d277ff42c8eb7c85e7cd522cae2e9cf28b8e10e3904c7ec2e3227372f397f6c5a381875dd747a42409471a29ad5049240417ec1441f3",
+ 's32i3p04.png': "a4de495c70f54eeccd115492a0dfe1cbbcf7f308343eacf6a57515d7a248b356a2639f5e88246d630c8713724cfd7ab1d5d388c677f026a1c5c9b4270a837c67",
+ 's32n3p04.png': "757009a2fdf19d1187d85930eeb4e75c6831387348fd8e618d1ef971c27d2682b2464b4160a743a6c6d712553fd7fe1f0e5d78226e348f270093495297ec83bf",
+ 's33i3p04.png': "19259eaf76a42fec949a21c4c55715247a027c2b59ba4bd0f45fdea1f3406cb475c33213b662fd64089b697a6cd25700364f76923dc2531fa0b39546242b3356",
+ 's33n3p04.png': "3f42b5f3896c1a47fe5dff9921d56234b4326dcffb70a7c6b1f0e7193a6f8f898438635f3b1cfef92c59d7ab827e2a3f40671d97c8547c8e7063a0076c97fba9",
+ 's34i3p04.png': "db0f7fe138fd732eae4a5c1b8d013167eb3be4afa86141b3e6ad096eabec67644e3108189311b3ce2c78f891d1ea7f5dfa1c30be59509edf123696064eecd00c",
+ 's34n3p04.png': "e35d9338637ae4c7a1c74a0e73a5c4ba405c2b0d36efd92512b7572d418c25e7d06361be2a8d16323c2708ff3921da24b76be5a41bd3cccf09c27ad472078261",
+ 's35i3p04.png': "9f0602e1160b81c2e88fc30daf295ff29c4f6faa5a3391c69d895621e7ab76e2071ced6f5a798e294f69621bb32272070ff4ceeeb1436b1cf03640417961a9d1",
+ 's35n3p04.png': "f12e6a7364073b7a010db0cf952989f5f5da20c592b0256efabb5e82e96d928dce7695c2a0af0749ddfa2739e3ca985463eb0f4a7fb6b8ab0638d65079fc6265",
+ 's36i3p04.png': "a2d0374bba6fb665deda98b1bd0ef767243b7a974b9f00c78d54bdbfed2c00decf6faef95816ef711efdc359247142be08ce2b86f7860b7384948ba394b4dd21",
+ 's36n3p04.png': "e200a6869dba1fc9e2eeeff6e686e02313c366a990bfb5582f66dba486251392a465db03806092543008e1130624f1d16cde61613d0ae2a9589941f69a1608db",
+ 's37i3p04.png': "555f1f7ec2d8ddb58ced7162a4dec315780be13b7cb9ed6d8978046c7fbcb91b4ecf6fcc5c99bd5b8b8d348e4cd202d882a31dec1ecd25156af8968c4a06fbff",
+ 's37n3p04.png': "d28b3f442b481214774d543924ab07b75fee5916262e6404992962184ea0059ca34fb32d14076642ecd83a3063966ea80676e3165759632782ffd844702cb74e",
+ 's38i3p04.png': "d4fe0179effbf28f7d28c0192de614512870367cec14ca04d86eb9fff9d6864b1074a68144023244e46cb69ad601e81632c36eb2ed307a32a3c37b7683f882d5",
+ 's38n3p04.png': "19d23ca8b9b44d26bc9173a69d1d8332e4e7b2ce6e6422195e71dfd0701158023253b130a831a035b2fce0a1556004e8de74e893caeea3d12410909e6e649831",
+ 's39i3p04.png': "f0c783232707d288b086398565918079e510677742bb5dab09b4520687a06809ae328d24508ebd8f5c26cf85105300ba98e55c29e3773579929839ed9ddbf7fa",
+ 's39n3p04.png': "39763c31a17edf2751442cf45ae3cc315623ed5b04141bbced2ee8d233485b2d1a2cc0678d60a1c84e3d89a7513634bfd9c82b58754cdfe95885f7a54ff18e2c",
+ 's40i3p04.png': "d33b29e6669accf1325e8212c555a6cb1d8413c445140aecb62eb6b40912743ef7c6298ad4bc2e232bc448ddaba37f79fa4d25e0cc8e3d53a5ebc93f8f984555",
+ 's40n3p04.png': "463eb60a2f0884fc368ea0650c5b7b6469c1429e5f006a6537e4aac721094bbd57baa6bcfe4025939089e27b344d7077ff09618e9ce3a5bd40ee3fe5a0e33ce0",
+ 'tbbn0g04.png': "24fb55d9fed351946869552edb15bf20a2e7a050094ca4b51ebd135958f8b77401e0e9b18618de0cbd18f835e16df24dc57ef094d3b456f0eb9f73c31748ce2a",
+ 'tbbn2c16.png': "ee98ae3a1cb4a851830ee3e8f4112d08bd74c2a05b778ce51102780ba9d7170c5200c9cc4e1a5c0833618ebe137595eb8fc0591b8798bb6e4e94c234f8cbba3b",
+ 'tbbn3p08.png': "ed325815b8525d3a5fa37c968b7c85946add7c08abd1c66d86e0264951cfa5a377078b910a78cc664ec2c43d352093c2609b8d01c9572f4ba922d98264e55c04",
+ 'tbgn2c16.png': "e6da4190d4cea04b0002d598d68c0536448899dd8fca4931b44bc8ea6d47e6946c55ebc5d2049936db2f7f52caef124648d25a360e838571f5f7cb2795eb3657",
+ 'tbgn3p08.png': "865358d285a8d8682a16b050d9c1b7492042e1a217b0b5753ad28ae1a698dd77150f8cd6510f345157e1efa1411b4e4d5938a81024c150c9d5e76e423105d9c8",
+ 'tbrn2c08.png': "cc3cd3b8b6cc9920914e0184bdedcf9e59975db3f99c39b93ea1202cf6e11689eb966fc40ae2caca8ef224a8aac03723142b58b701ca2a02fd73a62e379f7a6b",
+ 'tbwn0g16.png': "fa8359bf8cdac3ab9ac54cd4f1e96b1469ff3e3494102be179b5c7394a4e37953ef54f5e1ccffe771b4f028225ec164b410b0d08f82224ed93a654433feb14fe",
+ 'tbwn3p08.png': "a0e10707fe9df085596a724561ba6c80662f87095ba479b2345c985f4beb2933f7767fe3d07b30002591259dc14012f4b26fa9b503cc75fd644def7c27c9f2e6",
+ 'tbyn3p08.png': "9920b40b016c4a05a094c28a989d06e108e2ebd5d72c2a6ddca359b68ad95238b0b6dca0f60b78c56b551a2e44f924d5a443071bda6f6e31669b0a78c09b18af",
+ 'tm3n3p02.png': "e9910a8ccb78a10980c55c6ca7115757b48075e42c14a83aece92a7f85eee538d5e1d9301efc443a867628993ceff1c13aebcc574641ad85eec48ae05df9997c",
+ 'tp0n0g08.png': "57fbf8a07060565c23918420952d1feb506ce5b1bdb25f22d41ee1de4ce9655c6dde04b9643d2491b59efba229b7e0cacd6799010a89005802c28a300a4e578e",
+ 'tp0n2c08.png': "eed3f6c18bd81d96870a47c737574746293c71c517b6a5ba88afdad5ef89fa30d975717f8a8f84ec16cb98390353934cbdd6e4b099e86f0ca3fe8d50fa07bb11",
+ 'tp0n3p08.png': "9650347d0f4a1a6596828f48766949947148952c93c4899541324a48289ea558c5d7bd1a076ac0e32f71d197e478ffc418e424c52b3fcacd2f94eaae98a566c3",
+ 'tp1n3p08.png': "fbd0f987d98d96f85679ec237c05925032e8d7783551b3f3cffb1b7db6ebdb3afb61214460386b2a3a011826bbda8340757ba22727325eea9fe518c136969f24",
+ 'xc1n0g08.png': "6aa3e16f11e82378fa7d3767a785840960f2c152338374e3f64f94eb0799e1f29637a1a66435b6dcdbffb9208efbff65a70e17e80f1e05b3038a837dcf79312c",
+ 'xc9n2c08.png': "7e0d4285bc67345e092656f04b235b4fc273c7892e26dea339dc2bb8df6348d8477f7e6573fe4f40ede1c94b49a60d46ef47ff4f7327fb12cd6de3737e8b5e4c",
+ 'xcrn0g04.png': "f971b781eb229ada882bb333bbcce956740f9761581d68ba95b49d998b89499bdd4598c4155e72240d6a5b74c04d7081fe284f78fd3f85f2550a3d2171f6efbb",
+ 'xcsn0g01.png': "9e1d234c3775920546ab9f9eeabdb75457bd823d48ed677fdfe61a95c02c65730182ba7e84209bfbf59de5d1bea533ca57c90ff6a49ea6d5749636f949bdc16a",
+ 'xd0n2c08.png': "6458d4b8f10a01ff86207496fbf38b25c35857cc537e9e11085fd5fa7befe956e707e6c1c61bdd76a393a816fdc916e2003fcecf5b33dfeb53c4bb071110eaf0",
+ 'xd3n2c08.png': "fdf261941945d1231ff3b8e91db063ac5a52e8e56f1fc80c5c51149ed255a4eebb4351194d76ae156bdff1eaf5180184c2aa2dd27e4129498279360e00d7db4e",
+ 'xd9n2c08.png': "b7a3a47c0863bde4ae8aa5ef5fe5d43f8e29abb413dc002553b63d6a4c1fb79eaee66011f1f45887c218aef3fcd63fda847a1b1bc1975252c3b4fcad553c7b70",
+ 'xdtn0g01.png': "788ed6f9e7ed64e5f4dfa8b62dd88f6f37f7abd1c8e3abf4db2d1c46f0344e7ba638f6721e69ebffa19cf6536f7685f485e9eb548a3cae55131963da05950acd",
+ 'xhdn0g08.png': "1f06044e4607902e7bd8ba291bf2b9bbb855a881b4a7dde6a21e9f5f9b74f0f43f55a8aa31fa6d1c225d0dc891744943c1544aa17836b3ecf900f041b1cca23c",
+ 'xlfn0g04.png': "bf3467f8aa9d35f7ae17cd59c3b2d5f6bf110b71afdb3a501ee88306647d669e8419e78b93b995651193a9ff99c849f82530a0bd410cec445feffe36c8df8dd1",
+ 'xs1n0g01.png': "d1bae1e471886f1661354f23b3564a34c9e1b076bd158ba129388aeb1f287d39ba647269b955bf3cc81f2b962ac6a3eb1a887a8c85243574e84778e48096cf88",
+ 'xs2n0g01.png': "abd509aa6253d8367980e4f6f4d96bb4b3732287601a7bd3dfb0fa4c70dc3908937c16e6459961421409c74f9952b4693ed1d352dc002bd120a57ba5407cac1f",
+ 'xs4n0g01.png': "015a1bdc1f878435c3de87feed442e467b3c96f3db3134d1e23653b6759a3a3d68f05325d15992ecce18ec5c00cab7e430c1965ccf36b434d8c9f9a4e8194bfe",
+ 'xs7n0g01.png': "03dab5037599a58f25dcbd1be556ff60dba08ed3e0e92e5791c53e98041b0ef174a9ebdf75fd997696521ca96a19ca1bb9a5eff929f1a7c0dc1a7d3598d07d04",
+ 'z00n2c08.png': "9a65f94ebb3614b65e093534a7763f55687144fc9a82e2680e7cad9863d72947a0de3dfe57468e11b578234b8460485e8ee895c681c391d140d84b15c7a40f41",
+ 'z03n2c08.png': "847fd249d190ccd8ec54afc910afaecf007db7ea5753c18eec8de654b159f4cdf99b70bdd55ec276ce5340fd2ede5290468fe4c6029b5e4c0825ca881a75bde3",
+ 'z06n2c08.png': "94268c1998de1f4304d24219e31175def7375cc26e2bbfc7d1ac20465a42fae49bcc8ff7626873138b537588e8bce21b6d5e1373efaade1f83cae455334074aa",
+ 'z09n2c08.png': "3cbb1bb58d78ecc9dd5568a8e9093ba020b63449ef3ab102f98fac4220fc9619feaa873336a25f3c1ad99cfb3e5d32bcfe52d966bc8640d1d5ba4e061741743e",
+
+ 'unicode.xml': "e0cdc94f07fdbb15eea811ed2ae6dcf494a83d197dafe6580c740270feb0d8f5f7146d4a7d4c2d2ea25f8bd9678bc986123484b39399819a6b7262687959d1ae",
+}
def try_download_file(url, out_file):
try:
with urllib.request.urlopen(url) as response, open(out_file, 'wb') as of:
shutil.copyfileobj(response, of)
- print("... ", out_file)
except urllib.error.HTTPError:
print("Could not download", url)
return 1
@@ -55,24 +207,39 @@ def try_download_and_unpack_zip(suite):
url = ASSETS_BASE_URL.format(suite, "{}.zip".format(suite))
out_file = DOWNLOAD_BASE_PATH.format(suite) + "/{}.zip".format(suite)
- print("\tDownloading {} to {}.".format(url, out_file))
+ print("\tDownloading {} to {}".format(url, out_file))
if try_download_file(url, out_file) is not None:
print("Could not download ZIP file")
return 1
# Try opening the ZIP file and extracting the test images
- try:
- with zipfile.ZipFile(out_file) as z:
- for file in z.filelist:
- filename = file.filename
- extract_path = DOWNLOAD_BASE_PATH.format(suite)
+ #try:
+ with zipfile.ZipFile(out_file) as z:
+ print("\tUnpacking and verifying using HMAC(\"{}\", data, {}):\n".format(HMAC_KEY, HMAC_HASH.__name__))
+ for file in z.filelist:
+ if file.filename not in HMAC_DIGESTS:
+ print("Missing digest for {}".format(file.filename))
+ return 3
- print("\t\tExtracting: {}".format(filename))
- z.extract(file, extract_path)
- except:
- print("Could not extract ZIP file")
- return 2
+ extract_path = DOWNLOAD_BASE_PATH.format(suite)
+ z.extract(file, extract_path)
+
+ file_path = "{}/{}".format(extract_path, file.filename)
+
+ with open(file_path, "rb") as f:
+ file_data = f.read()
+ digest = hashlib.sha3_512(file_data).hexdigest()
+
+ hmac_digest = hmac.new(HMAC_KEY.encode(), file_data, HMAC_HASH).hexdigest()
+ print("{} *{}".format(hmac_digest, file.filename))
+ if not hmac.compare_digest(hmac_digest, HMAC_DIGESTS[file.filename]):
+ print("FAIL! Expected: {}".format(HMAC_DIGESTS[file.filename]))
+ return 4
+
+ #except:
+ # print("Could not extract ZIP file")
+ # return 2
def main():
for suite in TEST_SUITES:
@@ -91,9 +258,7 @@ def main():
return r
# We could fall back on downloading the PNG files individually, but it's slow
- print("Done downloading {} assets.".format(suite))
-
-
+ print("\nDone downloading {} assets.".format(suite))
return 0
diff --git a/tests/core/image/test_core_image.odin b/tests/core/image/test_core_image.odin
index 54b3608b7..ae92ca617 100644
--- a/tests/core/image/test_core_image.odin
+++ b/tests/core/image/test_core_image.odin
@@ -1580,7 +1580,7 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
{
// Roundtrip through PBM to test the PBM encoders and decoders - prefer ASCII
- pbm_info, pbm_format_selected := pbm.autoselect_pbm_format_from_image(img, false)
+ pbm_info, _ := pbm.autoselect_pbm_format_from_image(img, false)
// We already tested the binary formats above.
if pbm_info.header.format in pbm.ASCII {
@@ -1912,4 +1912,4 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
}
return
-}
\ No newline at end of file
+}
diff --git a/tests/internal/Makefile b/tests/internal/Makefile
index 00e46197b..c5c612cdd 100644
--- a/tests/internal/Makefile
+++ b/tests/internal/Makefile
@@ -1,6 +1,6 @@
ODIN=../../odin
-all: rtti_test map_test pow_test
+all: rtti_test map_test pow_test 128_test asan_test
rtti_test:
$(ODIN) run test_rtti.odin -file -vet -strict-style -o:minimal
@@ -9,4 +9,10 @@ map_test:
$(ODIN) run test_map.odin -file -vet -strict-style -o:minimal
pow_test:
- $(ODIN) run test_pow.odin -file -vet -strict-style -o:minimal
\ No newline at end of file
+ $(ODIN) run test_pow.odin -file -vet -strict-style -o:minimal
+
+128_test:
+ $(ODIN) run test_128.odin -file -vet -strict-style -o:minimal
+
+asan_test:
+ $(ODIN) run test_asan.odin -file -sanitize:address -debug
diff --git a/tests/internal/build.bat b/tests/internal/build.bat
index f289d17fa..da4fe890d 100644
--- a/tests/internal/build.bat
+++ b/tests/internal/build.bat
@@ -3,4 +3,6 @@ set PATH_TO_ODIN==..\..\odin
rem %PATH_TO_ODIN% run test_rtti.odin -file -vet -strict-style -o:minimal || exit /b
%PATH_TO_ODIN% run test_map.odin -file -vet -strict-style -o:minimal || exit /b
rem -define:SEED=42
-%PATH_TO_ODIN% run test_pow.odin -file -vet -strict-style -o:minimal || exit /b
\ No newline at end of file
+%PATH_TO_ODIN% run test_pow.odin -file -vet -strict-style -o:minimal || exit /b
+
+%PATH_TO_ODIN% run test_128.odin -file -vet -strict-style -o:minimal || exit /b
diff --git a/tests/internal/test_128.odin b/tests/internal/test_128.odin
new file mode 100644
index 000000000..11ef068ed
--- /dev/null
+++ b/tests/internal/test_128.odin
@@ -0,0 +1,59 @@
+package test_128
+
+import "core:fmt"
+import "core:os"
+import "core:testing"
+
+TEST_count := 0
+TEST_fail := 0
+
+when ODIN_TEST {
+ expect :: testing.expect
+ log :: testing.log
+} else {
+ expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
+ TEST_count += 1
+ if !condition {
+ TEST_fail += 1
+ fmt.printf("[%v] %v\n", loc, message)
+ return
+ }
+ }
+ log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
+ fmt.printf("[%v] ", loc)
+ fmt.printf("log: %v\n", v)
+ }
+}
+
+main :: proc() {
+ t := testing.T{}
+
+ test_128_align(&t)
+
+ fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
+ if TEST_fail > 0 {
+ os.exit(1)
+ }
+}
+
+@test
+test_128_align :: proc(t: ^testing.T) {
+ Danger_Struct :: struct {
+ x: u128,
+ y: u64,
+ }
+
+ list := [?]Danger_Struct{{0, 0}, {1, 0}, {2, 0}, {3, 0}}
+
+ expect(t, list[0].x == 0, fmt.tprintf("[0].x (%v) != 0", list[0].x))
+ expect(t, list[0].y == 0, fmt.tprintf("[0].y (%v) != 0", list[0].y))
+
+ expect(t, list[1].x == 1, fmt.tprintf("[1].x (%v) != 1", list[1].x))
+ expect(t, list[1].y == 0, fmt.tprintf("[1].y (%v) != 0", list[1].y))
+
+ expect(t, list[2].x == 2, fmt.tprintf("[2].x (%v) != 2", list[2].x))
+ expect(t, list[2].y == 0, fmt.tprintf("[2].y (%v) != 0", list[2].y))
+
+ expect(t, list[3].x == 3, fmt.tprintf("[3].x (%v) != 3", list[3].x))
+ expect(t, list[3].y == 0, fmt.tprintf("[3].y (%v) != 0", list[3].y))
+}
diff --git a/tests/internal/test_asan.odin b/tests/internal/test_asan.odin
new file mode 100644
index 000000000..2384ada76
--- /dev/null
+++ b/tests/internal/test_asan.odin
@@ -0,0 +1,62 @@
+// Intended to contain code that would trigger asan easily if the abi was set up badly.
+package test_asan
+
+import "core:fmt"
+import "core:testing"
+import "core:os"
+
+TEST_count := 0
+TEST_fail := 0
+
+when ODIN_TEST {
+ expect :: testing.expect
+ log :: testing.log
+} else {
+ expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
+ TEST_count += 1
+ if !condition {
+ TEST_fail += 1
+ fmt.printf("[%v] %v\n", loc, message)
+ return
+ }
+ }
+ log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
+ fmt.printf("[%v] ", loc)
+ fmt.printf("log: %v\n", v)
+ }
+}
+
+main :: proc() {
+ t := testing.T{}
+
+ test_12_bytes(&t)
+ test_12_bytes_two(&t)
+
+ fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
+ if TEST_fail > 0 {
+ os.exit(1)
+ }
+}
+
+@(test)
+test_12_bytes :: proc(t: ^testing.T) {
+ internal :: proc() -> (a, b: f32, ok: bool) {
+ return max(f32), 0, true
+ }
+
+ a, b, ok := internal()
+ expect(t, a == max(f32), fmt.tprintf("a (%v) != max(f32)", a))
+ expect(t, b == 0, fmt.tprintf("b (%v) != 0", b))
+ expect(t, ok, fmt.tprintf("ok (%v) != true", ok))
+}
+
+@(test)
+test_12_bytes_two :: proc(t: ^testing.T) {
+ internal :: proc() -> (a: f32, b: int) {
+ return 100., max(int)
+ }
+
+ a, b := internal()
+ expect(t, a == 100., fmt.tprintf("a (%v) != 100.", a))
+ expect(t, b == max(int), fmt.tprintf("b (%v) != max(int)", b))
+}
diff --git a/tests/internal/test_map.odin b/tests/internal/test_map.odin
index 2c808d85e..7d1dbf470 100644
--- a/tests/internal/test_map.odin
+++ b/tests/internal/test_map.odin
@@ -32,7 +32,7 @@ map_insert_random_key_value :: proc(t: ^testing.T) {
}
key_count := 0
- for k in m {
+ for _ in m {
key_count += 1
}
@@ -82,7 +82,7 @@ map_update_random_key_value :: proc(t: ^testing.T) {
}
key_count := 0
- for k in m {
+ for _ in m {
key_count += 1
}
@@ -144,7 +144,7 @@ map_delete_random_key_value :: proc(t: ^testing.T) {
}
key_count := 0
- for k in m {
+ for _ in m {
key_count += 1
}
@@ -220,7 +220,7 @@ set_insert_random_key_value :: proc(t: ^testing.T) {
}
key_count := 0
- for k in m {
+ for _ in m {
key_count += 1
}
@@ -268,7 +268,7 @@ set_delete_random_key_value :: proc(t: ^testing.T) {
}
key_count := 0
- for k in m {
+ for _ in m {
key_count += 1
}
@@ -379,4 +379,4 @@ when ODIN_TEST {
fmt.printf("[%v] ", loc)
fmt.printf("log: %v\n", v)
}
-}
\ No newline at end of file
+}
diff --git a/vendor/darwin/Foundation/NSApplication.odin b/vendor/darwin/Foundation/NSApplication.odin
index c87a3d44c..d332345f9 100644
--- a/vendor/darwin/Foundation/NSApplication.odin
+++ b/vendor/darwin/Foundation/NSApplication.odin
@@ -79,11 +79,22 @@ Application_setActivationPolicy :: proc "c" (self: ^Application, activationPolic
return msgSend(BOOL, self, "setActivationPolicy:", activationPolicy)
}
+@(deprecated="Use NSApplication method activate instead.")
@(objc_type=Application, objc_name="activateIgnoringOtherApps")
Application_activateIgnoringOtherApps :: proc "c" (self: ^Application, ignoreOtherApps: BOOL) {
msgSend(nil, self, "activateIgnoringOtherApps:", ignoreOtherApps)
}
+@(objc_type=Application, objc_name="activate")
+Application_activate :: proc "c" (self: ^Application) {
+ msgSend(nil, self, "activate")
+}
+
+@(objc_type=Application, objc_name="setTitle")
+Application_setTitle :: proc "c" (self: ^Application, title: ^String) {
+ msgSend(nil, self, "setTitle", title)
+}
+
@(objc_type=Application, objc_name="setMainMenu")
Application_setMainMenu :: proc "c" (self: ^Application, menu: ^Menu) {
msgSend(nil, self, "setMainMenu:", menu)
diff --git a/vendor/microui/microui.odin b/vendor/microui/microui.odin
index 1ddad2121..495289ede 100644
--- a/vendor/microui/microui.odin
+++ b/vendor/microui/microui.odin
@@ -1316,10 +1316,10 @@ begin_window :: proc(ctx: ^Context, title: string, rect: Rect, opt := Options{})
/* do title text */
if .NO_TITLE not_in opt {
- id := get_id(ctx, "!title")
- update_control(ctx, id, tr, opt)
+ tid := get_id(ctx, "!title")
+ update_control(ctx, tid, tr, opt)
draw_control_text(ctx, title, tr, .TITLE_TEXT, opt)
- if id == ctx.focus_id && ctx.mouse_down_bits == {.LEFT} {
+ if tid == ctx.focus_id && ctx.mouse_down_bits == {.LEFT} {
cnt.rect.x += ctx.mouse_delta.x
cnt.rect.y += ctx.mouse_delta.y
}
@@ -1329,12 +1329,12 @@ begin_window :: proc(ctx: ^Context, title: string, rect: Rect, opt := Options{})
/* do `close` button */
if .NO_CLOSE not_in opt {
- id := get_id(ctx, "!close")
+ cid := get_id(ctx, "!close")
r := Rect{tr.x + tr.w - tr.h, tr.y, tr.h, tr.h}
tr.w -= r.w
draw_icon(ctx, .CLOSE, r, ctx.style.colors[.TITLE_TEXT])
- update_control(ctx, id, r, opt)
- if .LEFT in ctx.mouse_released_bits && id == ctx.hover_id {
+ update_control(ctx, cid, r, opt)
+ if .LEFT in ctx.mouse_released_bits && cid == ctx.hover_id {
cnt.open = false
}
}
@@ -1343,11 +1343,11 @@ begin_window :: proc(ctx: ^Context, title: string, rect: Rect, opt := Options{})
/* do `resize` handle */
if .NO_RESIZE not_in opt {
sz := ctx.style.footer_height
- id := get_id(ctx, "!resize")
+ rid := get_id(ctx, "!resize")
r := Rect{rect.x + rect.w - sz, rect.y + rect.h - sz, sz, sz}
draw_icon(ctx, .RESIZE, r, ctx.style.colors[.TEXT])
- update_control(ctx, id, r, opt)
- if id == ctx.focus_id && .LEFT in ctx.mouse_down_bits {
+ update_control(ctx, rid, r, opt)
+ if rid == ctx.focus_id && .LEFT in ctx.mouse_down_bits {
cnt.rect.w = max(96, cnt.rect.w + ctx.mouse_delta.x)
cnt.rect.h = max(64, cnt.rect.h + ctx.mouse_delta.y)
}
diff --git a/vendor/nanovg/nanovg.odin b/vendor/nanovg/nanovg.odin
index 74fc70692..15611cfef 100644
--- a/vendor/nanovg/nanovg.odin
+++ b/vendor/nanovg/nanovg.odin
@@ -2009,7 +2009,7 @@ __expandStroke :: proc(
}
}
- for j in start.. c.int ---
SemTryWait :: proc(s: ^sem) -> c.int ---
SemWaitTimeout :: proc(s: ^sem, ms: u32) -> c.int ---
+ SemPost :: proc(s: ^sem) -> c.int ---
SemValue :: proc(s: ^sem) -> u32 ---
CreateCond :: proc() -> ^cond ---