From 398109ac841cb8c405b54da529837800ed8cddd1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 3 Jun 2018 10:51:43 +0100 Subject: [PATCH] Remove need for __llvm_core --- core/bits/bits.odin | 50 +++++++++++++++++++------------------- core/math/math.odin | 2 +- core/mem/mem.odin | 8 +++--- core/runtime/core.odin | 2 +- core/runtime/internal.odin | 46 +++++++++++++++++------------------ examples/demo/demo.odin | 5 +++- src/check_decl.cpp | 2 +- src/checker.cpp | 9 +++---- src/ir.cpp | 4 ++- src/parser.cpp | 22 ++++++++--------- 10 files changed, 76 insertions(+), 74 deletions(-) diff --git a/core/bits/bits.odin b/core/bits/bits.odin index 57e2ce7ae..a4c6e079e 100644 --- a/core/bits/bits.odin +++ b/core/bits/bits.odin @@ -22,7 +22,7 @@ I16_MAX :: -I16_MIN - 1; I32_MAX :: -I32_MIN - 1; I64_MAX :: -I64_MIN - 1; -foreign __llvm_core { +foreign { @(link_name="llvm.ctpop.i8") __llvm_ctpop8 :: proc(u8) -> u8 ---; @(link_name="llvm.ctpop.i16") __llvm_ctpop16 :: proc(u16) -> u16 ---; @(link_name="llvm.ctpop.i32") __llvm_ctpop32 :: proc(u32) -> u32 ---; @@ -122,14 +122,14 @@ to_le_u64 :: proc(i: u64) -> u64 { when os.ENDIAN == "little" { return i; } e to_le_uint :: proc(i: uint) -> uint { when os.ENDIAN == "little" { return i; } else { return byte_swap(i); } } -overflowing_add_u8 :: proc(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i8") op :: proc(u8, u8) -> (u8, bool) ---; return op(lhs, rhs); } -overflowing_add_i8 :: proc(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i8") op :: proc(i8, i8) -> (i8, bool) ---; return op(lhs, rhs); } -overflowing_add_u16 :: proc(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i16") op :: proc(u16, u16) -> (u16, bool) ---; return op(lhs, rhs); } -overflowing_add_i16 :: proc(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i16") op :: proc(i16, i16) -> (i16, bool) ---; return op(lhs, rhs); } -overflowing_add_u32 :: proc(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i32") op :: proc(u32, u32) -> (u32, bool) ---; return op(lhs, rhs); } -overflowing_add_i32 :: proc(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i32") op :: proc(i32, i32) -> (i32, bool) ---; return op(lhs, rhs); } -overflowing_add_u64 :: proc(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core @(link_name="llvm.uadd.with.overflow.i64") op :: proc(u64, u64) -> (u64, bool) ---; return op(lhs, rhs); } -overflowing_add_i64 :: proc(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core @(link_name="llvm.sadd.with.overflow.i64") op :: proc(i64, i64) -> (i64, bool) ---; return op(lhs, rhs); } +overflowing_add_u8 :: proc(lhs, rhs: u8) -> (u8, bool) { foreign { @(link_name="llvm.uadd.with.overflow.i8") op :: proc(u8, u8) -> (u8, bool) --- }; return op(lhs, rhs); } +overflowing_add_i8 :: proc(lhs, rhs: i8) -> (i8, bool) { foreign { @(link_name="llvm.sadd.with.overflow.i8") op :: proc(i8, i8) -> (i8, bool) --- }; return op(lhs, rhs); } +overflowing_add_u16 :: proc(lhs, rhs: u16) -> (u16, bool) { foreign { @(link_name="llvm.uadd.with.overflow.i16") op :: proc(u16, u16) -> (u16, bool) --- }; return op(lhs, rhs); } +overflowing_add_i16 :: proc(lhs, rhs: i16) -> (i16, bool) { foreign { @(link_name="llvm.sadd.with.overflow.i16") op :: proc(i16, i16) -> (i16, bool) --- }; return op(lhs, rhs); } +overflowing_add_u32 :: proc(lhs, rhs: u32) -> (u32, bool) { foreign { @(link_name="llvm.uadd.with.overflow.i32") op :: proc(u32, u32) -> (u32, bool) --- }; return op(lhs, rhs); } +overflowing_add_i32 :: proc(lhs, rhs: i32) -> (i32, bool) { foreign { @(link_name="llvm.sadd.with.overflow.i32") op :: proc(i32, i32) -> (i32, bool) --- }; return op(lhs, rhs); } +overflowing_add_u64 :: proc(lhs, rhs: u64) -> (u64, bool) { foreign { @(link_name="llvm.uadd.with.overflow.i64") op :: proc(u64, u64) -> (u64, bool) --- }; return op(lhs, rhs); } +overflowing_add_i64 :: proc(lhs, rhs: i64) -> (i64, bool) { foreign { @(link_name="llvm.sadd.with.overflow.i64") op :: proc(i64, i64) -> (i64, bool) --- }; return op(lhs, rhs); } overflowing_add_uint :: proc(lhs, rhs: uint) -> (uint, bool) { when size_of(uint) == size_of(u32) { x, ok := overflowing_add_u32(u32(lhs), u32(rhs)); @@ -157,14 +157,14 @@ overflowing_add :: proc[ overflowing_add_uint, overflowing_add_int, ]; -overflowing_sub_u8 :: proc(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i8") op :: proc(u8, u8) -> (u8, bool) ---; return op(lhs, rhs); } -overflowing_sub_i8 :: proc(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i8") op :: proc(i8, i8) -> (i8, bool) ---; return op(lhs, rhs); } -overflowing_sub_u16 :: proc(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i16") op :: proc(u16, u16) -> (u16, bool) ---; return op(lhs, rhs); } -overflowing_sub_i16 :: proc(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i16") op :: proc(i16, i16) -> (i16, bool) ---; return op(lhs, rhs); } -overflowing_sub_u32 :: proc(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i32") op :: proc(u32, u32) -> (u32, bool) ---; return op(lhs, rhs); } -overflowing_sub_i32 :: proc(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i32") op :: proc(i32, i32) -> (i32, bool) ---; return op(lhs, rhs); } -overflowing_sub_u64 :: proc(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core @(link_name="llvm.usub.with.overflow.i64") op :: proc(u64, u64) -> (u64, bool) ---; return op(lhs, rhs); } -overflowing_sub_i64 :: proc(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core @(link_name="llvm.ssub.with.overflow.i64") op :: proc(i64, i64) -> (i64, bool) ---; return op(lhs, rhs); } +overflowing_sub_u8 :: proc(lhs, rhs: u8) -> (u8, bool) { foreign { @(link_name="llvm.usub.with.overflow.i8") op :: proc(u8, u8) -> (u8, bool) --- }; return op(lhs, rhs); } +overflowing_sub_i8 :: proc(lhs, rhs: i8) -> (i8, bool) { foreign { @(link_name="llvm.ssub.with.overflow.i8") op :: proc(i8, i8) -> (i8, bool) --- }; return op(lhs, rhs); } +overflowing_sub_u16 :: proc(lhs, rhs: u16) -> (u16, bool) { foreign { @(link_name="llvm.usub.with.overflow.i16") op :: proc(u16, u16) -> (u16, bool) --- }; return op(lhs, rhs); } +overflowing_sub_i16 :: proc(lhs, rhs: i16) -> (i16, bool) { foreign { @(link_name="llvm.ssub.with.overflow.i16") op :: proc(i16, i16) -> (i16, bool) --- }; return op(lhs, rhs); } +overflowing_sub_u32 :: proc(lhs, rhs: u32) -> (u32, bool) { foreign { @(link_name="llvm.usub.with.overflow.i32") op :: proc(u32, u32) -> (u32, bool) --- }; return op(lhs, rhs); } +overflowing_sub_i32 :: proc(lhs, rhs: i32) -> (i32, bool) { foreign { @(link_name="llvm.ssub.with.overflow.i32") op :: proc(i32, i32) -> (i32, bool) --- }; return op(lhs, rhs); } +overflowing_sub_u64 :: proc(lhs, rhs: u64) -> (u64, bool) { foreign { @(link_name="llvm.usub.with.overflow.i64") op :: proc(u64, u64) -> (u64, bool) --- }; return op(lhs, rhs); } +overflowing_sub_i64 :: proc(lhs, rhs: i64) -> (i64, bool) { foreign { @(link_name="llvm.ssub.with.overflow.i64") op :: proc(i64, i64) -> (i64, bool) --- }; return op(lhs, rhs); } overflowing_sub_uint :: proc(lhs, rhs: uint) -> (uint, bool) { when size_of(uint) == size_of(u32) { x, ok := overflowing_sub_u32(u32(lhs), u32(rhs)); @@ -193,14 +193,14 @@ overflowing_sub :: proc[ ]; -overflowing_mul_u8 :: proc(lhs, rhs: u8) -> (u8, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i8") op :: proc(u8, u8) -> (u8, bool) ---; return op(lhs, rhs); } -overflowing_mul_i8 :: proc(lhs, rhs: i8) -> (i8, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i8") op :: proc(i8, i8) -> (i8, bool) ---; return op(lhs, rhs); } -overflowing_mul_u16 :: proc(lhs, rhs: u16) -> (u16, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i16") op :: proc(u16, u16) -> (u16, bool) ---; return op(lhs, rhs); } -overflowing_mul_i16 :: proc(lhs, rhs: i16) -> (i16, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i16") op :: proc(i16, i16) -> (i16, bool) ---; return op(lhs, rhs); } -overflowing_mul_u32 :: proc(lhs, rhs: u32) -> (u32, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i32") op :: proc(u32, u32) -> (u32, bool) ---; return op(lhs, rhs); } -overflowing_mul_i32 :: proc(lhs, rhs: i32) -> (i32, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i32") op :: proc(i32, i32) -> (i32, bool) ---; return op(lhs, rhs); } -overflowing_mul_u64 :: proc(lhs, rhs: u64) -> (u64, bool) { foreign __llvm_core @(link_name="llvm.umul.with.overflow.i64") op :: proc(u64, u64) -> (u64, bool) ---; return op(lhs, rhs); } -overflowing_mul_i64 :: proc(lhs, rhs: i64) -> (i64, bool) { foreign __llvm_core @(link_name="llvm.smul.with.overflow.i64") op :: proc(i64, i64) -> (i64, bool) ---; return op(lhs, rhs); } +overflowing_mul_u8 :: proc(lhs, rhs: u8) -> (u8, bool) { foreign { @(link_name="llvm.umul.with.overflow.i8") op :: proc(u8, u8) -> (u8, bool) --- }; return op(lhs, rhs); } +overflowing_mul_i8 :: proc(lhs, rhs: i8) -> (i8, bool) { foreign { @(link_name="llvm.smul.with.overflow.i8") op :: proc(i8, i8) -> (i8, bool) --- }; return op(lhs, rhs); } +overflowing_mul_u16 :: proc(lhs, rhs: u16) -> (u16, bool) { foreign { @(link_name="llvm.umul.with.overflow.i16") op :: proc(u16, u16) -> (u16, bool) --- }; return op(lhs, rhs); } +overflowing_mul_i16 :: proc(lhs, rhs: i16) -> (i16, bool) { foreign { @(link_name="llvm.smul.with.overflow.i16") op :: proc(i16, i16) -> (i16, bool) --- }; return op(lhs, rhs); } +overflowing_mul_u32 :: proc(lhs, rhs: u32) -> (u32, bool) { foreign { @(link_name="llvm.umul.with.overflow.i32") op :: proc(u32, u32) -> (u32, bool) --- }; return op(lhs, rhs); } +overflowing_mul_i32 :: proc(lhs, rhs: i32) -> (i32, bool) { foreign { @(link_name="llvm.smul.with.overflow.i32") op :: proc(i32, i32) -> (i32, bool) --- }; return op(lhs, rhs); } +overflowing_mul_u64 :: proc(lhs, rhs: u64) -> (u64, bool) { foreign { @(link_name="llvm.umul.with.overflow.i64") op :: proc(u64, u64) -> (u64, bool) --- }; return op(lhs, rhs); } +overflowing_mul_i64 :: proc(lhs, rhs: i64) -> (i64, bool) { foreign { @(link_name="llvm.smul.with.overflow.i64") op :: proc(i64, i64) -> (i64, bool) --- }; return op(lhs, rhs); } overflowing_mul_uint :: proc(lhs, rhs: uint) -> (uint, bool) { when size_of(uint) == size_of(u32) { x, ok := overflowing_mul_u32(u32(lhs), u32(rhs)); diff --git a/core/math/math.odin b/core/math/math.odin index e895ceb92..9a6799a7e 100644 --- a/core/math/math.odin +++ b/core/math/math.odin @@ -31,7 +31,7 @@ QUAT_IDENTITY := Quat{x = 0, y = 0, z = 0, w = 1}; @(default_calling_convention="c") -foreign __llvm_core { +foreign _ { @(link_name="llvm.sqrt.f32") sqrt_f32 :: proc(x: f32) -> f32 ---; @(link_name="llvm.sqrt.f64") diff --git a/core/mem/mem.odin b/core/mem/mem.odin index 15b3ff068..18cd970d4 100644 --- a/core/mem/mem.odin +++ b/core/mem/mem.odin @@ -2,7 +2,7 @@ package mem import "core:raw" -foreign __llvm_core { +foreign _ { @(link_name = "llvm.bswap.i16") swap16 :: proc(b: u16) -> u16 ---; @(link_name = "llvm.bswap.i32") swap32 :: proc(b: u32) -> u32 ---; @(link_name = "llvm.bswap.i64") swap64 :: proc(b: u64) -> u64 ---; @@ -12,7 +12,7 @@ swap :: proc[swap16, swap32, swap64]; set :: proc "contextless" (data: rawptr, value: i32, len: int) -> rawptr { if data == nil do return nil; - foreign __llvm_core { + foreign _ { when size_of(rawptr) == 8 { @(link_name="llvm.memset.p0i8.i64") llvm_memset :: proc(dst: rawptr, val: byte, len: int, align: i32, is_volatile: bool) ---; @@ -30,7 +30,7 @@ zero :: proc "contextless" (data: rawptr, len: int) -> rawptr { copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr { if src == nil do return dst; // NOTE(bill): This _must_ be implemented like C's memmove - foreign __llvm_core { + foreign _ { when size_of(rawptr) == 8 { @(link_name="llvm.memmove.p0i8.p0i8.i64") llvm_memmove :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) ---; @@ -45,7 +45,7 @@ copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr { copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr { if src == nil do return dst; // NOTE(bill): This _must_ be implemented like C's memcpy - foreign __llvm_core { + foreign _ { when size_of(rawptr) == 8 { @(link_name="llvm.memcpy.p0i8.p0i8.i64") llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) ---; diff --git a/core/runtime/core.odin b/core/runtime/core.odin index df3ff83c7..57835acb6 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -270,7 +270,7 @@ typeid_base_without_enum :: proc "contextless" (id: typeid) -> typeid { @(default_calling_convention = "c") -foreign __llvm_core { +foreign { @(link_name="llvm.assume") assume :: proc(cond: bool) ---; diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index 8104a72ef..87d19ab87 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -321,56 +321,56 @@ __slice_expr_error_loc :: inline proc "contextless" (using loc := #caller_locati @(default_calling_convention = "c") -foreign __llvm_core { - @(link_name="llvm.sqrt.f32") __sqrt_f32 :: proc(x: f32) -> f32 ---; - @(link_name="llvm.sqrt.f64") __sqrt_f64 :: proc(x: f64) -> f64 ---; +foreign { + @(link_name="llvm.sqrt.f32") __sqrt_f32 :: proc(x: f32) -> f32 --- + @(link_name="llvm.sqrt.f64") __sqrt_f64 :: proc(x: f64) -> f64 --- - @(link_name="llvm.sin.f32") __sin_f32 :: proc(θ: f32) -> f32 ---; - @(link_name="llvm.sin.f64") __sin_f64 :: proc(θ: f64) -> f64 ---; + @(link_name="llvm.sin.f32") __sin_f32 :: proc(θ: f32) -> f32 --- + @(link_name="llvm.sin.f64") __sin_f64 :: proc(θ: f64) -> f64 --- - @(link_name="llvm.cos.f32") __cos_f32 :: proc(θ: f32) -> f32 ---; - @(link_name="llvm.cos.f64") __cos_f64 :: proc(θ: f64) -> f64 ---; + @(link_name="llvm.cos.f32") __cos_f32 :: proc(θ: f32) -> f32 --- + @(link_name="llvm.cos.f64") __cos_f64 :: proc(θ: f64) -> f64 --- - @(link_name="llvm.pow.f32") __pow_f32 :: proc(x, power: f32) -> f32 ---; - @(link_name="llvm.pow.f64") __pow_f64 :: proc(x, power: f64) -> f64 ---; + @(link_name="llvm.pow.f32") __pow_f32 :: proc(x, power: f32) -> f32 --- + @(link_name="llvm.pow.f64") __pow_f64 :: proc(x, power: f64) -> f64 --- - @(link_name="llvm.fmuladd.f32") fmuladd32 :: proc(a, b, c: f32) -> f32 ---; - @(link_name="llvm.fmuladd.f64") fmuladd64 :: proc(a, b, c: f64) -> f64 ---; + @(link_name="llvm.fmuladd.f32") fmuladd32 :: proc(a, b, c: f32) -> f32 --- + @(link_name="llvm.fmuladd.f64") fmuladd64 :: proc(a, b, c: f64) -> f64 --- } __abs_f32 :: inline proc "contextless" (x: f32) -> f32 { - foreign __llvm_core { - @(link_name="llvm.fabs.f32") _abs :: proc "c" (x: f32) -> f32 ---; + foreign { + @(link_name="llvm.fabs.f32") _abs :: proc "c" (x: f32) -> f32 --- } return _abs(x); } __abs_f64 :: inline proc "contextless" (x: f64) -> f64 { - foreign __llvm_core { - @(link_name="llvm.fabs.f64") _abs :: proc "c" (x: f64) -> f64 ---; + foreign { + @(link_name="llvm.fabs.f64") _abs :: proc "c" (x: f64) -> f64 --- } return _abs(x); } __min_f32 :: proc(a, b: f32) -> f32 { - foreign __llvm_core { - @(link_name="llvm.minnum.f32") _min :: proc "c" (a, b: f32) -> f32 ---; + foreign { + @(link_name="llvm.minnum.f32") _min :: proc "c" (a, b: f32) -> f32 --- } return _min(a, b); } __min_f64 :: proc(a, b: f64) -> f64 { - foreign __llvm_core { - @(link_name="llvm.minnum.f64") _min :: proc "c" (a, b: f64) -> f64 ---; + foreign { + @(link_name="llvm.minnum.f64") _min :: proc "c" (a, b: f64) -> f64 --- } return _min(a, b); } __max_f32 :: proc(a, b: f32) -> f32 { - foreign __llvm_core { - @(link_name="llvm.maxnum.f32") _max :: proc "c" (a, b: f32) -> f32 ---; + foreign { + @(link_name="llvm.maxnum.f32") _max :: proc "c" (a, b: f32) -> f32 --- } return _max(a, b); } __max_f64 :: proc(a, b: f64) -> f64 { - foreign __llvm_core { - @(link_name="llvm.maxnum.f64") _max :: proc "c" (a, b: f64) -> f64 ---; + foreign { + @(link_name="llvm.maxnum.f64") _max :: proc "c" (a, b: f64) -> f64 --- } return _max(a, b); } diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index 14265696c..54a895d0a 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -739,7 +739,7 @@ deprecated_attribute :: proc() { } main :: proc() { - when true { + when false { general_stuff(); union_type(); parametric_polymorphism(); @@ -753,5 +753,8 @@ main :: proc() { cstring_example(); deprecated_attribute(); } + + x := f32(-123); + fmt.println(abs(x)); } diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 4e4355968..3a8f787c6 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -459,7 +459,7 @@ void init_entity_foreign_library(CheckerContext *ctx, Entity *e) { Entity *found = scope_lookup_entity(ctx->scope, name); if (found == nullptr) { if (is_blank_ident(name)) { - error(ident, "'_' cannot be used as a value type"); + // NOTE(bill): link against nothing } else { error(ident, "Undeclared name: %.*s", LIT(name)); } diff --git a/src/checker.cpp b/src/checker.cpp index 2471bcf54..a2a677340 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -575,14 +575,11 @@ void init_universal_scope(void) { add_global_constant(str_lit("false"), t_untyped_bool, exact_value_bool(false)); add_global_entity(alloc_entity_nil(str_lit("nil"), t_untyped_nil)); - add_global_entity(alloc_entity_library_name(universal_scope, - make_token_ident(str_lit("__llvm_core")), t_invalid, - str_lit(""), str_lit("__llvm_core"))); + // add_global_entity(alloc_entity_library_name(universal_scope, + // make_token_ident(str_lit("__llvm_core")), t_invalid, + // str_lit(""), str_lit("__llvm_core"))); // TODO(bill): Set through flags in the compiler - // add_global_string_constant(str_lit("ODIN_OS"), bc->ODIN_OS); - // add_global_string_constant(str_lit("ODIN_ARCH"), bc->ODIN_ARCH); - // add_global_string_constant(str_lit("ODIN_ENDIAN"), bc->ODIN_ENDIAN); add_global_string_constant(str_lit("ODIN_VENDOR"), bc->ODIN_VENDOR); add_global_string_constant(str_lit("ODIN_VERSION"), bc->ODIN_VERSION); add_global_string_constant(str_lit("ODIN_ROOT"), bc->ODIN_ROOT); diff --git a/src/ir.cpp b/src/ir.cpp index 65fa38932..4e670fbd6 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -1327,7 +1327,9 @@ irValue *ir_add_global_string_array(irModule *m, String string) { } void ir_add_foreign_library_path(irModule *m, Entity *e) { - GB_ASSERT(e != nullptr); + if (e == nullptr) { + return; + } GB_ASSERT(e->kind == Entity_LibraryName); GB_ASSERT(e->LibraryName.used); diff --git a/src/parser.cpp b/src/parser.cpp index 98e3bc3c9..2aeb98706 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1318,7 +1318,7 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) { case AstNode_BitFieldType: return true; case AstNode_ProcLit: - return s->ProcLit.body != nullptr; + return true; case AstNode_PackageDecl: case AstNode_ImportDecl: @@ -2410,6 +2410,8 @@ AstNode *parse_foreign_block(AstFile *f, Token token) { AstNode *foreign_library = nullptr; if (f->curr_token.kind == Token_export) { foreign_library = ast_implicit(f, expect_token(f, Token_export)); + } else if (f->curr_token.kind == Token_OpenBrace) { + foreign_library = ast_ident(f, blank_token); } else { foreign_library = parse_ident(f); } @@ -2421,19 +2423,16 @@ AstNode *parse_foreign_block(AstFile *f, Token token) { defer (f->in_foreign_block = prev_in_foreign_block); f->in_foreign_block = true; - if (f->curr_token.kind != Token_OpenBrace) { + + open = expect_token(f, Token_OpenBrace); + + while (f->curr_token.kind != Token_CloseBrace && + f->curr_token.kind != Token_EOF) { parse_foreign_block_decl(f, &decls); - } else { - open = expect_token(f, Token_OpenBrace); - - while (f->curr_token.kind != Token_CloseBrace && - f->curr_token.kind != Token_EOF) { - parse_foreign_block_decl(f, &decls); - } - - close = expect_token(f, Token_CloseBrace); } + close = expect_token(f, Token_CloseBrace); + AstNode *decl = ast_foreign_block_decl(f, token, foreign_library, open, close, decls, docs); expect_semicolon(f, decl); return decl; @@ -3512,6 +3511,7 @@ AstNode *parse_foreign_decl(AstFile *f) { switch (f->curr_token.kind) { case Token_export: case Token_Ident: + case Token_OpenBrace: return parse_foreign_block(f, token); case Token_import: {