- Added path::home_directory, path::documents_directory, path::videos_directory, path::pictures_directory, path::desktop_directory, path::screenshots_directory,

`path::public_share_directory`, `path::templates_directory`, `path::saved_games_directory`, `path::music_directory`, `path::downloads_directory`.
  Fix codegen bug in expressions like `foo(x()) ?? io::EOF?` causing irregular crashes.
This commit is contained in:
Christoffer Lerno
2025-09-04 21:34:34 +02:00
committed by Christoffer Lerno
parent cbd415881b
commit 69b3263a00
17 changed files with 342 additions and 42 deletions

View File

@@ -88,16 +88,16 @@ jobs:
..\build\${{ matrix.build_type }}\c3c.exe compile --lib raylib55 --print-linking examples\raylib\raylib_snake.c3
..\build\${{ matrix.build_type }}\c3c.exe compile --lib raylib55 --print-linking examples\raylib\raylib_tetris.c3
- name: run compiler tests
run: |
cd test
..\build\${{ matrix.build_type }}\c3c.exe compile-run -O1 src/test_suite_runner.c3 -- ..\build\${{ matrix.build_type }}\c3c.exe test_suite/
- name: Compile run unit tests
run: |
cd test
..\build\${{ matrix.build_type }}\c3c.exe compile-test unit -O1 -D SLOW_TESTS
- name: run compiler tests
run: |
cd test
..\build\${{ matrix.build_type }}\c3c.exe compile-run -O1 src/test_suite_runner.c3 -- ..\build\${{ matrix.build_type }}\c3c.exe test_suite/ --no-terminal
- name: Test python script
run: |
py msvc_build_libraries.py --accept-license

View File

@@ -35,6 +35,7 @@ faultdef
NO_PERMISSION,
OUT_OF_SPACE,
OVERFLOW,
PATH_COULD_NOT_BE_FOUND,
READ_ONLY,
SYMLINK_FAILED,
TOO_MANY_DESCRIPTORS,

View File

@@ -1,5 +1,112 @@
module std::io::os;
enum NativeSystemDir
{
DESKTOP,
DOCUMENTS,
VIDEOS,
MUSIC,
DOWNLOADS,
PICTURES,
TEMPLATES,
PUBLIC_SHARE,
SAVED_GAMES,
SCREENSHOTS
}
module std::io::os @if(env::LIBC);
import std::io::path, std::os;
import std::io, std::os;
fn String? win32_get_known_folder_temp(Win32_REFKNOWNFOLDERID rfid) @private @if(env::WIN32)
{
Win32_PWSTR path;
Win32_HRESULT res = win32::shGetKnownFolderPath(rfid, 0x00008000 /* KF_FLAG_CREATE */, null, &path);
if (res) return io::PATH_COULD_NOT_BE_FOUND?;
return string::from_wstring(tmem, (WString)path);
}
fn Path? native_home_directory(Allocator allocator) => @pool()
{
$switch env::OS_TYPE:
$case IOS:
$case MACOS:
$case TVOS:
$case WATCHOS:
$case FREEBSD:
$case KFREEBSD:
$case LINUX:
$case NETBSD:
$case OPENBSD:
$case HAIKU:
return path::new(allocator, env::tget_var("HOME")) ?? io::PATH_COULD_NOT_BE_FOUND?;
$case WIN32:
return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_PROFILE));
$default:
return io::PATH_COULD_NOT_BE_FOUND?;
$endswitch
}
fn Path? native_user_directory(Allocator allocator, NativeSystemDir dir) => @pool()
{
$switch env::OS_TYPE:
$case FREEBSD:
$case KFREEBSD:
$case LINUX:
$case NETBSD:
$case OPENBSD:
$case HAIKU:
switch (dir)
{
case DESKTOP: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "DESKTOP"));
case DOWNLOADS: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "DOWNLOAD"));
case DOCUMENTS: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "DOCUMENTS"));
case MUSIC: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "MUSIC"));
case VIDEOS: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "VIDEOS"));
case PICTURES: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "PICTURES"));
case PUBLIC_SHARE: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "PUBLICSHARE"));
case TEMPLATES: return path::new(allocator, posix::xdg_user_dir_lookup(tmem, "TEMPLATES"));
case SAVED_GAMES:
case SCREENSHOTS: nextcase;
default: return io::PATH_COULD_NOT_BE_FOUND?;
}
$case IOS:
$case MACOS:
$case WATCHOS:
$case TVOS:
switch (dir)
{
case DESKTOP: return path::new(allocator, darwin::find_first_directory_temp(DESKTOP, USER));
case DOWNLOADS: return path::new(allocator, darwin::find_first_directory_temp(DOWNLOADS, USER));
case DOCUMENTS: return path::new(allocator, darwin::find_first_directory_temp(DOCUMENT, USER));
case MUSIC: return path::new(allocator, darwin::find_first_directory_temp(MUSIC, USER));
case VIDEOS: return path::new(allocator, darwin::find_first_directory_temp(MOVIES, USER));
case PICTURES: return path::new(allocator, darwin::find_first_directory_temp(PICTURES, USER));
case PUBLIC_SHARE: return path::new(allocator, darwin::find_first_directory_temp(SHARED_PUBLIC, USER));
case SAVED_GAMES:
case SCREENSHOTS:
case TEMPLATES: nextcase;
default: return io::PATH_COULD_NOT_BE_FOUND?;
}
$case WIN32:
switch (dir)
{
case DOWNLOADS: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_DOWNLOADS));
case DOCUMENTS: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_DOCUMENTS));
case DESKTOP: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_DESKTOP));
case MUSIC: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_MUSIC));
case VIDEOS: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_VIDEOS));
case PICTURES: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_PICTURES));
case SAVED_GAMES: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_SAVED_GAMES));
case SCREENSHOTS: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_SCREENSHOTS));
case TEMPLATES: return path::new(allocator, win32_get_known_folder_temp(&win32::FOLDERID_TEMPLATES));
case PUBLIC_SHARE: nextcase;
default: return io::PATH_COULD_NOT_BE_FOUND?;
}
$default:
return io::PATH_COULD_NOT_BE_FOUND?;
$endswitch
}
fn Path? native_temp_directory(Allocator allocator) @if(!env::WIN32)
{
@@ -23,7 +130,6 @@ fn Path? native_temp_directory(Allocator allocator) @if(env::WIN32) => @pool()
module std::io::os @if(env::NO_LIBC);
import std::io::path;
macro Path? native_temp_directory(Allocator allocator)
{
return io::UNSUPPORTED_OPERATION?;
}
macro Path? native_home_directory(Allocator allocator) => io::PATH_COULD_NOT_BE_FOUND?;
macro Path? native_temp_directory(Allocator allocator) => io::PATH_COULD_NOT_BE_FOUND?;
fn Path? native_user_directory(Allocator allocator, NativeSystemDir dir) => io::PATH_COULD_NOT_BE_FOUND?;

View File

@@ -57,6 +57,18 @@ macro void? chdir(path)
fn Path? temp_directory(Allocator allocator) => os::native_temp_directory(allocator);
fn Path? home_directory(Allocator allocator) => os::native_home_directory(allocator);
fn Path? desktop_directory(Allocator allocator) => os::native_user_directory(allocator, DESKTOP);
fn Path? videos_directory(Allocator allocator) => os::native_user_directory(allocator, VIDEOS);
fn Path? music_directory(Allocator allocator) => os::native_user_directory(allocator, MUSIC);
fn Path? documents_directory(Allocator allocator) => os::native_user_directory(allocator, DOCUMENTS);
fn Path? screenshots_directory(Allocator allocator) => os::native_user_directory(allocator, SCREENSHOTS);
fn Path? saved_games_directory(Allocator allocator) => os::native_user_directory(allocator, SAVED_GAMES);
fn Path? downloads_directory(Allocator allocator) => os::native_user_directory(allocator, DOWNLOADS);
fn Path? pictures_directory(Allocator allocator) => os::native_user_directory(allocator, PICTURES);
fn Path? templates_directory(Allocator allocator) => os::native_user_directory(allocator, TEMPLATES);
fn Path? public_share_directory(Allocator allocator) => os::native_user_directory(allocator, PUBLIC_SHARE);
fn void? delete(Path path) => os::native_remove(path.str_view()) @inline;
macro bool @is_pathlike(#path) @const => $typeof(#path) == String ||| $typeof(#path) == Path;

View File

@@ -1,11 +1,18 @@
module std::os::macos::cf @if(env::DARWIN) @link(env::DARWIN, "CoreFoundation.framework");
typedef CFArrayRef = void*;
typedef CFArray = inline CFType;
alias CFArrayRef = CFArray*;
typedef CFArrayCallBacksRef = void*;
typedef CFMutableArrayRef = void*;
typedef CFMutableArray = inline CFArray;
typedef CFMutableArrayRef = CFMutableArray*;
extern fn CFIndex CFArray.getCount(&self) @extern("CFArrayGetCount");
extern fn void* CFArray.getValueAtIndex(&self, CFIndex i) @extern("CFArrayGetValueAtIndex");
extern fn CFArrayRef macos_CFArrayCreate(CFAllocatorRef allocator, void** values, CFIndex num_values, CFArrayCallBacksRef callBacks) @extern("CFArrayCreate") @builtin;
extern fn CFArrayRef macos_CFArrayCopy(CFAllocatorRef allocator, CFArrayRef array) @extern("CFArrayCopy") @builtin;
extern fn CFIndex macos_CFArrayGetCount(CFArrayRef array) @extern("CFArrayGetCount") @builtin;
extern fn void macos_CFArrayAppendArray(CFMutableArrayRef theArray, CFArrayRef otherArray, CFRange otherRange) @extern("CFArrayAppendArray") @builtin;
extern fn void CFMutableArray.appendArray(&self, CFArrayRef otherArray, CFRange otherRange) @extern("CFArrayAppendArray");
extern fn void CFMutableArray.appendValue(&self, void *value) @extern("CFArrayAppendValue");
extern fn CFMutableArrayRef macos_CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, CFArrayCallBacksRef callBacks) @extern("CFArrayCreateMutable") @builtin;
extern fn void macos_CFArrayAppendValue(CFMutableArrayRef theArray, void *value) @extern("CFArrayAppendValue") @builtin;

View File

@@ -1,13 +1,42 @@
module std::os::macos::cf @if(env::DARWIN) @link(env::DARWIN, "CoreFoundation.framework");
typedef CFTypeRef = void*;
typedef CFType = void;
typedef CFTypeRef = CFType*;
alias CFIndex = isz;
typedef CFString = inline CFType;
alias CFStringRef = CFString*;
struct CFRange
{
CFIndex location;
CFIndex length;
}
extern fn CFTypeRef macos_CFRetain(CFTypeRef cf) @extern("CFRetain") @builtin;
extern fn void macos_CFRelease(CFTypeRef cf) @extern("CFRelease") @builtin;
extern fn ZString CFString.getCStringPtr(&self, CFStringEncoding encoding) @extern("CFStringGetCStringPtr");
extern fn ZString CFString.getCString(&self, char* buffer, usz len, CFStringEncoding encoding) @extern("CFStringGetCString");
extern fn CFTypeRef CFType.retain(&self) @extern("CFRetain");
extern fn void CFType.release(&self) @extern("CFRelease");
extern fn CFIndex CFType.getRetainCount(&self) @extern("CFGetRetainCount");
enum CFStringEncoding : const uint
{
INVALID_ID = 0xffffffffU,
MAC_ROMAN = 0,
WINDOWS_LATIN_1 = 0x0500,
ISO_LATIM_1 = 0x0201,
NEXT_STEP_LATIN = 0x0B01,
ASCII = 0x0600,
UNICODE = 0x0100,
UTF8 = 0x08000100,
NON_LOSSY_ASCII = 0x0BFF,
UTF16 = 0x0100,
UTF16BE = 0x10000100,
UTF16LE = 0x14000100,
UTF32 = 0x0c000100,
UTF32BE = 0x18000100,
UTF32LE = 0x1c000100
}

View File

@@ -1,2 +1,60 @@
module std::os::darwin @if(env::DARWIN);
module std::os::darwin @if(env::DARWIN) @link("Foundation.framework");
import std::os::macos::cf, std::os::macos::objc, std::io;
enum NSSearchPathDomainMask : const NSUInteger
{
USER = 1,
LOCAL = 2,
NETWORK = 4,
SYSTEM = 8,
ALL = 0x0ffff
}
enum NSSearchPathDirectory : const NSUInteger
{
APPLICATION = 1,
DEMO_APPLICATION,
DEVELOPER_APPLICATION,
ADMIN_APPLICATION,
LIBRARY,
DEVELOPER,
USER,
DOCUMENTATION,
DOCUMENT,
CORE_SERVICE,
AUTOSAVED_INFORMATION,
DESKTOP = 12,
CACHES = 13,
APPLICATION_SUPPORT = 14,
DOWNLOADS = 15,
INPUT_METHODS = 16,
MOVIES = 17,
MUSIC = 18,
PICTURES = 19,
PRINTER_DESCRIPTION = 20,
SHARED_PUBLIC = 21,
PREFERENCE_PANES = 22,
APPLICATION_SCRIPTS = 23,
ITEM_REPLACEMENT = 99,
ALL_APPLICATIONS = 100,
ALL_LIBRARIES = 101,
TRASH = 102,
}
// real signature in Foundation
extern fn CFArrayRef nsSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, bool expandTilde) @extern("NSSearchPathForDirectoriesInDomains");
fn String? find_first_directory_temp(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask)
{
objc::@autoreleasepool()
{
CFArrayRef arr = nsSearchPathForDirectoriesInDomains(directory, domainMask, true);
if (!arr.getCount()) return io::PATH_COULD_NOT_BE_FOUND?;
CFStringRef str = (CFStringRef)arr.getValueAtIndex(0);
char* buffer = tmalloc(2048);
if (!str.getCString(buffer, 2048, UTF8)) return io::PATH_COULD_NOT_BE_FOUND?;
return ((ZString)buffer).str_view();
};
}

View File

@@ -20,6 +20,9 @@ macro bool ObjcClass.equals(ObjcClass a, ObjcClass b) => a == b;
fn ObjcId alloc(ObjcClass cls) => objc::msg_send(cls, SendVoid, "alloc");
fn void release(ObjcId id) => objc::msg_send(id, SendVoid, "release");
alias NSUInteger = $typefrom(env::ARCH_64_BIT ??? ulong : uint);
alias NSInteger = $typefrom(env::ARCH_64_BIT ??? long : int);
macro ObjcClass? class_by_name(ZString c)
{
ObjcClass cls = objc::lookUpClass(c);
@@ -43,6 +46,15 @@ macro msg_send(id, $FunctionType, ZString $selector, ...)
return (($FunctionType)&msgSend)((ObjcId)id, sel_getUid($selector), $vasplat);
}
macro void @autoreleasepool(;@body())
{
void* ctx = objc_autoreleasePoolPush();
defer objc_autoreleasePoolPop(ctx);
@body();
}
extern fn void* objc_autoreleasePoolPush();
extern fn void objc_autoreleasePoolPop(void* context);
extern fn ObjcClass getClass(ZString name) @extern("objc_getClass");
extern fn int getClassList(ObjcClass* buffer, int buffer_count) @extern("objc_getClassList");
extern fn ObjcClass lookUpClass(ZString name) @extern("objc_lookUpClass") @builtin;

View File

@@ -0,0 +1,16 @@
module std::os::win32 @if(env::WIN32) @link("shell32");
typedef Win32_REFKNOWNFOLDERID = Win32_KNOWNFOLDERID*;
typedef Win32_KNOWNFOLDERID = Win32_GUID;
extern fn Win32_HRESULT shGetKnownFolderPath(Win32_REFKNOWNFOLDERID rfid, Win32_DWORD dwFlags, Win32_HANDLE hToken, Win32_PWSTR* ppszPath) @extern("SHGetKnownFolderPath");
const Win32_KNOWNFOLDERID FOLDERID_PROFILE = { 0x5E6C858F, 0x0E22, 0x4760, x"9AFEEA3317B67173" };
const Win32_KNOWNFOLDERID FOLDERID_DESKTOP = { 0xB4BFCC3A, 0xDB2C, 0x424C, x"B0297FE99A87C641" };
const Win32_KNOWNFOLDERID FOLDERID_DOCUMENTS = { 0xFDD39AD0, 0x238F, 0x46AF, x"ADB46C85480369C7" };
const Win32_KNOWNFOLDERID FOLDERID_DOWNLOADS = { 0x374de290, 0x123f, 0x4565, x"916439c4925e467b" };
const Win32_KNOWNFOLDERID FOLDERID_MUSIC = { 0x4BD8D571, 0x6D19, 0x48D3, x"BE97422220080E43" };
const Win32_KNOWNFOLDERID FOLDERID_PICTURES = { 0x33E28130, 0x4E1E, 0x4676, x"835A98395C3BC3BB" };
const Win32_KNOWNFOLDERID FOLDERID_SAVED_GAMES = { 0x4c5c32ff, 0xbb9d, 0x43b0, x"b5b42d72e54eaaa4" };
const Win32_KNOWNFOLDERID FOLDERID_SCREENSHOTS = { 0xb7bede81, 0xdf94, 0x4682, x"a7d857a52620b86f" };
const Win32_KNOWNFOLDERID FOLDERID_TEMPLATES = { 0xA63293E8, 0x664E, 0x48DB, x"A079DF759E0509F7" };
const Win32_KNOWNFOLDERID FOLDERID_VIDEOS = { 0x18989B1D, 0x99B5, 0x455B, x"841CAB7C74E4DDFC" };

53
lib/std/os/xdg.c3 Normal file
View File

@@ -0,0 +1,53 @@
module std::os::posix @if(env::POSIX);
import std::io, std::os::env;
fn String? xdg_user_dir_lookup(Allocator allocator, String type) => @pool()
{
String home = env::tget_var("HOME")!;
String config_file @noinit;
if (try String config_home = env::tget_var("XDG_CONFIG_HOME") && config_home.len)
{
config_file = config_home.tconcat("/user-dirs.dirs");
}
else
{
config_file = home.tconcat("/.config/user-dirs.dirs");
}
File f = file::open(config_file, "r")!;
defer (void)f.close();
while (try line = io::treadline(&f))
{
line = line.trim();
if (!line.starts_with("XDG_")) continue;
line = line[4..];
if (!line.starts_with(type)) continue;
line = line[type.len ..];
if (!line.starts_with("_DIR")) continue;
line = line[4..];
line = line.trim();
if (!line.starts_with("=")) continue;
line = line[1..].trim();
if (!line.starts_with("\"")) continue;
line = line[1..];
bool relative = false;
if (line.starts_with("$HOME/"))
{
relative = true;
line = line[6..];
}
else
{
if (!line.starts_with("/")) continue;
if (line.len < 2) continue;
line = line[1..];
}
if (line.len < 1 || line[^1] != '"') continue;
line = line[:^1];
if (relative)
{
return string::format(allocator, "%s/%s", home, line);
}
return line.copy(allocator);
}
return io::PATH_COULD_NOT_BE_FOUND?;
}

View File

@@ -11,9 +11,12 @@
- Returning pointer to index of slice stored in a struct from method taking self incorrectly detected as returning pointer to local variable #2455.
- Inlining location when accessing #foo symbols.
- Improve inlined-at when checking generic code.
- Fix codegen bug in expressions like `foo(x()) ?? io::EOF?` causing irregular crashes.
### Stdlib changes
- Added generic `InterfaceList` to store a list of values that implement a specific interface
- Added `path::home_directory`, `path::documents_directory`, `path::videos_directory`, `path::pictures_directory`, `path::desktop_directory`, `path::screenshots_directory`,
`path::public_share_directory`, `path::templates_directory`, `path::saved_games_directory`, `path::music_directory`, `path::downloads_directory`.
## 0.7.5 Change list

View File

@@ -1,10 +1,5 @@
module hello_world;
import std;
import bar;
import clib;
import clib2;
import std::core::env;
import std, bar, clib, clib2;
fn int test_doubler(int x) @if(env::WIN32) => x * x;
extern fn int test_doubler(int) @if(!env::WIN32);
@@ -18,6 +13,10 @@ fn int main()
printf("Author emails:");
io::printn(env::AUTHOR_EMAILS);
(void)io::printfn("Home dir: %s", path::home_directory(tmem));
(void)io::printfn("Desktop dir: %s", path::desktop_directory(tmem));
(void)io::printfn("Documents dir: %s", path::documents_directory(tmem));
bar::test();
printf("Hello double: %d\n", test_doubler(11));
if ($feature(ABCD)) io::printn("ABCD");

View File

@@ -404,10 +404,12 @@ bool decl_needs_prefix(Decl *decl)
{
switch (decl->decl_kind)
{
case DECL_VAR:
case DECL_ALIAS:
case DECL_FUNC:
case DECL_MACRO:
if (decl->func_decl.type_parent) return false;
FALLTHROUGH;
case DECL_VAR:
case DECL_ALIAS:
case DECL_FAULT:
return !decl->is_autoimport;
default:

View File

@@ -3858,7 +3858,10 @@ static void llvm_emit_else(GenContext *c, BEValue *be_value, Expr *expr)
// Only jump to phi if we didn't have an immediate jump. That would
// for example happen on "{| defer foo(); return Foo.ERR?; |} ?? 123"
if (success_end_block) llvm_emit_br(c, phi_block);
if (success_end_block)
{
if (!llvm_emit_br(c, phi_block)) success_end_block = NULL;
}
// Emit else
llvm_emit_block(c, else_block);
@@ -3881,27 +3884,28 @@ static void llvm_emit_else(GenContext *c, BEValue *be_value, Expr *expr)
}
}
// If there wasn't a success, then we end here, even if the else was a jump.
if (!success_end_block)
{
*be_value = else_value;
return;
}
LLVMBasicBlockRef else_block_exit = llvm_get_current_block_if_in_use(c);
// While the value may not be an optional, we may get a jump
// from this construction: foo() ?? (bar()?)
// In this case the else block is empty.
if (!else_block_exit)
if (!else_block_exit || !llvm_emit_br(c, phi_block))
{
llvm_emit_block(c, phi_block);
*be_value = real_value;
return;
}
llvm_emit_br(c, phi_block);
llvm_emit_block(c, phi_block);
// Was there never a success, if so the result is the be_value.
if (!success_end_block)
{
*be_value = else_value;
return;
}
assert(success_end_block && else_block_exit);
// Emit an address if the phi is was by address
if (was_address)

View File

@@ -55,11 +55,12 @@ bool llvm_emit_check_block_branch(GenContext *c)
return true;
}
void llvm_emit_br(GenContext *c, LLVMBasicBlockRef next_block)
bool llvm_emit_br(GenContext *c, LLVMBasicBlockRef next_block)
{
if (!llvm_emit_check_block_branch(c)) return;
if (!llvm_emit_check_block_branch(c)) return false;
c->current_block = NULL;
LLVMBuildBr(c->builder, next_block);
return true;
}

View File

@@ -424,7 +424,7 @@ INLINE LLVMValueRef llvm_get_struct_of_type(GenContext *c, Type *type, LLVMValue
// -- Jumps --
void llvm_emit_cond_br(GenContext *context, BEValue *value, LLVMBasicBlockRef then_block, LLVMBasicBlockRef else_block);
void llvm_emit_cond_br_raw(GenContext *context, LLVMValueRef b, LLVMBasicBlockRef then_block, LLVMBasicBlockRef else_block);
void llvm_emit_br(GenContext *c, LLVMBasicBlockRef next_block);
bool llvm_emit_br(GenContext *c, LLVMBasicBlockRef next_block);
void llvm_emit_jump_to_optional_exit(GenContext *c, LLVMValueRef opt_value);
void llvm_emit_return_abi(GenContext *c, BEValue *return_value, BEValue *optional);
void llvm_emit_return_implicit(GenContext *c);

View File

@@ -28,9 +28,6 @@ opt_block_cleanup: ; preds = %entry
br label %else_block
else_block: ; preds = %opt_block_cleanup
br label %phi_block
phi_block: ; preds = %else_block
%1 = call i32 (ptr, ...) @printf(ptr @.str, i32 2)
%2 = call i32 (ptr, ...) @printf(ptr @.str.3)
ret void