mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Updates to file:: and path::, Path is now passed an allocator. path::traverse function. mkdir / rmdir / chdir works directly with strings. Strings get file_basepath, path_dirname. Test suite runner now uses lib7. Bug when printing a parameter declaration error. Fix optional jumps in expression lists, #1942.
This commit is contained in:
committed by
Christoffer Lerno
parent
1dfc24822e
commit
062a67fe75
16
.github/workflows/main.yml
vendored
16
.github/workflows/main.yml
vendored
@@ -95,7 +95,7 @@ jobs:
|
||||
- name: run compiler tests
|
||||
run: |
|
||||
cd test
|
||||
..\build\${{ matrix.build_type }}\c3c.exe compile-run -O1 src/test_suite_runner.c3 --enable-new-generics -- ..\build\${{ matrix.build_type }}\c3c.exe test_suite/
|
||||
..\build\${{ matrix.build_type }}\c3c.exe compile-run -O1 src/test_suite_runner.c3 --stdlib ..\lib7 --enable-new-generics -- ..\build\${{ matrix.build_type }}\c3c.exe test_suite/
|
||||
|
||||
- name: Test python script
|
||||
run: |
|
||||
@@ -168,7 +168,7 @@ jobs:
|
||||
- name: run compiler tests
|
||||
run: |
|
||||
cd test
|
||||
../build/c3c.exe compile --target windows-x64 -O1 src/test_suite_runner.c3 --enable-new-generics
|
||||
../build/c3c.exe compile --target windows-x64 -O1 src/test_suite_runner.c3 --stdlib ../lib7 --enable-new-generics
|
||||
./test_suite_runner.exe ../build/c3c.exe test_suite/
|
||||
|
||||
build-msys2-clang:
|
||||
@@ -220,7 +220,7 @@ jobs:
|
||||
- name: run compiler tests
|
||||
run: |
|
||||
cd test
|
||||
../build/c3c.exe compile-run -O1 src/test_suite_runner.c3 --enable-new-generics
|
||||
../build/c3c.exe compile-run -O1 --stdlib ../lib7 src/test_suite_runner.c3 --enable-new-generics
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-22.04
|
||||
@@ -381,7 +381,7 @@ jobs:
|
||||
- name: run compiler tests
|
||||
run: |
|
||||
cd test
|
||||
../build/c3c compile-run -O1 src/test_suite_runner.c3 --enable-new-generics -- ../build/c3c test_suite/
|
||||
../build/c3c compile-run -O1 src/test_suite_runner.c3 --stdlib ../lib7 --enable-new-generics -- ../build/c3c test_suite/
|
||||
|
||||
- name: bundle_output
|
||||
if: matrix.llvm_version == env.LLVM_RELEASE_VERSION_LINUX
|
||||
@@ -502,7 +502,7 @@ jobs:
|
||||
- name: run compiler tests
|
||||
run: |
|
||||
cd test
|
||||
../build/c3c compile-run -O1 src/test_suite_runner.c3 --enable-new-generics -- ../build/c3c test_suite/
|
||||
../build/c3c compile-run -O1 src/test_suite_runner.c3 --stdlib ../lib7 --enable-new-generics -- ../build/c3c test_suite/
|
||||
|
||||
- name: bundle_output
|
||||
if: matrix.llvm_version == env.LLVM_RELEASE_VERSION_UBUNTU20
|
||||
@@ -606,7 +606,7 @@ jobs:
|
||||
- name: run compiler tests
|
||||
run: |
|
||||
cd test
|
||||
../build/c3c compile-run -O1 src/test_suite_runner.c3 --enable-new-generics -- ../build/c3c test_suite/
|
||||
../build/c3c compile-run -O1 src/test_suite_runner.c3 --stdlib ../lib7 --enable-new-generics -- ../build/c3c test_suite/
|
||||
|
||||
build-mac:
|
||||
runs-on: macos-latest
|
||||
@@ -686,13 +686,13 @@ jobs:
|
||||
- name: run compiler tests
|
||||
run: |
|
||||
cd test
|
||||
../build/c3c compile -O1 src/test_suite_runner.c3 --enable-new-generics
|
||||
../build/c3c compile -O1 src/test_suite_runner.c3 --stdlib ../lib7 --enable-new-generics
|
||||
./test_suite_runner ../build/c3c test_suite/
|
||||
|
||||
- name: run build test suite runner
|
||||
run: |
|
||||
cd test
|
||||
../build/c3c compile -O1 src/test_suite_runner.c3 --enable-new-generics
|
||||
../build/c3c compile -O1 src/test_suite_runner.c3 --stdlib ../lib7 --enable-new-generics
|
||||
|
||||
- name: bundle_output
|
||||
if: matrix.llvm_version == env.LLVM_RELEASE_VERSION_MAC
|
||||
|
||||
@@ -21,7 +21,7 @@ fn File! open_path(Path path, String mode)
|
||||
|
||||
fn bool exists(String file) => @pool()
|
||||
{
|
||||
return path::exists(path::tnew(file)) ?? false;
|
||||
return os::native_file_or_dir_exists(file);
|
||||
}
|
||||
|
||||
fn File from_handle(CFile file)
|
||||
@@ -34,12 +34,20 @@ fn bool is_file(String path)
|
||||
return os::native_is_file(path);
|
||||
}
|
||||
|
||||
fn bool is_dir(String path)
|
||||
{
|
||||
return os::native_is_dir(path);
|
||||
}
|
||||
|
||||
fn usz! get_size(String path)
|
||||
{
|
||||
return os::native_file_size(path);
|
||||
}
|
||||
|
||||
fn void! delete(String filename) => os::native_remove(filename) @inline;
|
||||
fn void! delete(String filename)
|
||||
{
|
||||
return os::native_remove(filename) @inline;
|
||||
}
|
||||
|
||||
|
||||
<*
|
||||
|
||||
@@ -2,7 +2,7 @@ module std::io::path;
|
||||
import std::collections::list, std::io::os;
|
||||
import std::os::win32;
|
||||
|
||||
const PathEnv DEFAULT_PATH_ENV = env::WIN32 ? PathEnv.WIN32 : PathEnv.POSIX;
|
||||
const PathEnv DEFAULT_ENV = env::WIN32 ? PathEnv.WIN32 : PathEnv.POSIX;
|
||||
const char PREFERRED_SEPARATOR_WIN32 = '\\';
|
||||
const char PREFERRED_SEPARATOR_POSIX = '/';
|
||||
const char PREFERRED_SEPARATOR = env::WIN32 ? PREFERRED_SEPARATOR_WIN32 : PREFERRED_SEPARATOR_POSIX;
|
||||
@@ -21,6 +21,7 @@ struct PathImp (Printable)
|
||||
{
|
||||
String path_string;
|
||||
PathEnv env;
|
||||
Allocator allocator;
|
||||
}
|
||||
|
||||
enum PathEnv
|
||||
@@ -42,24 +43,35 @@ fn bool is_file(Path path) => os::native_is_file(path.str_view());
|
||||
fn usz! file_size(Path path) => os::native_file_size(path.str_view());
|
||||
fn bool exists(Path path) => os::native_file_or_dir_exists(path.str_view());
|
||||
fn Path! tcwd() => cwd(tmem()) @inline;
|
||||
fn void! chdir(Path path) => os::native_chdir(path) @inline;
|
||||
|
||||
<*
|
||||
@require @is_pathlike(path) : "Expected a Path or String to chdir"
|
||||
*>
|
||||
macro void! chdir(path)
|
||||
{
|
||||
$if @typeis(path, String):
|
||||
@pool()
|
||||
{
|
||||
return os::native_chdir(tnew(path));
|
||||
};
|
||||
$else
|
||||
return os::native_chdir(path) @inline;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn Path! temp_directory(Allocator allocator) => os::native_temp_directory(allocator);
|
||||
|
||||
fn void! delete(Path path) => os::native_remove(path.str_view()) @inline;
|
||||
|
||||
macro bool is_separator(char c, PathEnv path_env = DEFAULT_PATH_ENV)
|
||||
macro bool @is_pathlike(#path) => @typeis(#path, String) || @typeis(#path, Path);
|
||||
|
||||
macro bool is_separator(char c, PathEnv path_env = DEFAULT_ENV)
|
||||
{
|
||||
return c == '/' || (c == '\\' && path_env == PathEnv.WIN32);
|
||||
}
|
||||
|
||||
macro bool is_posix_separator(char c)
|
||||
{
|
||||
return c == '/' || c == '\\';
|
||||
}
|
||||
|
||||
macro bool is_win32_separator(char c)
|
||||
{
|
||||
return c == '/' || c == '\\';
|
||||
}
|
||||
macro bool is_posix_separator(char c) => c == '/';
|
||||
macro bool is_win32_separator(char c) => c == '/' || c == '\\';
|
||||
|
||||
fn PathList! ls(Allocator allocator, Path dir, bool no_dirs = false, bool no_symlinks = false, String mask = "")
|
||||
{
|
||||
@@ -81,35 +93,35 @@ enum MkdirPermissions
|
||||
Create a directory on a given path, optionally recursive.
|
||||
|
||||
@param path `The path to create`
|
||||
@require @is_pathlike(path) : "Expected a Path or String to chdir"
|
||||
@param recursive `If directories in between should be created if they're missing, defaults to false`
|
||||
@param permissions `The permissions to set on the directory`
|
||||
*>
|
||||
fn bool! mkdir(Path path, bool recursive = false, MkdirPermissions permissions = NORMAL)
|
||||
macro bool! mkdir(Path path, bool recursive = false, MkdirPermissions permissions = NORMAL)
|
||||
{
|
||||
if (!path.path_string.len) return PathResult.INVALID_PATH?;
|
||||
if (is_dir(path)) return false;
|
||||
if (exists(path)) return IoError.FILE_NOT_DIR?;
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
if (try parent = path.parent()) mkdir(parent, true, permissions)!;
|
||||
$if @typeis(path, String):
|
||||
@pool() { return _mkdir(tnew(path), recursive, permissions); };
|
||||
$else
|
||||
return _mkdir(path, recursive, permissions);
|
||||
$endif
|
||||
}
|
||||
if (!is_dir(path.parent()) ?? false) return IoError.CANNOT_READ_DIR?;
|
||||
|
||||
return os::native_mkdir(path, permissions);
|
||||
}
|
||||
|
||||
<*
|
||||
Tries to delete directory, which must be empty.
|
||||
|
||||
@param path `The path to delete`
|
||||
@require @is_pathlike(path) : "Expected a Path or String to chdir"
|
||||
@return `true if there was a directory to delete, false otherwise`
|
||||
@return! PathResult.INVALID_PATH `if the path was invalid`
|
||||
*>
|
||||
fn bool! rmdir(Path path)
|
||||
macro bool! rmdir(path)
|
||||
{
|
||||
if (!path.path_string.len) return PathResult.INVALID_PATH?;
|
||||
return os::native_rmdir(path);
|
||||
$if @typeis(path, String):
|
||||
@pool() { return _rmdir(tnew(path)); };
|
||||
$else
|
||||
return _mkdir(path);
|
||||
$endif
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -130,9 +142,9 @@ fn void! rmtree(Path path)
|
||||
|
||||
@return! PathResult.INVALID_PATH `if the path was invalid`
|
||||
*>
|
||||
fn Path! new(Allocator allocator, String path, PathEnv path_env = DEFAULT_PATH_ENV)
|
||||
fn Path! new(Allocator allocator, String path, PathEnv path_env = DEFAULT_ENV)
|
||||
{
|
||||
return { normalize(path.copy(allocator), path_env), path_env };
|
||||
return { normalize(path.copy(allocator), path_env), path_env, allocator };
|
||||
}
|
||||
|
||||
<*
|
||||
@@ -140,7 +152,7 @@ fn Path! new(Allocator allocator, String path, PathEnv path_env = DEFAULT_PATH_E
|
||||
|
||||
@return! PathResult.INVALID_PATH `if the path was invalid`
|
||||
*>
|
||||
fn Path! tnew(String path, PathEnv path_env = DEFAULT_PATH_ENV)
|
||||
fn Path! tnew(String path, PathEnv path_env = DEFAULT_ENV)
|
||||
{
|
||||
return new(tmem(), path, path_env);
|
||||
}
|
||||
@@ -181,33 +193,37 @@ fn Path! Path.append(self, Allocator allocator, String filename)
|
||||
dstr.append(self.path_string);
|
||||
dstr.append(PREFERRED_SEPARATOR);
|
||||
dstr.append(filename);
|
||||
return { normalize(dstr.copy_str(allocator), self.env), self.env };
|
||||
return new(allocator, dstr.str_view(), self.env);
|
||||
};
|
||||
}
|
||||
|
||||
fn Path! Path.tappend(self, String filename) => self.append(tmem(), filename);
|
||||
|
||||
fn usz Path.start_of_base_name(self) @local
|
||||
fn usz! start_of_base_name(String str, PathEnv path_env) @local
|
||||
{
|
||||
String path_str = self.path_string;
|
||||
if (!path_str.len) return 0;
|
||||
if (self.env == PathEnv.WIN32)
|
||||
{
|
||||
if (try index = path_str.rindex_of_char('\\'))
|
||||
if (!str.len) return PathResult.INVALID_PATH?;
|
||||
usz! start_slash = str.rindex_of_char('/');
|
||||
if (path_env != PathEnv.WIN32) return start_slash + 1 ?? 0;
|
||||
if (try index = str.rindex_of_char('\\'))
|
||||
{
|
||||
if (try start_slash && start_slash > index) return start_slash + 1;
|
||||
// c:\ style path, we're done!
|
||||
if (path_str[0] != '\\') return index + 1;
|
||||
if (str[0] != '\\') return index + 1;
|
||||
// Handle \\server\foo
|
||||
// Find the \ before "foo"
|
||||
usz last_index = 2 + path_str[2..].index_of_char('\\')!!;
|
||||
usz last_index = 2 + str[2..].index_of_char('\\')!;
|
||||
// If they don't match, we're done
|
||||
assert(last_index <= index, "Invalid normalized, path %d vs %s in %s", last_index, index, path_str);
|
||||
if (last_index > index) return PathResult.INVALID_PATH?;
|
||||
if (last_index != index) return index + 1;
|
||||
// Otherwise just default to the volume length.
|
||||
}
|
||||
return volume_name_len(path_str, self.env)!!;
|
||||
return volume_name_len(str, path_env)!!;
|
||||
}
|
||||
return path_str.rindex_of_char('/') + 1 ?? 0;
|
||||
|
||||
|
||||
fn bool! String.is_absolute_path(self) => @pool()
|
||||
{
|
||||
return tnew(self).is_absolute();
|
||||
}
|
||||
|
||||
fn bool! Path.is_absolute(self)
|
||||
@@ -220,8 +236,13 @@ fn bool! Path.is_absolute(self)
|
||||
}
|
||||
|
||||
|
||||
fn Path! String.to_absolute_path(self, Allocator allocator) => @pool(allocator)
|
||||
{
|
||||
return tnew(self).absolute(allocator);
|
||||
}
|
||||
|
||||
<*
|
||||
@require self.env == DEFAULT_PATH_ENV : "This method is only available on native paths"
|
||||
@require self.env == DEFAULT_ENV : "This method is only available on native paths"
|
||||
*>
|
||||
fn Path! Path.absolute(self, Allocator allocator)
|
||||
{
|
||||
@@ -236,34 +257,47 @@ fn Path! Path.absolute(self, Allocator allocator)
|
||||
return new(allocator, cwd, self.env);
|
||||
};
|
||||
}
|
||||
$if DEFAULT_PATH_ENV == WIN32:
|
||||
$if DEFAULT_ENV == WIN32:
|
||||
@pool(allocator)
|
||||
{
|
||||
const usz BUFFER_LEN = 4096;
|
||||
WString buffer = (WString)mem::temp_alloc_array(Char16, BUFFER_LEN);
|
||||
buffer = win32::_wfullpath(buffer, path_str.to_wstring_tcopy()!, BUFFER_LEN);
|
||||
if (!buffer) return PathResult.INVALID_PATH?;
|
||||
return { string::new_from_wstring(allocator, buffer), WIN32 };
|
||||
return { string::new_from_wstring(allocator, buffer), WIN32, allocator };
|
||||
};
|
||||
$else
|
||||
String cwd = os::getcwd(tmem())!;
|
||||
return (Path){ cwd, self.env }.append(allocator, path_str)!;
|
||||
return (Path){ cwd, self.env, tmem() }.append(allocator, path_str)!;
|
||||
$endif
|
||||
}
|
||||
|
||||
fn String! String.file_basename(self, Allocator allocator) => @pool(allocator)
|
||||
{
|
||||
return tnew(self).basename().copy(allocator);
|
||||
}
|
||||
|
||||
fn String! String.file_tbasename(self) => self.file_basename(tmem());
|
||||
|
||||
fn String Path.basename(self)
|
||||
{
|
||||
usz basename_start = self.start_of_base_name();
|
||||
usz basename_start = start_of_base_name(self.path_string, self.env)!!;
|
||||
String path_str = self.path_string;
|
||||
if (basename_start == path_str.len) return "";
|
||||
return path_str[basename_start..];
|
||||
}
|
||||
|
||||
fn String! String.path_tdirname(self) => self.path_dirname(tmem());
|
||||
|
||||
fn String! String.path_dirname(self, Allocator allocator) => @pool(allocator)
|
||||
{
|
||||
return tnew(self).dirname().copy(allocator);
|
||||
}
|
||||
|
||||
fn String Path.dirname(self)
|
||||
{
|
||||
usz basename_start = self.start_of_base_name();
|
||||
String path_str = self.path_string;
|
||||
usz basename_start = start_of_base_name(path_str, self.env)!!;
|
||||
if (basename_start == 0) return ".";
|
||||
usz start = volume_name_len(path_str, self.env)!!;
|
||||
if (basename_start <= start + 1)
|
||||
@@ -277,6 +311,7 @@ fn String Path.dirname(self)
|
||||
return path_str[:basename_start - 1];
|
||||
}
|
||||
|
||||
|
||||
<*
|
||||
Test if the path has the given extension, so given the path /foo/bar.c3
|
||||
this would be true matching the extension "c3"
|
||||
@@ -310,6 +345,16 @@ fn String Path.volume_name(self)
|
||||
return self.path_string[:len];
|
||||
}
|
||||
|
||||
fn Path! String.to_path(self, Allocator allocator)
|
||||
{
|
||||
return new(allocator, self);
|
||||
}
|
||||
|
||||
fn Path! String.to_tpath(self)
|
||||
{
|
||||
return new(tmem(), self);
|
||||
}
|
||||
|
||||
fn usz! volume_name_len(String path, PathEnv path_env) @local
|
||||
{
|
||||
usz len = path.len;
|
||||
@@ -360,13 +405,13 @@ fn Path! Path.parent(self)
|
||||
{
|
||||
if (is_separator(c, self.env))
|
||||
{
|
||||
return { self.path_string[:i], self.env };
|
||||
return { self.path_string[:i], self.env, null };
|
||||
}
|
||||
}
|
||||
return PathResult.NO_PARENT?;
|
||||
}
|
||||
|
||||
fn String! normalize(String path_str, PathEnv path_env = DEFAULT_PATH_ENV)
|
||||
fn String! normalize(String path_str, PathEnv path_env = DEFAULT_ENV)
|
||||
{
|
||||
if (!path_str.len) return path_str;
|
||||
usz path_start = volume_name_len(path_str, path_env)!;
|
||||
@@ -517,7 +562,7 @@ def PathWalker = fn bool! (Path, bool is_dir, void*);
|
||||
<*
|
||||
Walk the path recursively. PathWalker is run on every file and
|
||||
directory found. Return true to abort the walk.
|
||||
@require self.env == DEFAULT_PATH_ENV : "This method is only available on native paths"
|
||||
@require self.env == DEFAULT_ENV : "This method is only available on native paths"
|
||||
*>
|
||||
fn bool! Path.walk(self, PathWalker w, void* data)
|
||||
{
|
||||
@@ -538,6 +583,35 @@ fn bool! Path.walk(self, PathWalker w, void* data)
|
||||
return false;
|
||||
}
|
||||
|
||||
def TraverseCallback = fn bool! (Path, bool is_dir, any data);
|
||||
|
||||
<*
|
||||
Walk the path recursively. TraverseCallback is run for every file and
|
||||
directory found. Return true to abort the walk.
|
||||
@require path.env == DEFAULT_ENV : "This method is only available on native paths"
|
||||
*>
|
||||
fn bool! traverse(Path path, TraverseCallback callback, any data)
|
||||
{
|
||||
const PATH_MAX = 512;
|
||||
@stack_mem(PATH_MAX; Allocator allocator)
|
||||
{
|
||||
Path abs = path.absolute(allocator)!;
|
||||
PathList files = ls(allocator, abs)!;
|
||||
foreach (f : files)
|
||||
{
|
||||
if (f.str_view() == "." || f.str_view() == "..") continue;
|
||||
@stack_mem(128; Allocator smem)
|
||||
{
|
||||
f = abs.append(smem, f.str_view())!;
|
||||
bool is_directory = is_dir(f);
|
||||
if (callback(f, is_directory, data)!) return true;
|
||||
if (is_directory && traverse(f, callback, data)!) return true;
|
||||
};
|
||||
}
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
fn String Path.str_view(self) @inline
|
||||
{
|
||||
return self.path_string;
|
||||
@@ -549,26 +623,19 @@ fn bool Path.has_suffix(self, String str)
|
||||
return self.str_view().ends_with(str);
|
||||
}
|
||||
|
||||
fn void Path.free_with_allocator(self, Allocator allocator)
|
||||
{
|
||||
allocator::free(allocator, self.path_string.ptr);
|
||||
}
|
||||
|
||||
<*
|
||||
@require self.allocator != null : "This Path should never be freed"
|
||||
*>
|
||||
fn void Path.free(self)
|
||||
{
|
||||
free(self.path_string.ptr);
|
||||
allocator::free(self.allocator, self.path_string.ptr);
|
||||
}
|
||||
|
||||
|
||||
fn usz! Path.to_format(&self, Formatter* formatter) @dynamic
|
||||
{
|
||||
return formatter.print(self.str_view());
|
||||
}
|
||||
|
||||
fn String Path.to_new_string(&self, Allocator allocator = allocator::heap()) @dynamic
|
||||
{
|
||||
return self.str_view().copy(allocator);
|
||||
}
|
||||
|
||||
const bool[256] RESERVED_PATH_CHAR_POSIX = {
|
||||
[0] = true,
|
||||
@@ -592,9 +659,29 @@ macro bool is_reserved_win32_path_char(char c)
|
||||
return RESERVED_PATH_CHAR_WIN32[c];
|
||||
}
|
||||
|
||||
macro bool is_reserved_path_char(char c, PathEnv path_env = DEFAULT_PATH_ENV)
|
||||
macro bool is_reserved_path_char(char c, PathEnv path_env = DEFAULT_ENV)
|
||||
{
|
||||
return path_env == PathEnv.WIN32
|
||||
? RESERVED_PATH_CHAR_WIN32[c]
|
||||
: RESERVED_PATH_CHAR_POSIX[c];
|
||||
}
|
||||
fn bool! _mkdir(Path path, bool recursive = false, MkdirPermissions permissions = NORMAL) @private
|
||||
{
|
||||
if (!path.path_string.len) return PathResult.INVALID_PATH?;
|
||||
if (is_dir(path)) return false;
|
||||
if (exists(path)) return IoError.FILE_NOT_DIR?;
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
if (try parent = path.parent()) mkdir(parent, true, permissions)!;
|
||||
}
|
||||
if (!is_dir(path.parent()) ?? false) return IoError.CANNOT_READ_DIR?;
|
||||
|
||||
return os::native_mkdir(path, permissions);
|
||||
}
|
||||
|
||||
fn bool! _rmdir(Path path) @private
|
||||
{
|
||||
if (!path.path_string.len) return PathResult.INVALID_PATH?;
|
||||
return os::native_rmdir(path);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ in llvmPackages.stdenv.mkDerivation (finalAttrs: {
|
||||
checkPhase = ''
|
||||
runHook preCheck
|
||||
( cd ../resources/testproject; ../../build/c3c build --trust=full )
|
||||
( cd ../test; ../build/c3c compile-run -O1 src/test_suite_runner.c3 --enable-new-generics -- ../build/c3c test_suite )
|
||||
( cd ../test; ../build/c3c compile-run -O1 src/test_suite_runner.c3 --stdlib ../lib7 --enable-new-generics -- ../build/c3c test_suite )
|
||||
runHook postCheck
|
||||
'';
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
- Aliases are now correctly handled as if they were variables/functions in regards to namespacing and accept `@builtin`.
|
||||
- Correctly handle in/out when interacting with inout.
|
||||
- Don't delete .o files not produced by the compiler.
|
||||
- Fix optional jumps in expression lists, #1942.
|
||||
|
||||
### Stdlib changes
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ static inline bool create_module_or_check_name(CompilationUnit *unit, Path *modu
|
||||
if (!module->is_generic) goto DONE;
|
||||
if (vec_size(parameters) != vec_size(module->parameters))
|
||||
{
|
||||
PRINT_ERROR_AT(module_name, "The parameter declarations of the generic module '%s' don't match.", module->name);
|
||||
PRINT_ERROR_AT(module_name, "The parameter declarations of the generic module '%s' don't match.", module_name->module);
|
||||
SEMA_NOTE(module->name, "A different definition can be found here.");
|
||||
return false;
|
||||
}
|
||||
@@ -39,7 +39,7 @@ static inline bool create_module_or_check_name(CompilationUnit *unit, Path *modu
|
||||
bool is_type = str_is_type(name);
|
||||
if (is_type != str_is_type(module->parameters[idx]))
|
||||
{
|
||||
PRINT_ERROR_AT(module_name, "The parameter declarations of the generic module '%s' don't match.", module->name);
|
||||
PRINT_ERROR_AT(module_name, "The parameter declarations of the generic module '%s' don't match.", module_name->module);
|
||||
SEMA_NOTE(module->name, "The other definition is here.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5876,10 +5876,15 @@ static void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr
|
||||
|
||||
static inline void llvm_emit_expression_list_expr(GenContext *c, BEValue *be_value, Expr *expr)
|
||||
{
|
||||
FOREACH(Expr *, e, expr->expression_list)
|
||||
Expr **list = expr->expression_list;
|
||||
unsigned count = vec_size(list);
|
||||
assert(count);
|
||||
unsigned last = count - 1;
|
||||
for (unsigned i = 0; i < last; i++)
|
||||
{
|
||||
llvm_emit_expr(c, be_value, e);
|
||||
llvm_emit_ignored_expr(c, list[i]);
|
||||
}
|
||||
llvm_emit_expr(c, be_value, list[last]);
|
||||
}
|
||||
|
||||
static inline void llvm_emit_return_block(GenContext *c, BEValue *be_value, Type *type, AstId current, BlockExit **block_exit)
|
||||
|
||||
@@ -21,14 +21,14 @@ fn void main(String[] args)
|
||||
print_to_file = !io::stdout().isatty();
|
||||
|
||||
// Retain our current path.
|
||||
start_cwd = path::temp_cwd()!!;
|
||||
start_cwd = path::tcwd()!!;
|
||||
|
||||
// Create our test path, note that this prevents us from doing tests in parallell
|
||||
test_dir = start_cwd.temp_append("_c3test_")!!;
|
||||
test_dir = start_cwd.tappend("_c3test_")!!;
|
||||
defer (void)path::rmtree(test_dir);
|
||||
|
||||
// Find the compiler
|
||||
Path! path = start_cwd.temp_append(args[1]);
|
||||
Path! path = start_cwd.tappend(args[1]);
|
||||
if (catch path) arg_error_exit(appname, "Invalid compiler path: %s", args[1]);
|
||||
// Is it a valid file?
|
||||
if (!path::is_file(path))
|
||||
@@ -58,7 +58,7 @@ fn void main(String[] args)
|
||||
{
|
||||
error_exit(appname, "Stdlib directory '%s' cannot be found.", stdlib);
|
||||
}
|
||||
stdlib = start_cwd.temp_append(stdlib).str_view()!!;
|
||||
stdlib = start_cwd.tappend(stdlib).str_view()!!;
|
||||
default:
|
||||
arg_error_exit(appname, "Unknown option '%s'.", args[i]);
|
||||
}
|
||||
@@ -66,7 +66,7 @@ fn void main(String[] args)
|
||||
if (only_skipped && args[3] != "-s" && args[3] != "--skipped") usage(appname);
|
||||
|
||||
// Get the directory or file to test
|
||||
Path! file = path::temp_new(args[2]);
|
||||
Path! file = args[2].to_tpath();
|
||||
if (catch file) arg_error_exit(appname, "Invalid path: '%s'.", args[2]);
|
||||
|
||||
// Now just run all tests recursively.
|
||||
@@ -129,17 +129,14 @@ fn void RunFile.add_line(&self, String line)
|
||||
|
||||
fn RunFile*! create_input_file(String filename)
|
||||
{
|
||||
File file = file::open_path(test_dir.temp_append(filename), "wb")!;
|
||||
File file = file::open_path(test_dir.tappend(filename), "wb")!;
|
||||
RunFile *run_file = mem::temp_new(RunFile, { .name = filename, .file = file, .is_output = false });
|
||||
run_file.warnings.temp_init();
|
||||
run_file.errors.temp_init();
|
||||
return run_file;
|
||||
}
|
||||
|
||||
fn RunFile*! create_output_file(String filename)
|
||||
{
|
||||
RunFile *run_file = mem::temp_new(RunFile, { .name = filename, .is_output = true });
|
||||
run_file.expected_lines.temp_init();
|
||||
return run_file;
|
||||
}
|
||||
|
||||
@@ -168,7 +165,7 @@ fn bool check_line(RunSettings* settings, String type, String file, String line_
|
||||
int line = line_str.to_int()!!;
|
||||
|
||||
// Get the base name
|
||||
String basename = path::temp_new(file).basename()!!;
|
||||
String basename = file.file_tbasename()!!;
|
||||
|
||||
// Loop through our input files (usually only 1!)
|
||||
foreach (f : settings.input_files)
|
||||
@@ -232,7 +229,7 @@ fn bool parse_result(DString out, RunSettings settings)
|
||||
io::printn("FAILED\n\n Unexpected compilation errors:");
|
||||
io::printn(" ------------------------------");
|
||||
}
|
||||
io::printf(" %d. %s at %s:%s: ", ++errors, parts[0], path::temp_new(parts[1]).basename()!!, parts[2]);
|
||||
io::printf(" %d. %s at %s:%s: ", ++errors, parts[0], parts[1].file_tbasename()!!, parts[2]);
|
||||
io::printfn(`"%s"`, parts[4]);
|
||||
success = false;
|
||||
}
|
||||
@@ -389,9 +386,6 @@ fn void test_file(Path file_path)
|
||||
}
|
||||
defer (void)f.close();
|
||||
RunSettings settings;
|
||||
settings.opts.temp_init();
|
||||
settings.input_files.temp_init();
|
||||
settings.output_files.temp_init();
|
||||
settings.current_file = create_input_file(file_path.basename()[..^(single ? 4 : 5)].tconcat(".c3"))!!;
|
||||
settings.input_files.push(settings.current_file);
|
||||
int line_no = 1;
|
||||
@@ -413,7 +407,6 @@ fn void test_file(Path file_path)
|
||||
|
||||
// Construct the compile line
|
||||
List{String} cmdline;
|
||||
cmdline.temp_init();
|
||||
cmdline.push(compiler_path.str_view());
|
||||
cmdline.push("compile-only");
|
||||
cmdline.push("--test");
|
||||
@@ -448,7 +441,7 @@ fn void test_file(Path file_path)
|
||||
SubProcess compilation = process::create(cmdline.array_view(), { .search_user_path, .no_window, .inherit_environment })!!;
|
||||
defer compilation.destroy();
|
||||
CInt result = compilation.join()!!;
|
||||
DString out = dstring::temp_new();
|
||||
DString out;
|
||||
io::copy_to(&&compilation.stderr(), &out)!!;
|
||||
if (result != 0 && result != 1)
|
||||
{
|
||||
@@ -501,12 +494,12 @@ fn void test_file(Path file_path)
|
||||
fn void! test_path(Path file_path)
|
||||
{
|
||||
(void)path::chdir(start_cwd);
|
||||
foreach (file : path::temp_ls(file_path)!!)
|
||||
foreach (file : path::ls(tmem(), file_path)!!)
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
(void)path::chdir(start_cwd);
|
||||
file = file_path.temp_append(file.str_view())!;
|
||||
file = file_path.tappend(file.str_view())!;
|
||||
switch
|
||||
{
|
||||
case path::is_dir(file):
|
||||
|
||||
@@ -25,11 +25,11 @@ entry:
|
||||
%retparam = alloca i32, align 4
|
||||
%.anon1 = alloca i32, align 4
|
||||
%anon.f2 = alloca i64, align 8
|
||||
%.anon18 = alloca i32, align 4
|
||||
%anon.f19 = alloca i64, align 8
|
||||
%retparam20 = alloca i32, align 4
|
||||
%.anon27 = alloca i32, align 4
|
||||
%anon.f28 = alloca i64, align 8
|
||||
%.anon15 = alloca i32, align 4
|
||||
%anon.f16 = alloca i64, align 8
|
||||
%retparam17 = alloca i32, align 4
|
||||
%.anon22 = alloca i32, align 4
|
||||
%anon.f23 = alloca i64, align 8
|
||||
%0 = call i8 @"std_collections_map$int$int$.HashMap.set"(ptr @test.m, i32 3, i32 100)
|
||||
%1 = call i64 @"std_collections_map$int$int$.HashMap.get"(ptr %retparam, ptr @test.m, i32 3)
|
||||
%not_err = icmp eq i64 %1, 0
|
||||
@@ -38,7 +38,7 @@ entry:
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %1, ptr %anon.f, align 8
|
||||
br label %optional_assign_jump
|
||||
br label %after_assign
|
||||
|
||||
after_check: ; preds = %entry
|
||||
%3 = load i32, ptr %retparam, align 4
|
||||
@@ -46,12 +46,7 @@ after_check: ; preds = %entry
|
||||
store i64 0, ptr %anon.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
optional_assign_jump: ; preds = %assign_optional
|
||||
%reload_err = load i64, ptr %anon.f, align 8
|
||||
store i64 %reload_err, ptr %x.f, align 8
|
||||
br label %after_assign17
|
||||
|
||||
after_assign: ; preds = %after_check
|
||||
after_assign: ; preds = %after_check, %assign_optional
|
||||
%optval = load i64, ptr %anon.f, align 8
|
||||
%not_err3 = icmp eq i64 %optval, 0
|
||||
%4 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true)
|
||||
@@ -59,7 +54,7 @@ after_assign: ; preds = %after_check
|
||||
|
||||
assign_optional4: ; preds = %after_assign
|
||||
store i64 %optval, ptr %anon.f2, align 8
|
||||
br label %optional_assign_jump6
|
||||
br label %after_assign6
|
||||
|
||||
after_check5: ; preds = %after_assign
|
||||
%5 = load i32, ptr %.anon, align 4
|
||||
@@ -67,113 +62,96 @@ after_check5: ; preds = %after_assign
|
||||
store i32 %sub, ptr %.anon, align 4
|
||||
store i32 %5, ptr %.anon1, align 4
|
||||
store i64 0, ptr %anon.f2, align 8
|
||||
br label %after_assign8
|
||||
br label %after_assign6
|
||||
|
||||
optional_assign_jump6: ; preds = %assign_optional4
|
||||
%reload_err7 = load i64, ptr %anon.f2, align 8
|
||||
store i64 %reload_err7, ptr %x.f, align 8
|
||||
br label %after_assign17
|
||||
after_assign6: ; preds = %after_check5, %assign_optional4
|
||||
%optval7 = load i64, ptr %anon.f, align 8
|
||||
%not_err8 = icmp eq i64 %optval7, 0
|
||||
%6 = call i1 @llvm.expect.i1(i1 %not_err8, i1 true)
|
||||
br i1 %6, label %after_check9, label %voiderr
|
||||
|
||||
after_assign8: ; preds = %after_check5
|
||||
%optval9 = load i64, ptr %anon.f, align 8
|
||||
%not_err10 = icmp eq i64 %optval9, 0
|
||||
%6 = call i1 @llvm.expect.i1(i1 %not_err10, i1 true)
|
||||
br i1 %6, label %after_check12, label %assign_optional11
|
||||
|
||||
assign_optional11: ; preds = %after_assign8
|
||||
store i64 %optval9, ptr %x.f, align 8
|
||||
br label %after_assign17
|
||||
|
||||
after_check12: ; preds = %after_assign8
|
||||
after_check9: ; preds = %after_assign6
|
||||
%7 = load i32, ptr %.anon, align 4
|
||||
%8 = call i8 @"std_collections_map$int$int$.HashMap.set"(ptr @test.m, i32 3, i32 %7)
|
||||
%optval13 = load i64, ptr %anon.f2, align 8
|
||||
%not_err14 = icmp eq i64 %optval13, 0
|
||||
%9 = call i1 @llvm.expect.i1(i1 %not_err14, i1 true)
|
||||
br i1 %9, label %after_check16, label %assign_optional15
|
||||
br label %voiderr
|
||||
|
||||
assign_optional15: ; preds = %after_check12
|
||||
store i64 %optval13, ptr %x.f, align 8
|
||||
br label %after_assign17
|
||||
voiderr: ; preds = %after_check9, %after_assign6
|
||||
%optval10 = load i64, ptr %anon.f2, align 8
|
||||
%not_err11 = icmp eq i64 %optval10, 0
|
||||
%9 = call i1 @llvm.expect.i1(i1 %not_err11, i1 true)
|
||||
br i1 %9, label %after_check13, label %assign_optional12
|
||||
|
||||
after_check16: ; preds = %after_check12
|
||||
assign_optional12: ; preds = %voiderr
|
||||
store i64 %optval10, ptr %x.f, align 8
|
||||
br label %after_assign14
|
||||
|
||||
after_check13: ; preds = %voiderr
|
||||
%10 = load i32, ptr %.anon1, align 4
|
||||
store i32 %10, ptr %x, align 4
|
||||
store i64 0, ptr %x.f, align 8
|
||||
br label %after_assign17
|
||||
br label %after_assign14
|
||||
|
||||
after_assign17: ; preds = %after_check16, %assign_optional15, %assign_optional11, %optional_assign_jump6, %optional_assign_jump
|
||||
%11 = call i64 @"std_collections_map$int$int$.HashMap.get"(ptr %retparam20, ptr @test.m, i32 3)
|
||||
%not_err21 = icmp eq i64 %11, 0
|
||||
%12 = call i1 @llvm.expect.i1(i1 %not_err21, i1 true)
|
||||
br i1 %12, label %after_check23, label %assign_optional22
|
||||
after_assign14: ; preds = %after_check13, %assign_optional12
|
||||
%11 = call i64 @"std_collections_map$int$int$.HashMap.get"(ptr %retparam17, ptr @test.m, i32 3)
|
||||
%not_err18 = icmp eq i64 %11, 0
|
||||
%12 = call i1 @llvm.expect.i1(i1 %not_err18, i1 true)
|
||||
br i1 %12, label %after_check20, label %assign_optional19
|
||||
|
||||
assign_optional22: ; preds = %after_assign17
|
||||
store i64 %11, ptr %anon.f19, align 8
|
||||
br label %optional_assign_jump24
|
||||
assign_optional19: ; preds = %after_assign14
|
||||
store i64 %11, ptr %anon.f16, align 8
|
||||
br label %after_assign21
|
||||
|
||||
after_check23: ; preds = %after_assign17
|
||||
%13 = load i32, ptr %retparam20, align 4
|
||||
store i32 %13, ptr %.anon18, align 4
|
||||
store i64 0, ptr %anon.f19, align 8
|
||||
br label %after_assign26
|
||||
after_check20: ; preds = %after_assign14
|
||||
%13 = load i32, ptr %retparam17, align 4
|
||||
store i32 %13, ptr %.anon15, align 4
|
||||
store i64 0, ptr %anon.f16, align 8
|
||||
br label %after_assign21
|
||||
|
||||
optional_assign_jump24: ; preds = %assign_optional22
|
||||
%reload_err25 = load i64, ptr %anon.f19, align 8
|
||||
store i64 %reload_err25, ptr %x.f, align 8
|
||||
br label %after_assign44
|
||||
after_assign21: ; preds = %after_check20, %assign_optional19
|
||||
%optval24 = load i64, ptr %anon.f16, align 8
|
||||
%not_err25 = icmp eq i64 %optval24, 0
|
||||
%14 = call i1 @llvm.expect.i1(i1 %not_err25, i1 true)
|
||||
br i1 %14, label %after_check27, label %assign_optional26
|
||||
|
||||
after_assign26: ; preds = %after_check23
|
||||
%optval29 = load i64, ptr %anon.f19, align 8
|
||||
%not_err30 = icmp eq i64 %optval29, 0
|
||||
%14 = call i1 @llvm.expect.i1(i1 %not_err30, i1 true)
|
||||
br i1 %14, label %after_check32, label %assign_optional31
|
||||
assign_optional26: ; preds = %after_assign21
|
||||
store i64 %optval24, ptr %anon.f23, align 8
|
||||
br label %after_assign28
|
||||
|
||||
assign_optional31: ; preds = %after_assign26
|
||||
store i64 %optval29, ptr %anon.f28, align 8
|
||||
br label %optional_assign_jump33
|
||||
|
||||
after_check32: ; preds = %after_assign26
|
||||
%15 = load i32, ptr %.anon18, align 4
|
||||
after_check27: ; preds = %after_assign21
|
||||
%15 = load i32, ptr %.anon15, align 4
|
||||
%add = add i32 %15, 1
|
||||
store i32 %add, ptr %.anon18, align 4
|
||||
store i32 %add, ptr %.anon27, align 4
|
||||
store i64 0, ptr %anon.f28, align 8
|
||||
br label %after_assign35
|
||||
store i32 %add, ptr %.anon15, align 4
|
||||
store i32 %add, ptr %.anon22, align 4
|
||||
store i64 0, ptr %anon.f23, align 8
|
||||
br label %after_assign28
|
||||
|
||||
optional_assign_jump33: ; preds = %assign_optional31
|
||||
%reload_err34 = load i64, ptr %anon.f28, align 8
|
||||
store i64 %reload_err34, ptr %x.f, align 8
|
||||
br label %after_assign44
|
||||
after_assign28: ; preds = %after_check27, %assign_optional26
|
||||
%optval29 = load i64, ptr %anon.f16, align 8
|
||||
%not_err30 = icmp eq i64 %optval29, 0
|
||||
%16 = call i1 @llvm.expect.i1(i1 %not_err30, i1 true)
|
||||
br i1 %16, label %after_check31, label %voiderr32
|
||||
|
||||
after_assign35: ; preds = %after_check32
|
||||
%optval36 = load i64, ptr %anon.f19, align 8
|
||||
%not_err37 = icmp eq i64 %optval36, 0
|
||||
%16 = call i1 @llvm.expect.i1(i1 %not_err37, i1 true)
|
||||
br i1 %16, label %after_check39, label %assign_optional38
|
||||
|
||||
assign_optional38: ; preds = %after_assign35
|
||||
store i64 %optval36, ptr %x.f, align 8
|
||||
br label %after_assign44
|
||||
|
||||
after_check39: ; preds = %after_assign35
|
||||
%17 = load i32, ptr %.anon18, align 4
|
||||
after_check31: ; preds = %after_assign28
|
||||
%17 = load i32, ptr %.anon15, align 4
|
||||
%18 = call i8 @"std_collections_map$int$int$.HashMap.set"(ptr @test.m, i32 3, i32 %17)
|
||||
%optval40 = load i64, ptr %anon.f28, align 8
|
||||
%not_err41 = icmp eq i64 %optval40, 0
|
||||
%19 = call i1 @llvm.expect.i1(i1 %not_err41, i1 true)
|
||||
br i1 %19, label %after_check43, label %assign_optional42
|
||||
br label %voiderr32
|
||||
|
||||
assign_optional42: ; preds = %after_check39
|
||||
store i64 %optval40, ptr %x.f, align 8
|
||||
br label %after_assign44
|
||||
voiderr32: ; preds = %after_check31, %after_assign28
|
||||
%optval33 = load i64, ptr %anon.f23, align 8
|
||||
%not_err34 = icmp eq i64 %optval33, 0
|
||||
%19 = call i1 @llvm.expect.i1(i1 %not_err34, i1 true)
|
||||
br i1 %19, label %after_check36, label %assign_optional35
|
||||
|
||||
after_check43: ; preds = %after_check39
|
||||
%20 = load i32, ptr %.anon27, align 4
|
||||
assign_optional35: ; preds = %voiderr32
|
||||
store i64 %optval33, ptr %x.f, align 8
|
||||
br label %after_assign37
|
||||
|
||||
after_check36: ; preds = %voiderr32
|
||||
%20 = load i32, ptr %.anon22, align 4
|
||||
store i32 %20, ptr %x, align 4
|
||||
store i64 0, ptr %x.f, align 8
|
||||
br label %after_assign44
|
||||
br label %after_assign37
|
||||
|
||||
after_assign44: ; preds = %after_check43, %assign_optional42, %assign_optional38, %optional_assign_jump33, %optional_assign_jump24
|
||||
after_assign37: ; preds = %after_check36, %assign_optional35
|
||||
ret void
|
||||
}
|
||||
|
||||
60
test/test_suite7/errors/optional_expr_list.c3t
Normal file
60
test/test_suite7/errors/optional_expr_list.c3t
Normal file
@@ -0,0 +1,60 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
|
||||
fn void main()
|
||||
{
|
||||
int! n;
|
||||
for (n += 1, 1 + 1; false;);
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
|
||||
; ModuleID = 'test'
|
||||
source_filename = "test"
|
||||
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-apple-macosx10.13.0"
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define void @test.main() #0 {
|
||||
entry:
|
||||
%n = alloca i32, align 4
|
||||
%n.f = alloca i64, align 8
|
||||
store i64 0, ptr %n.f, align 8
|
||||
store i32 0, ptr %n, align 4
|
||||
%optval = load i64, ptr %n.f, align 8
|
||||
%not_err = icmp eq i64 %optval, 0
|
||||
%0 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
||||
br i1 %0, label %after_check, label %voiderr
|
||||
|
||||
after_check: ; preds = %entry
|
||||
%1 = load i32, ptr %n, align 4
|
||||
%add = add i32 %1, 1
|
||||
store i32 %add, ptr %n, align 4
|
||||
br label %voiderr
|
||||
|
||||
voiderr: ; preds = %after_check, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define i32 @main(i32 %0, ptr %1) #0 {
|
||||
entry:
|
||||
call void @test.main()
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
|
||||
declare i1 @llvm.expect.i1(i1, i1) #1
|
||||
|
||||
attributes #0 = { nounwind uwtable "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
|
||||
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(none) }
|
||||
|
||||
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
|
||||
|
||||
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!2 = !{i32 2, !"wchar_size", i32 4}
|
||||
!3 = !{i32 4, !"PIC Level", i32 2}
|
||||
!4 = !{i32 1, !"uwtable", i32 2}
|
||||
!5 = !{i32 2, !"frame-pointer", i32 2}
|
||||
@@ -2,7 +2,7 @@
|
||||
module test;
|
||||
import std;
|
||||
|
||||
def Abc = HashMap(<int, int>);
|
||||
def Abc = HashMap{int, int};
|
||||
Abc m;
|
||||
fn void main()
|
||||
{
|
||||
@@ -25,11 +25,11 @@ entry:
|
||||
%retparam = alloca i32, align 4
|
||||
%.anon1 = alloca i32, align 4
|
||||
%anon.f2 = alloca i64, align 8
|
||||
%.anon18 = alloca i32, align 4
|
||||
%anon.f19 = alloca i64, align 8
|
||||
%retparam20 = alloca i32, align 4
|
||||
%.anon27 = alloca i32, align 4
|
||||
%anon.f28 = alloca i64, align 8
|
||||
%.anon15 = alloca i32, align 4
|
||||
%anon.f16 = alloca i64, align 8
|
||||
%retparam17 = alloca i32, align 4
|
||||
%.anon22 = alloca i32, align 4
|
||||
%anon.f23 = alloca i64, align 8
|
||||
%0 = call i8 @"std_collections_map$int$int$.HashMap.set"(ptr @test.m, i32 3, i32 100)
|
||||
%1 = call i64 @"std_collections_map$int$int$.HashMap.get"(ptr %retparam, ptr @test.m, i32 3)
|
||||
%not_err = icmp eq i64 %1, 0
|
||||
@@ -38,7 +38,7 @@ entry:
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %1, ptr %anon.f, align 8
|
||||
br label %optional_assign_jump
|
||||
br label %after_assign
|
||||
|
||||
after_check: ; preds = %entry
|
||||
%3 = load i32, ptr %retparam, align 4
|
||||
@@ -46,12 +46,7 @@ after_check: ; preds = %entry
|
||||
store i64 0, ptr %anon.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
optional_assign_jump: ; preds = %assign_optional
|
||||
%reload_err = load i64, ptr %anon.f, align 8
|
||||
store i64 %reload_err, ptr %x.f, align 8
|
||||
br label %after_assign17
|
||||
|
||||
after_assign: ; preds = %after_check
|
||||
after_assign: ; preds = %after_check, %assign_optional
|
||||
%optval = load i64, ptr %anon.f, align 8
|
||||
%not_err3 = icmp eq i64 %optval, 0
|
||||
%4 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true)
|
||||
@@ -59,7 +54,7 @@ after_assign: ; preds = %after_check
|
||||
|
||||
assign_optional4: ; preds = %after_assign
|
||||
store i64 %optval, ptr %anon.f2, align 8
|
||||
br label %optional_assign_jump6
|
||||
br label %after_assign6
|
||||
|
||||
after_check5: ; preds = %after_assign
|
||||
%5 = load i32, ptr %.anon, align 4
|
||||
@@ -67,113 +62,96 @@ after_check5: ; preds = %after_assign
|
||||
store i32 %sub, ptr %.anon, align 4
|
||||
store i32 %5, ptr %.anon1, align 4
|
||||
store i64 0, ptr %anon.f2, align 8
|
||||
br label %after_assign8
|
||||
br label %after_assign6
|
||||
|
||||
optional_assign_jump6: ; preds = %assign_optional4
|
||||
%reload_err7 = load i64, ptr %anon.f2, align 8
|
||||
store i64 %reload_err7, ptr %x.f, align 8
|
||||
br label %after_assign17
|
||||
after_assign6: ; preds = %after_check5, %assign_optional4
|
||||
%optval7 = load i64, ptr %anon.f, align 8
|
||||
%not_err8 = icmp eq i64 %optval7, 0
|
||||
%6 = call i1 @llvm.expect.i1(i1 %not_err8, i1 true)
|
||||
br i1 %6, label %after_check9, label %voiderr
|
||||
|
||||
after_assign8: ; preds = %after_check5
|
||||
%optval9 = load i64, ptr %anon.f, align 8
|
||||
%not_err10 = icmp eq i64 %optval9, 0
|
||||
%6 = call i1 @llvm.expect.i1(i1 %not_err10, i1 true)
|
||||
br i1 %6, label %after_check12, label %assign_optional11
|
||||
|
||||
assign_optional11: ; preds = %after_assign8
|
||||
store i64 %optval9, ptr %x.f, align 8
|
||||
br label %after_assign17
|
||||
|
||||
after_check12: ; preds = %after_assign8
|
||||
after_check9: ; preds = %after_assign6
|
||||
%7 = load i32, ptr %.anon, align 4
|
||||
%8 = call i8 @"std_collections_map$int$int$.HashMap.set"(ptr @test.m, i32 3, i32 %7)
|
||||
%optval13 = load i64, ptr %anon.f2, align 8
|
||||
%not_err14 = icmp eq i64 %optval13, 0
|
||||
%9 = call i1 @llvm.expect.i1(i1 %not_err14, i1 true)
|
||||
br i1 %9, label %after_check16, label %assign_optional15
|
||||
br label %voiderr
|
||||
|
||||
assign_optional15: ; preds = %after_check12
|
||||
store i64 %optval13, ptr %x.f, align 8
|
||||
br label %after_assign17
|
||||
voiderr: ; preds = %after_check9, %after_assign6
|
||||
%optval10 = load i64, ptr %anon.f2, align 8
|
||||
%not_err11 = icmp eq i64 %optval10, 0
|
||||
%9 = call i1 @llvm.expect.i1(i1 %not_err11, i1 true)
|
||||
br i1 %9, label %after_check13, label %assign_optional12
|
||||
|
||||
after_check16: ; preds = %after_check12
|
||||
assign_optional12: ; preds = %voiderr
|
||||
store i64 %optval10, ptr %x.f, align 8
|
||||
br label %after_assign14
|
||||
|
||||
after_check13: ; preds = %voiderr
|
||||
%10 = load i32, ptr %.anon1, align 4
|
||||
store i32 %10, ptr %x, align 4
|
||||
store i64 0, ptr %x.f, align 8
|
||||
br label %after_assign17
|
||||
br label %after_assign14
|
||||
|
||||
after_assign17: ; preds = %after_check16, %assign_optional15, %assign_optional11, %optional_assign_jump6, %optional_assign_jump
|
||||
%11 = call i64 @"std_collections_map$int$int$.HashMap.get"(ptr %retparam20, ptr @test.m, i32 3)
|
||||
%not_err21 = icmp eq i64 %11, 0
|
||||
%12 = call i1 @llvm.expect.i1(i1 %not_err21, i1 true)
|
||||
br i1 %12, label %after_check23, label %assign_optional22
|
||||
after_assign14: ; preds = %after_check13, %assign_optional12
|
||||
%11 = call i64 @"std_collections_map$int$int$.HashMap.get"(ptr %retparam17, ptr @test.m, i32 3)
|
||||
%not_err18 = icmp eq i64 %11, 0
|
||||
%12 = call i1 @llvm.expect.i1(i1 %not_err18, i1 true)
|
||||
br i1 %12, label %after_check20, label %assign_optional19
|
||||
|
||||
assign_optional22: ; preds = %after_assign17
|
||||
store i64 %11, ptr %anon.f19, align 8
|
||||
br label %optional_assign_jump24
|
||||
assign_optional19: ; preds = %after_assign14
|
||||
store i64 %11, ptr %anon.f16, align 8
|
||||
br label %after_assign21
|
||||
|
||||
after_check23: ; preds = %after_assign17
|
||||
%13 = load i32, ptr %retparam20, align 4
|
||||
store i32 %13, ptr %.anon18, align 4
|
||||
store i64 0, ptr %anon.f19, align 8
|
||||
br label %after_assign26
|
||||
after_check20: ; preds = %after_assign14
|
||||
%13 = load i32, ptr %retparam17, align 4
|
||||
store i32 %13, ptr %.anon15, align 4
|
||||
store i64 0, ptr %anon.f16, align 8
|
||||
br label %after_assign21
|
||||
|
||||
optional_assign_jump24: ; preds = %assign_optional22
|
||||
%reload_err25 = load i64, ptr %anon.f19, align 8
|
||||
store i64 %reload_err25, ptr %x.f, align 8
|
||||
br label %after_assign44
|
||||
after_assign21: ; preds = %after_check20, %assign_optional19
|
||||
%optval24 = load i64, ptr %anon.f16, align 8
|
||||
%not_err25 = icmp eq i64 %optval24, 0
|
||||
%14 = call i1 @llvm.expect.i1(i1 %not_err25, i1 true)
|
||||
br i1 %14, label %after_check27, label %assign_optional26
|
||||
|
||||
after_assign26: ; preds = %after_check23
|
||||
%optval29 = load i64, ptr %anon.f19, align 8
|
||||
%not_err30 = icmp eq i64 %optval29, 0
|
||||
%14 = call i1 @llvm.expect.i1(i1 %not_err30, i1 true)
|
||||
br i1 %14, label %after_check32, label %assign_optional31
|
||||
assign_optional26: ; preds = %after_assign21
|
||||
store i64 %optval24, ptr %anon.f23, align 8
|
||||
br label %after_assign28
|
||||
|
||||
assign_optional31: ; preds = %after_assign26
|
||||
store i64 %optval29, ptr %anon.f28, align 8
|
||||
br label %optional_assign_jump33
|
||||
|
||||
after_check32: ; preds = %after_assign26
|
||||
%15 = load i32, ptr %.anon18, align 4
|
||||
after_check27: ; preds = %after_assign21
|
||||
%15 = load i32, ptr %.anon15, align 4
|
||||
%add = add i32 %15, 1
|
||||
store i32 %add, ptr %.anon18, align 4
|
||||
store i32 %add, ptr %.anon27, align 4
|
||||
store i64 0, ptr %anon.f28, align 8
|
||||
br label %after_assign35
|
||||
store i32 %add, ptr %.anon15, align 4
|
||||
store i32 %add, ptr %.anon22, align 4
|
||||
store i64 0, ptr %anon.f23, align 8
|
||||
br label %after_assign28
|
||||
|
||||
optional_assign_jump33: ; preds = %assign_optional31
|
||||
%reload_err34 = load i64, ptr %anon.f28, align 8
|
||||
store i64 %reload_err34, ptr %x.f, align 8
|
||||
br label %after_assign44
|
||||
after_assign28: ; preds = %after_check27, %assign_optional26
|
||||
%optval29 = load i64, ptr %anon.f16, align 8
|
||||
%not_err30 = icmp eq i64 %optval29, 0
|
||||
%16 = call i1 @llvm.expect.i1(i1 %not_err30, i1 true)
|
||||
br i1 %16, label %after_check31, label %voiderr32
|
||||
|
||||
after_assign35: ; preds = %after_check32
|
||||
%optval36 = load i64, ptr %anon.f19, align 8
|
||||
%not_err37 = icmp eq i64 %optval36, 0
|
||||
%16 = call i1 @llvm.expect.i1(i1 %not_err37, i1 true)
|
||||
br i1 %16, label %after_check39, label %assign_optional38
|
||||
|
||||
assign_optional38: ; preds = %after_assign35
|
||||
store i64 %optval36, ptr %x.f, align 8
|
||||
br label %after_assign44
|
||||
|
||||
after_check39: ; preds = %after_assign35
|
||||
%17 = load i32, ptr %.anon18, align 4
|
||||
after_check31: ; preds = %after_assign28
|
||||
%17 = load i32, ptr %.anon15, align 4
|
||||
%18 = call i8 @"std_collections_map$int$int$.HashMap.set"(ptr @test.m, i32 3, i32 %17)
|
||||
%optval40 = load i64, ptr %anon.f28, align 8
|
||||
%not_err41 = icmp eq i64 %optval40, 0
|
||||
%19 = call i1 @llvm.expect.i1(i1 %not_err41, i1 true)
|
||||
br i1 %19, label %after_check43, label %assign_optional42
|
||||
br label %voiderr32
|
||||
|
||||
assign_optional42: ; preds = %after_check39
|
||||
store i64 %optval40, ptr %x.f, align 8
|
||||
br label %after_assign44
|
||||
voiderr32: ; preds = %after_check31, %after_assign28
|
||||
%optval33 = load i64, ptr %anon.f23, align 8
|
||||
%not_err34 = icmp eq i64 %optval33, 0
|
||||
%19 = call i1 @llvm.expect.i1(i1 %not_err34, i1 true)
|
||||
br i1 %19, label %after_check36, label %assign_optional35
|
||||
|
||||
after_check43: ; preds = %after_check39
|
||||
%20 = load i32, ptr %.anon27, align 4
|
||||
assign_optional35: ; preds = %voiderr32
|
||||
store i64 %optval33, ptr %x.f, align 8
|
||||
br label %after_assign37
|
||||
|
||||
after_check36: ; preds = %voiderr32
|
||||
%20 = load i32, ptr %.anon22, align 4
|
||||
store i32 %20, ptr %x, align 4
|
||||
store i64 0, ptr %x.f, align 8
|
||||
br label %after_assign44
|
||||
br label %after_assign37
|
||||
|
||||
after_assign44: ; preds = %after_check43, %assign_optional42, %assign_optional38, %optional_assign_jump33, %optional_assign_jump24
|
||||
after_assign37: ; preds = %after_check36, %assign_optional35
|
||||
ret void
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user