mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-12 07:45:24 +00:00
Merge branch 'master' into windows-llvm-13.0.0
This commit is contained in:
@@ -25,10 +25,6 @@ _read_writer_vtable := &io.Stream_VTable{
|
||||
b := (^Read_Writer)(s.stream_data).r
|
||||
return reader_read(b, p)
|
||||
},
|
||||
impl_read_byte = proc(s: io.Stream) -> (c: byte, err: io.Error) {
|
||||
b := (^Read_Writer)(s.stream_data).r
|
||||
return reader_read_byte(b)
|
||||
},
|
||||
impl_unread_byte = proc(s: io.Stream) -> io.Error {
|
||||
b := (^Read_Writer)(s.stream_data).r
|
||||
return reader_unread_byte(b)
|
||||
|
||||
@@ -122,73 +122,3 @@ to_write_seeker :: proc(s: Stream) -> (w: Write_Seeker, ok: bool = true) #option
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
to_byte_reader :: proc(s: Stream) -> (b: Byte_Reader, ok: bool = true) #optional_ok {
|
||||
b.stream = s
|
||||
if s.stream_vtable == nil || s.impl_read_byte == nil {
|
||||
ok = false
|
||||
if s.stream_vtable != nil && s.impl_read != nil {
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
to_byte_scanner :: proc(s: Stream) -> (b: Byte_Scanner, ok: bool = true) #optional_ok {
|
||||
b.stream = s
|
||||
if s.stream_vtable != nil {
|
||||
if s.impl_unread_byte == nil {
|
||||
ok = false
|
||||
return
|
||||
}
|
||||
if s.impl_read_byte != nil {
|
||||
ok = true
|
||||
} else if s.impl_read != nil {
|
||||
ok = true
|
||||
} else {
|
||||
ok = false
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
to_byte_writer :: proc(s: Stream) -> (b: Byte_Writer, ok: bool = true) #optional_ok {
|
||||
b.stream = s
|
||||
if s.stream_vtable == nil || s.impl_write_byte == nil {
|
||||
ok = false
|
||||
if s.stream_vtable != nil && s.impl_write != nil {
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
to_rune_reader :: proc(s: Stream) -> (r: Rune_Reader, ok: bool = true) #optional_ok {
|
||||
r.stream = s
|
||||
if s.stream_vtable == nil || s.impl_read_rune == nil {
|
||||
ok = false
|
||||
if s.stream_vtable != nil && s.impl_read != nil {
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
to_rune_scanner :: proc(s: Stream) -> (r: Rune_Scanner, ok: bool = true) #optional_ok {
|
||||
r.stream = s
|
||||
if s.stream_vtable != nil {
|
||||
if s.impl_unread_rune == nil {
|
||||
ok = false
|
||||
return
|
||||
}
|
||||
if s.impl_read_rune != nil {
|
||||
ok = true
|
||||
} else if s.impl_read != nil {
|
||||
ok = true
|
||||
} else {
|
||||
ok = false
|
||||
}
|
||||
} else {
|
||||
ok = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -123,13 +123,6 @@ Writer_At :: struct {using stream: Stream}
|
||||
Reader_From :: struct {using stream: Stream}
|
||||
Writer_To :: struct {using stream: Stream}
|
||||
|
||||
Byte_Reader :: struct {using stream: Stream}
|
||||
Byte_Scanner :: struct {using stream: Stream}
|
||||
Byte_Writer :: struct {using stream: Stream}
|
||||
|
||||
Rune_Reader :: struct {using stream: Stream}
|
||||
Rune_Scanner :: struct {using stream: Stream}
|
||||
|
||||
|
||||
destroy :: proc(s: Stream) -> Error {
|
||||
close_err := close({s})
|
||||
@@ -147,24 +140,48 @@ destroy :: proc(s: Stream) -> Error {
|
||||
// When read encounters an .EOF or error after successfully reading n > 0 bytes, it returns the number of
|
||||
// bytes read along with the error.
|
||||
read :: proc(s: Reader, p: []byte, n_read: ^int = nil) -> (n: int, err: Error) {
|
||||
if s.stream_vtable != nil && s.impl_read != nil {
|
||||
n, err = s->impl_read(p)
|
||||
if n_read != nil {
|
||||
n_read^ += n
|
||||
if s.stream_vtable != nil {
|
||||
if s.impl_read != nil {
|
||||
n, err = s->impl_read(p)
|
||||
if n_read != nil {
|
||||
n_read^ += n
|
||||
}
|
||||
return
|
||||
} else if s.impl_read_byte != nil {
|
||||
bytes_read := 0
|
||||
defer if n_read != nil {
|
||||
n_read^ += bytes_read
|
||||
}
|
||||
for _, i in p {
|
||||
p[i] = s->impl_read_byte() or_return
|
||||
bytes_read += 1
|
||||
}
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
return 0, .Empty
|
||||
}
|
||||
|
||||
// write writes up to len(p) bytes into s. It returns the number of bytes written and any error if occurred.
|
||||
write :: proc(s: Writer, p: []byte, n_written: ^int = nil) -> (n: int, err: Error) {
|
||||
if s.stream_vtable != nil && s.impl_write != nil {
|
||||
n, err = s->impl_write(p)
|
||||
if n_written != nil {
|
||||
n_written^ += n
|
||||
if s.stream_vtable != nil {
|
||||
if s.impl_write != nil {
|
||||
n, err = s->impl_write(p)
|
||||
if n_written != nil {
|
||||
n_written^ += n
|
||||
}
|
||||
return
|
||||
} else if s.impl_write_byte != nil {
|
||||
bytes_written := 0
|
||||
defer if n_written != nil {
|
||||
n_written^ += bytes_written
|
||||
}
|
||||
for c in p {
|
||||
s->impl_write_byte(c) or_return
|
||||
bytes_written += 1
|
||||
}
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
return 0, .Empty
|
||||
}
|
||||
@@ -319,7 +336,7 @@ read_from :: proc(w: Reader_From, r: Reader) -> (n: i64, err: Error) {
|
||||
|
||||
|
||||
// read_byte reads and returns the next byte from r.
|
||||
read_byte :: proc(r: Byte_Reader, n_read: ^int = nil) -> (b: byte, err: Error) {
|
||||
read_byte :: proc(r: Reader, n_read: ^int = nil) -> (b: byte, err: Error) {
|
||||
defer if err == nil && n_read != nil {
|
||||
n_read^ += 1
|
||||
}
|
||||
@@ -339,21 +356,12 @@ read_byte :: proc(r: Byte_Reader, n_read: ^int = nil) -> (b: byte, err: Error) {
|
||||
return buf[0], err
|
||||
}
|
||||
|
||||
write_byte :: proc{
|
||||
write_byte_to_byte_writer,
|
||||
write_byte_to_writer,
|
||||
}
|
||||
|
||||
write_byte_to_byte_writer :: proc(w: Byte_Writer, c: byte, n_written: ^int = nil) -> Error {
|
||||
return _write_byte(w, c, n_written)
|
||||
}
|
||||
|
||||
write_byte_to_writer :: proc(w: Writer, c: byte, n_written: ^int = nil) -> Error {
|
||||
write_byte :: proc(w: Writer, c: byte, n_written: ^int = nil) -> Error {
|
||||
return _write_byte(auto_cast w, c, n_written)
|
||||
}
|
||||
|
||||
@(private)
|
||||
_write_byte :: proc(w: Byte_Writer, c: byte, n_written: ^int = nil) -> (err: Error) {
|
||||
_write_byte :: proc(w: Writer, c: byte, n_written: ^int = nil) -> (err: Error) {
|
||||
defer if err == nil && n_written != nil {
|
||||
n_written^ += 1
|
||||
}
|
||||
@@ -373,7 +381,7 @@ _write_byte :: proc(w: Byte_Writer, c: byte, n_written: ^int = nil) -> (err: Err
|
||||
}
|
||||
|
||||
// read_rune reads a single UTF-8 encoded Unicode codepoint and returns the rune and its size in bytes.
|
||||
read_rune :: proc(br: Rune_Reader, n_read: ^int = nil) -> (ch: rune, size: int, err: Error) {
|
||||
read_rune :: proc(br: Reader, n_read: ^int = nil) -> (ch: rune, size: int, err: Error) {
|
||||
defer if err == nil && n_read != nil {
|
||||
n_read^ += size
|
||||
}
|
||||
@@ -417,13 +425,21 @@ read_rune :: proc(br: Rune_Reader, n_read: ^int = nil) -> (ch: rune, size: int,
|
||||
return
|
||||
}
|
||||
|
||||
unread_byte :: proc(s: Byte_Scanner) -> Error {
|
||||
if s.stream_vtable != nil && s.impl_unread_byte != nil {
|
||||
unread_byte :: proc(s: Stream) -> Error {
|
||||
if s.stream_vtable == nil {
|
||||
return .Empty
|
||||
}
|
||||
if s.impl_unread_byte != nil {
|
||||
return s->impl_unread_byte()
|
||||
}
|
||||
if s.impl_seek != nil {
|
||||
_, err := s->impl_seek(-1, .Current)
|
||||
return err
|
||||
}
|
||||
|
||||
return .Empty
|
||||
}
|
||||
unread_rune :: proc(s: Rune_Scanner) -> Error {
|
||||
unread_rune :: proc(s: Writer) -> Error {
|
||||
if s.stream_vtable != nil && s.impl_unread_rune != nil {
|
||||
return s->impl_unread_rune()
|
||||
}
|
||||
@@ -442,7 +458,10 @@ write_rune :: proc(s: Writer, r: rune, n_written: ^int = nil) -> (size: int, err
|
||||
n_written^ += size
|
||||
}
|
||||
|
||||
if s.stream_vtable != nil && s.impl_write_rune != nil {
|
||||
if s.stream_vtable == nil {
|
||||
return 0, .Empty
|
||||
}
|
||||
if s.impl_write_rune != nil {
|
||||
return s->impl_write_rune(r)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ Proc_Tag :: enum {
|
||||
Bounds_Check,
|
||||
No_Bounds_Check,
|
||||
Optional_Ok,
|
||||
Optional_Second,
|
||||
Optional_Allocator_Error,
|
||||
}
|
||||
Proc_Tags :: distinct bit_set[Proc_Tag; u32]
|
||||
|
||||
|
||||
@@ -2062,7 +2062,7 @@ parse_proc_tags :: proc(p: ^Parser) -> (tags: ast.Proc_Tags) {
|
||||
case "bounds_check": tags += {.Bounds_Check}
|
||||
case "no_bounds_check": tags += {.No_Bounds_Check}
|
||||
case "optional_ok": tags += {.Optional_Ok}
|
||||
case "optional_second": tags += {.Optional_Second}
|
||||
case "optional_allocator_error": tags += {.Optional_Allocator_Error}
|
||||
case:
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ delete :: proc{
|
||||
// The new built-in procedure allocates memory. The first argument is a type, not a value, and the value
|
||||
// return is a pointer to a newly allocated value of that type using the specified allocator, default is context.allocator
|
||||
@builtin
|
||||
new :: proc($T: typeid, allocator := context.allocator, loc := #caller_location) -> (^T, Allocator_Error) #optional_second {
|
||||
new :: proc($T: typeid, allocator := context.allocator, loc := #caller_location) -> (^T, Allocator_Error) #optional_allocator_error {
|
||||
return new_aligned(T, align_of(T), allocator, loc)
|
||||
}
|
||||
new_aligned :: proc($T: typeid, alignment: int, allocator := context.allocator, loc := #caller_location) -> (t: ^T, err: Allocator_Error) {
|
||||
@@ -199,7 +199,7 @@ new_aligned :: proc($T: typeid, alignment: int, allocator := context.allocator,
|
||||
}
|
||||
|
||||
@builtin
|
||||
new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_location) -> (t: ^T, err: Allocator_Error) #optional_second {
|
||||
new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_location) -> (t: ^T, err: Allocator_Error) #optional_allocator_error {
|
||||
t_data := mem_alloc_bytes(size_of(T), align_of(T), allocator, loc) or_return
|
||||
t = (^T)(raw_data(t_data))
|
||||
if t != nil {
|
||||
@@ -210,7 +210,7 @@ new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_locat
|
||||
|
||||
DEFAULT_RESERVE_CAPACITY :: 16
|
||||
|
||||
make_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_second {
|
||||
make_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error {
|
||||
make_slice_error_loc(loc, len)
|
||||
data, err := mem_alloc_bytes(size_of(E)*len, alignment, allocator, loc)
|
||||
if data == nil && size_of(E) != 0 {
|
||||
@@ -221,19 +221,19 @@ make_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocat
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
make_slice :: proc($T: typeid/[]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_second {
|
||||
make_slice :: proc($T: typeid/[]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error {
|
||||
return make_aligned(T, len, align_of(E), allocator, loc)
|
||||
}
|
||||
@(builtin)
|
||||
make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_second {
|
||||
make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error {
|
||||
return make_dynamic_array_len_cap(T, 0, DEFAULT_RESERVE_CAPACITY, allocator, loc)
|
||||
}
|
||||
@(builtin)
|
||||
make_dynamic_array_len :: proc($T: typeid/[dynamic]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_second {
|
||||
make_dynamic_array_len :: proc($T: typeid/[dynamic]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error {
|
||||
return make_dynamic_array_len_cap(T, len, len, allocator, loc)
|
||||
}
|
||||
@(builtin)
|
||||
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) #optional_second {
|
||||
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) #optional_allocator_error {
|
||||
make_dynamic_array_error_loc(loc, len, cap)
|
||||
data := mem_alloc_bytes(size_of(E)*cap, align_of(E), allocator, loc) or_return
|
||||
s := Raw_Dynamic_Array{raw_data(data), len, cap, allocator}
|
||||
@@ -253,7 +253,7 @@ make_map :: proc($T: typeid/map[$K]$E, #any_int cap: int = DEFAULT_RESERVE_CAPAC
|
||||
return m
|
||||
}
|
||||
@(builtin)
|
||||
make_multi_pointer :: proc($T: typeid/[^]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (mp: T, err: Allocator_Error) #optional_second {
|
||||
make_multi_pointer :: proc($T: typeid/[^]$E, #any_int len: int, allocator := context.allocator, loc := #caller_location) -> (mp: T, err: Allocator_Error) #optional_allocator_error {
|
||||
make_slice_error_loc(loc, len)
|
||||
data := mem_alloc_bytes(size_of(E)*len, align_of(E), allocator, loc) or_return
|
||||
if data == nil && size_of(E) != 0 {
|
||||
|
||||
@@ -79,7 +79,7 @@ raw_soa_footer :: proc{
|
||||
|
||||
|
||||
@builtin
|
||||
make_soa_aligned :: proc($T: typeid/#soa[]$E, length: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_second {
|
||||
make_soa_aligned :: proc($T: typeid/#soa[]$E, length: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error {
|
||||
if length <= 0 {
|
||||
return
|
||||
}
|
||||
@@ -138,7 +138,7 @@ make_soa_aligned :: proc($T: typeid/#soa[]$E, length: int, alignment: int, alloc
|
||||
}
|
||||
|
||||
@builtin
|
||||
make_soa_slice :: proc($T: typeid/#soa[]$E, length: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_second {
|
||||
make_soa_slice :: proc($T: typeid/#soa[]$E, length: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error {
|
||||
return make_soa_aligned(T, length, align_of(E), allocator, loc)
|
||||
}
|
||||
|
||||
|
||||
@@ -42,20 +42,6 @@ to_reader_at :: proc(r: ^Reader, s: string) -> io.Reader_At {
|
||||
return rr
|
||||
}
|
||||
|
||||
// init a reader to the string `s` and return an io.Byte_Reader
|
||||
to_byte_reader :: proc(r: ^Reader, s: string) -> io.Byte_Reader {
|
||||
reader_init(r, s)
|
||||
rr, _ := io.to_byte_reader(reader_to_stream(r))
|
||||
return rr
|
||||
}
|
||||
|
||||
// init a reader to the string `s` and return an io.Rune_Reader
|
||||
to_rune_reader :: proc(r: ^Reader, s: string) -> io.Rune_Reader {
|
||||
reader_init(r, s)
|
||||
rr, _ := io.to_rune_reader(reader_to_stream(r))
|
||||
return rr
|
||||
}
|
||||
|
||||
// remaining length of the reader
|
||||
reader_length :: proc(r: ^Reader) -> int {
|
||||
if r.i >= i64(len(r.s)) {
|
||||
|
||||
@@ -937,14 +937,14 @@ index_any :: proc(s, chars: string) -> int {
|
||||
}
|
||||
|
||||
/*
|
||||
returns the index of any first char of `chars` found in `s`, -1 if not found
|
||||
returns the last matching index in `s` of any char in `chars` found in `s`, -1 if not found
|
||||
iterates the string in reverse
|
||||
|
||||
strings.index_any("test", "s") -> 2
|
||||
strings.index_any("test", "se") -> 2
|
||||
strings.index_any("test", "et") -> 1
|
||||
strings.index_any("test", "set") -> 3
|
||||
strings.index_any("test", "x") -> -1
|
||||
strings.last_index_any("test", "s") -> 2
|
||||
strings.last_index_any("test", "se") -> 2
|
||||
strings.last_index_any("test", "et") -> 3
|
||||
strings.last_index_any("test", "set") -> 3
|
||||
strings.last_index_any("test", "x") -> -1
|
||||
*/
|
||||
last_index_any :: proc(s, chars: string) -> int {
|
||||
if chars == "" {
|
||||
|
||||
@@ -1355,6 +1355,12 @@ bool init_build_paths(String init_filename) {
|
||||
// [BuildPathMainPackage] Turn given init path into a `Path`, which includes normalizing it into a full path.
|
||||
bc->build_paths[BuildPath_Main_Package] = path_from_string(ha, init_filename);
|
||||
|
||||
{
|
||||
String build_project_name = last_path_element(bc->build_paths[BuildPath_Main_Package].basename);
|
||||
GB_ASSERT(build_project_name.len > 0);
|
||||
bc->ODIN_BUILD_PROJECT_NAME = build_project_name;
|
||||
}
|
||||
|
||||
bool produces_output_file = false;
|
||||
if (bc->command_kind == Command_doc && bc->cmd_doc_flags & CmdDocFlag_DocFormat) {
|
||||
produces_output_file = true;
|
||||
@@ -1538,12 +1544,6 @@ bool init_build_paths(String init_filename) {
|
||||
enable_target_feature({}, bc->target_features_string);
|
||||
}
|
||||
|
||||
{
|
||||
String build_project_name = last_path_element(bc->build_paths[BuildPath_Main_Package].basename);
|
||||
GB_ASSERT(build_project_name.len > 0);
|
||||
bc->ODIN_BUILD_PROJECT_NAME = build_project_name;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -2006,22 +2006,21 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pt->tags & ProcTag_optional_second) {
|
||||
if (pt->tags & ProcTag_optional_allocator_error) {
|
||||
if (optional_ok) {
|
||||
error(proc_type_node, "A procedure type cannot have both an #optional_ok tag and #optional_second");
|
||||
error(proc_type_node, "A procedure type cannot have both an #optional_ok tag and #optional_allocator_error");
|
||||
}
|
||||
optional_ok = true;
|
||||
if (result_count != 2) {
|
||||
error(proc_type_node, "A procedure type with the #optional_second tag requires 2 return values, got %td", result_count);
|
||||
error(proc_type_node, "A procedure type with the #optional_allocator_error tag requires 2 return values, got %td", result_count);
|
||||
} else {
|
||||
bool ok = false;
|
||||
AstFile *file = proc_type_node->file();
|
||||
if (file && file->pkg) {
|
||||
ok = file->pkg->scope == ctx->info->runtime_package->scope;
|
||||
}
|
||||
init_mem_allocator(c->checker);
|
||||
|
||||
if (!ok) {
|
||||
error(proc_type_node, "A procedure type with the #optional_second may only be allowed within 'package runtime'");
|
||||
Type *type = results->Tuple.variables[1]->type;
|
||||
if (!are_types_identical(type, t_allocator_error)) {
|
||||
gbString t = type_to_string(type);
|
||||
error(proc_type_node, "A procedure type with the #optional_allocator_error expects a `runtime.Allocator_Error`, got '%s'", t);
|
||||
gb_string_free(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2809,17 +2809,9 @@ void init_mem_allocator(Checker *c) {
|
||||
if (t_allocator != nullptr) {
|
||||
return;
|
||||
}
|
||||
AstPackage *pkg = get_core_package(&c->info, str_lit("runtime"));
|
||||
|
||||
String name = str_lit("Allocator");
|
||||
Entity *e = scope_lookup_current(pkg->scope, name);
|
||||
if (e == nullptr) {
|
||||
compiler_error("Could not find type declaration for '%.*s'\n", LIT(name));
|
||||
// NOTE(bill): This will exit the program as it's cannot continue without it!
|
||||
}
|
||||
|
||||
t_allocator = e->type;
|
||||
t_allocator = find_core_type(c, str_lit("Allocator"));
|
||||
t_allocator_ptr = alloc_type_pointer(t_allocator);
|
||||
t_allocator_error = find_core_type(c, str_lit("Allocator_Error"));
|
||||
}
|
||||
|
||||
void init_core_context(Checker *c) {
|
||||
@@ -2827,7 +2819,6 @@ void init_core_context(Checker *c) {
|
||||
return;
|
||||
}
|
||||
t_context = find_core_type(c, str_lit("Context"));
|
||||
GB_ASSERT(t_context != nullptr);
|
||||
t_context_ptr = alloc_type_pointer(t_context);
|
||||
}
|
||||
|
||||
|
||||
@@ -578,7 +578,7 @@ void lb_begin_procedure_body(lbProcedure *p) {
|
||||
GB_ASSERT(!is_blank_ident(e->token));
|
||||
|
||||
lbAddr res = {};
|
||||
if (return_ptr_value.value) {
|
||||
if (return_ptr_value.value != nullptr) {
|
||||
lbValue ptr = return_ptr_value;
|
||||
if (results->variables.count != 1) {
|
||||
ptr = lb_emit_struct_ep(p, ptr, cast(i32)i);
|
||||
@@ -586,6 +586,7 @@ void lb_begin_procedure_body(lbProcedure *p) {
|
||||
|
||||
res = lb_addr(ptr);
|
||||
lb_add_entity(p->module, e, ptr);
|
||||
lb_add_debug_local_variable(p, ptr.value, e->type, e->token);
|
||||
} else {
|
||||
res = lb_add_local(p, e->type, e);
|
||||
}
|
||||
@@ -594,8 +595,10 @@ void lb_begin_procedure_body(lbProcedure *p) {
|
||||
lbValue c = lb_handle_param_value(p, e->type, e->Variable.param_value, e->token.pos);
|
||||
lb_addr_store(p, res, c);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (p->type->Proc.calling_convention == ProcCC_Odin) {
|
||||
|
||||
@@ -1857,7 +1857,7 @@ void parse_proc_tags(AstFile *f, u64 *tags) {
|
||||
|
||||
if (false) {}
|
||||
ELSE_IF_ADD_TAG(optional_ok)
|
||||
ELSE_IF_ADD_TAG(optional_second)
|
||||
ELSE_IF_ADD_TAG(optional_allocator_error)
|
||||
ELSE_IF_ADD_TAG(require_results)
|
||||
ELSE_IF_ADD_TAG(bounds_check)
|
||||
ELSE_IF_ADD_TAG(no_bounds_check)
|
||||
|
||||
@@ -232,7 +232,7 @@ enum ProcTag {
|
||||
|
||||
ProcTag_require_results = 1<<4,
|
||||
ProcTag_optional_ok = 1<<5,
|
||||
ProcTag_optional_second = 1<<6,
|
||||
ProcTag_optional_allocator_error = 1<<6,
|
||||
};
|
||||
|
||||
enum ProcCallingConvention : i32 {
|
||||
|
||||
@@ -681,6 +681,7 @@ gb_global Type *t_allocator = nullptr;
|
||||
gb_global Type *t_allocator_ptr = nullptr;
|
||||
gb_global Type *t_context = nullptr;
|
||||
gb_global Type *t_context_ptr = nullptr;
|
||||
gb_global Type *t_allocator_error = nullptr;
|
||||
|
||||
gb_global Type *t_source_code_location = nullptr;
|
||||
gb_global Type *t_source_code_location_ptr = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user