Skip to content

Commit 6fece14

Browse files
committedDec 27, 2017
self-hosted: build against zig_llvm and embedded LLD
Now the self-hosted compiler re-uses the same C++ code for interfacing with LLVM as the C++ code. It also links against the same LLD library files.
·
0.15.20.2.0
1 parent 2a25398 commit 6fece14

File tree

22 files changed

+736
-461
lines changed

22 files changed

+736
-461
lines changed
 

‎CMakeLists.txt‎

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ option(ZIG_FORCE_EXTERNAL_LLD "If your system has the LLD patches use it instead
4949
find_package(llvm)
5050
find_package(clang)
5151

52+
set(ZIG_CPP_LIB_DIR "${CMAKE_BINARY_DIR}/zig_cpp")
53+
5254
if(ZIG_FORCE_EXTERNAL_LLD)
5355
find_package(lld)
5456
include_directories(${LLVM_INCLUDE_DIRS})
@@ -192,6 +194,7 @@ else()
192194
embedded_lld_coff
193195
embedded_lld_lib
194196
)
197+
install(TARGETS embedded_lld_elf embedded_lld_coff embedded_lld_lib DESTINATION "${ZIG_CPP_LIB_DIR}")
195198
endif()
196199

197200
# No patches have been applied to SoftFloat-3d
@@ -345,6 +348,8 @@ set(ZIG_SOURCES
345348
"${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"
346349
"${CMAKE_SOURCE_DIR}/src/util.cpp"
347350
"${CMAKE_SOURCE_DIR}/src/translate_c.cpp"
351+
)
352+
set(ZIG_CPP_SOURCES
348353
"${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp"
349354
)
350355

@@ -390,13 +395,16 @@ if(ZIG_TEST_COVERAGE)
390395
set(EXE_LDFLAGS "${EXE_LDFLAGS} -fprofile-arcs -ftest-coverage")
391396
endif()
392397

398+
add_library(zig_cpp STATIC ${ZIG_CPP_SOURCES})
399+
393400
add_executable(zig ${ZIG_SOURCES})
394401
set_target_properties(zig PROPERTIES
395402
COMPILE_FLAGS ${EXE_CFLAGS}
396403
LINK_FLAGS ${EXE_LDFLAGS}
397404
)
398405

399406
target_link_libraries(zig LINK_PUBLIC
407+
zig_cpp
400408
${SOFTFLOAT_LIBRARIES}
401409
${CLANG_LIBRARIES}
402410
${LLD_LIBRARIES}
@@ -407,6 +415,7 @@ if(MSVC OR MINGW)
407415
target_link_libraries(zig LINK_PUBLIC version)
408416
endif()
409417
install(TARGETS zig DESTINATION bin)
418+
install(TARGETS zig_cpp DESTINATION "${ZIG_CPP_LIB_DIR}")
410419

411420
install(FILES "${CMAKE_SOURCE_DIR}/c_headers/__clang_cuda_builtin_vars.h" DESTINATION "${C_HEADERS_DEST}")
412421
install(FILES "${CMAKE_SOURCE_DIR}/c_headers/__clang_cuda_cmath.h" DESTINATION "${C_HEADERS_DEST}")
@@ -619,16 +628,3 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/udivti3.zig" DESTINAT
619628
install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/umodti3.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt")
620629
install(FILES "${CMAKE_SOURCE_DIR}/std/special/panic.zig" DESTINATION "${ZIG_STD_DEST}/special")
621630
install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")
622-
623-
if (ZIG_TEST_COVERAGE)
624-
add_custom_target(coverage
625-
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
626-
COMMAND lcov --directory . --zerocounters --rc lcov_branch_coverage=1
627-
COMMAND ./zig build --build-file ../build.zig test
628-
COMMAND lcov --directory . --capture --output-file coverage.info --rc lcov_branch_coverage=1
629-
COMMAND lcov --remove coverage.info '/usr/*' --output-file coverage.info.cleaned --rc lcov_branch_coverage=1
630-
COMMAND genhtml -o coverage coverage.info.cleaned --rc lcov_branch_coverage=1
631-
COMMAND rm coverage.info coverage.info.cleaned
632-
)
633-
endif()
634-

‎README.md‎

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ clarity.
2626
always compiled against statically in source form. Compile units do not
2727
depend on libc unless explicitly linked.
2828
* Nullable type instead of null pointers.
29-
* Tagged union type instead of raw unions.
29+
* Safe unions, tagged unions, and C ABI compatible unions.
3030
* Generics so that one can write efficient data structures that work for any
3131
data type.
3232
* No header files required. Top level declarations are entirely
@@ -35,7 +35,7 @@ clarity.
3535
* Partial compile-time function evaluation with eliminates the need for
3636
a preprocessor or macros.
3737
* The binaries produced by Zig have complete debugging information so you can,
38-
for example, use GDB to debug your software.
38+
for example, use GDB or MSVC to debug your software.
3939
* Built-in unit tests with `zig test`.
4040
* Friendly toward package maintainers. Reproducible build, bootstrapping
4141
process carefully documented. Issues filed by package maintainers are
@@ -78,10 +78,10 @@ that counts as "freestanding" for the purposes of this table.
7878

7979
### Wanted: Windows Developers
8080

81-
Help get the tests passing on Windows, flesh out the standard library for
82-
Windows, streamline Zig installation and distribution for Windows. Work with
83-
LLVM and LLD teams to improve PDB/CodeView/MSVC debugging. Implement stack traces
84-
for Windows in the MinGW environment and the MSVC environment.
81+
Flesh out the standard library for Windows, streamline Zig installation and
82+
distribution for Windows. Work with LLVM and LLD teams to improve
83+
PDB/CodeView/MSVC debugging. Implement stack traces for Windows in the MinGW
84+
environment and the MSVC environment.
8585

8686
### Wanted: MacOS and iOS Developers
8787

@@ -178,6 +178,10 @@ Dependencies are the same as Stage 1, except now you have a working zig compiler
178178
bin/zig build --build-file ../build.zig --prefix $(pwd)/stage2 install
179179
```
180180

181+
This produces `./stage2/bin/zig` which can be used for testing and development.
182+
Once it is feature complete, it will be used to build stage 3 - the final compiler
183+
binary.
184+
181185
### Stage 3: Rebuild Self-Hosted Zig Using the Self-Hosted Compiler
182186

183187
This is the actual compiler binary that we will install to the system.
@@ -194,20 +198,6 @@ This is the actual compiler binary that we will install to the system.
194198
./stage2/bin/zig build --build-file ../build.zig install -Drelease-fast
195199
```
196200

197-
### Test Coverage
198-
199-
To see test coverage in Zig, configure with `-DZIG_TEST_COVERAGE=ON` as an
200-
additional parameter to the Debug build.
201-
202-
You must have `lcov` installed and available.
203-
204-
Then `make coverage`.
205-
206-
With GCC you will get a nice HTML view of the coverage data. With clang,
207-
the last step will fail, but you can execute
208-
`llvm-cov gcov $(find CMakeFiles/ -name "*.gcda")` and then inspect the
209-
produced .gcov files.
210-
211201
### Related Projects
212202

213203
* [zig-mode](https://github.com/AndreaOrru/zig-mode) - Emacs integration

‎build.zig‎

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const builtin = @import("builtin");
12
const std = @import("std");
23
const Builder = std.build.Builder;
34
const tests = @import("test/tests.zig");
@@ -33,11 +34,32 @@ pub fn build(b: &Builder) {
3334
docs_step.dependOn(&docgen_home_cmd.step);
3435

3536
if (findLLVM(b)) |llvm| {
37+
// find the stage0 build artifacts because we're going to re-use config.h and zig_cpp library
38+
const build_info = b.exec([][]const u8{b.zig_exe, "BUILD_INFO"});
39+
var build_info_it = mem.split(build_info, "\n");
40+
const cmake_binary_dir = ??build_info_it.next();
41+
const cxx_compiler = ??build_info_it.next();
42+
3643
var exe = b.addExecutable("zig", "src-self-hosted/main.zig");
3744
exe.setBuildMode(mode);
38-
exe.linkSystemLibrary("c");
45+
exe.addIncludeDir("src");
46+
exe.addIncludeDir(cmake_binary_dir);
47+
addCppLib(b, exe, cmake_binary_dir, "libzig_cpp");
48+
addCppLib(b, exe, cmake_binary_dir, "libembedded_lld_elf");
49+
addCppLib(b, exe, cmake_binary_dir, "libembedded_lld_coff");
50+
addCppLib(b, exe, cmake_binary_dir, "libembedded_lld_lib");
3951
dependOnLib(exe, llvm);
4052

53+
if (!exe.target.isWindows()) {
54+
const libstdcxx_path_padded = b.exec([][]const u8{cxx_compiler, "-print-file-name=libstdc++.a"});
55+
const libstdcxx_path = ??mem.split(libstdcxx_path_padded, "\n").next();
56+
exe.addObjectFile(libstdcxx_path);
57+
58+
exe.linkSystemLibrary("pthread");
59+
}
60+
61+
exe.linkSystemLibrary("c");
62+
4163
b.default_step.dependOn(&exe.step);
4264
b.default_step.dependOn(docs_step);
4365

@@ -91,6 +113,11 @@ fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) {
91113
}
92114
}
93115

116+
fn addCppLib(b: &Builder, lib_exe_obj: &std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) {
117+
lib_exe_obj.addObjectFile(%%os.path.join(b.allocator, cmake_binary_dir, "zig_cpp",
118+
b.fmt("{}{}", lib_name, lib_exe_obj.target.libFileExt())));
119+
}
120+
94121
const LibraryDep = struct {
95122
libdirs: ArrayList([]const u8),
96123
libs: ArrayList([]const u8),

‎src-self-hosted/c.zig‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
pub use @cImport({
2-
@cInclude("llvm-c/Core.h");
3-
@cInclude("llvm-c/Analysis.h");
4-
@cInclude("llvm-c/Target.h");
5-
@cInclude("llvm-c/Initialization.h");
6-
@cInclude("llvm-c/TargetMachine.h");
2+
@cInclude("config.h");
3+
@cInclude("zig_llvm.h");
74
});

‎src-self-hosted/ir.zig‎

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
const Scope = @import("scope.zig").Scope;
2+
3+
pub const Instruction = struct {
4+
id: Id,
5+
scope: &Scope,
6+
7+
pub const Id = enum {
8+
Br,
9+
CondBr,
10+
SwitchBr,
11+
SwitchVar,
12+
SwitchTarget,
13+
Phi,
14+
UnOp,
15+
BinOp,
16+
DeclVar,
17+
LoadPtr,
18+
StorePtr,
19+
FieldPtr,
20+
StructFieldPtr,
21+
UnionFieldPtr,
22+
ElemPtr,
23+
VarPtr,
24+
Call,
25+
Const,
26+
Return,
27+
Cast,
28+
ContainerInitList,
29+
ContainerInitFields,
30+
StructInit,
31+
UnionInit,
32+
Unreachable,
33+
TypeOf,
34+
ToPtrType,
35+
PtrTypeChild,
36+
SetDebugSafety,
37+
SetFloatMode,
38+
ArrayType,
39+
SliceType,
40+
Asm,
41+
SizeOf,
42+
TestNonNull,
43+
UnwrapMaybe,
44+
MaybeWrap,
45+
UnionTag,
46+
Clz,
47+
Ctz,
48+
Import,
49+
CImport,
50+
CInclude,
51+
CDefine,
52+
CUndef,
53+
ArrayLen,
54+
Ref,
55+
MinValue,
56+
MaxValue,
57+
CompileErr,
58+
CompileLog,
59+
ErrName,
60+
EmbedFile,
61+
Cmpxchg,
62+
Fence,
63+
Truncate,
64+
IntType,
65+
BoolNot,
66+
Memset,
67+
Memcpy,
68+
Slice,
69+
MemberCount,
70+
MemberType,
71+
MemberName,
72+
Breakpoint,
73+
ReturnAddress,
74+
FrameAddress,
75+
AlignOf,
76+
OverflowOp,
77+
TestErr,
78+
UnwrapErrCode,
79+
UnwrapErrPayload,
80+
ErrWrapCode,
81+
ErrWrapPayload,
82+
FnProto,
83+
TestComptime,
84+
PtrCast,
85+
BitCast,
86+
WidenOrShorten,
87+
IntToPtr,
88+
PtrToInt,
89+
IntToEnum,
90+
IntToErr,
91+
ErrToInt,
92+
CheckSwitchProngs,
93+
CheckStatementIsVoid,
94+
TypeName,
95+
CanImplicitCast,
96+
DeclRef,
97+
Panic,
98+
TagName,
99+
TagType,
100+
FieldParentPtr,
101+
OffsetOf,
102+
TypeId,
103+
SetEvalBranchQuota,
104+
PtrTypeOf,
105+
AlignCast,
106+
OpaqueType,
107+
SetAlignStack,
108+
ArgType,
109+
Export,
110+
};
111+
112+
};

‎src-self-hosted/main.zig‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const ErrColor = Module.ErrColor;
1212
const Emit = Module.Emit;
1313
const builtin = @import("builtin");
1414
const ArrayList = std.ArrayList;
15+
const c = @import("c.zig");
1516

1617
error InvalidCommandLineArguments;
1718
error ZigLibDirNotFound;
@@ -462,7 +463,11 @@ pub fn main2() -> %void {
462463
else => unreachable,
463464
}
464465
},
465-
Cmd.Version => @panic("TODO zig version"),
466+
Cmd.Version => {
467+
var stdout_file = %return io.getStdErr();
468+
%return stdout_file.write(std.cstr.toSliceConst(c.ZIG_VERSION_STRING));
469+
%return stdout_file.write("\n");
470+
},
466471
Cmd.Targets => @panic("TODO zig targets"),
467472
}
468473
}

‎src-self-hosted/module.zig‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,13 @@ pub const Module = struct {
199199
}
200200

201201
pub fn build(self: &Module) -> %void {
202+
if (self.llvm_argv.len != 0) {
203+
var c_compatible_args = %return std.cstr.NullTerminated2DArray.fromSlices(self.allocator,
204+
[][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, });
205+
defer c_compatible_args.deinit();
206+
c.ZigLLVMParseCommandLineOptions(self.llvm_argv.len + 1, c_compatible_args.ptr);
207+
}
208+
202209
const root_src_path = self.root_src_path ?? @panic("TODO handle null root src path");
203210
const root_src_real_path = os.path.real(self.allocator, root_src_path) %% |err| {
204211
%return printError("unable to open '{}': {}", root_src_path, err);

‎src-self-hosted/scope.zig‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
pub const Scope = struct {
2+
id: Id,
3+
parent: &Scope,
4+
5+
pub const Id = enum {
6+
Decls,
7+
Block,
8+
Defer,
9+
DeferExpr,
10+
VarDecl,
11+
CImport,
12+
Loop,
13+
FnDef,
14+
CompTime,
15+
};
16+
};

‎src/all_types.hpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#include "list.hpp"
1212
#include "buffer.hpp"
13-
#include "zig_llvm.hpp"
13+
#include "zig_llvm.h"
1414
#include "hash_map.hpp"
1515
#include "errmsg.hpp"
1616
#include "bigint.hpp"

‎src/analyze.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include "os.hpp"
1515
#include "parser.hpp"
1616
#include "softfloat.hpp"
17-
#include "zig_llvm.hpp"
17+
#include "zig_llvm.h"
1818

1919

2020
static const size_t default_backward_branch_quota = 1000;

‎src/codegen.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "os.hpp"
1818
#include "translate_c.hpp"
1919
#include "target.hpp"
20-
#include "zig_llvm.hpp"
20+
#include "zig_llvm.h"
2121

2222
#include <stdio.h>
2323
#include <errno.h>

‎src/config.h.in‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,8 @@
2424
// Only used for running tests before installing.
2525
#define ZIG_TEST_DIR "@CMAKE_SOURCE_DIR@/test"
2626

27+
// Used for communicating build information to self hosted build.
28+
#define ZIG_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@"
29+
#define ZIG_CXX_COMPILER "@CMAKE_CXX_COMPILER@"
30+
2731
#endif

‎src/link.cpp‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,16 @@ static void coff_append_machine_arg(CodeGen *g, ZigList<const char *> *list) {
351351
}
352352
}
353353

354+
static void link_diag_callback(void *context, const char *ptr, size_t len) {
355+
Buf *diag = reinterpret_cast<Buf *>(context);
356+
buf_append_mem(diag, ptr, len);
357+
}
358+
359+
static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag) {
360+
buf_resize(diag, 0);
361+
return ZigLLDLink(oformat, args, arg_count, link_diag_callback, diag);
362+
}
363+
354364
static void construct_linker_job_coff(LinkJob *lj) {
355365
CodeGen *g = lj->codegen;
356366

@@ -515,7 +525,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
515525
gen_lib_args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path))));
516526
gen_lib_args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(generated_lib_path))));
517527
Buf diag = BUF_INIT;
518-
if (!ZigLLDLink(g->zig_target.oformat, gen_lib_args.items, gen_lib_args.length, &diag)) {
528+
if (!zig_lld_link(g->zig_target.oformat, gen_lib_args.items, gen_lib_args.length, &diag)) {
519529
fprintf(stderr, "%s\n", buf_ptr(&diag));
520530
exit(1);
521531
}
@@ -930,7 +940,7 @@ void codegen_link(CodeGen *g, const char *out_file) {
930940
Buf diag = BUF_INIT;
931941

932942
codegen_add_time_event(g, "LLVM Link");
933-
if (!ZigLLDLink(g->zig_target.oformat, lj.args.items, lj.args.length, &diag)) {
943+
if (!zig_lld_link(g->zig_target.oformat, lj.args.items, lj.args.length, &diag)) {
934944
fprintf(stderr, "%s\n", buf_ptr(&diag));
935945
exit(1);
936946
}

‎src/main.cpp‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,11 @@ static void add_package(CodeGen *g, CliPkg *cli_pkg, PackageTableEntry *pkg) {
266266
}
267267

268268
int main(int argc, char **argv) {
269+
if (argc == 2 && strcmp(argv[1], "BUILD_INFO") == 0) {
270+
printf("%s\n%s\n", ZIG_CMAKE_BINARY_DIR, ZIG_CXX_COMPILER);
271+
return 0;
272+
}
273+
269274
os_init();
270275

271276
char *arg0 = argv[0];

‎src/os.hpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include "list.hpp"
1212
#include "buffer.hpp"
1313
#include "error.hpp"
14-
#include "zig_llvm.hpp"
14+
#include "zig_llvm.h"
1515

1616
#include <stdio.h>
1717
#include <inttypes.h>

‎src/target.hpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#ifndef ZIG_TARGET_HPP
99
#define ZIG_TARGET_HPP
1010

11-
#include <zig_llvm.hpp>
11+
#include <zig_llvm.h>
1212

1313
struct Buf;
1414

‎src/util.hpp‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
#include <string.h>
1414
#include <assert.h>
1515

16-
#include <new>
17-
1816
#if defined(_MSC_VER)
1917

2018
#include <intrin.h>

‎src/zig_llvm.cpp‎

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* 3. Prevent C++ from infecting the rest of the project.
1414
*/
1515

16-
#include "zig_llvm.hpp"
16+
#include "zig_llvm.h"
1717

1818
#include <llvm/Analysis/TargetLibraryInfo.h>
1919
#include <llvm/Analysis/TargetTransformInfo.h>
@@ -39,8 +39,35 @@
3939

4040
#include <lld/Driver/Driver.h>
4141

42+
#include <new>
43+
44+
#include <stdlib.h>
45+
46+
#if defined(_MSC_VER)
47+
#define ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
48+
#else
49+
#define ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
50+
#endif
51+
4252
using namespace llvm;
4353

54+
template<typename T, typename... Args>
55+
ATTRIBUTE_RETURNS_NOALIAS static inline T * create(Args... args) {
56+
T * ptr = reinterpret_cast<T*>(malloc(sizeof(T)));
57+
if (ptr == nullptr)
58+
return nullptr;
59+
new (ptr) T(args...);
60+
return ptr;
61+
}
62+
63+
template<typename T>
64+
static inline void destroy(T * ptr) {
65+
if (ptr != nullptr) {
66+
ptr[0].~T();
67+
}
68+
free(ptr);
69+
}
70+
4471
void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) {
4572
initializeLoopStrengthReducePass(*unwrap(R));
4673
}
@@ -50,8 +77,7 @@ void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R) {
5077
}
5178

5279
char *ZigLLVMGetHostCPUName(void) {
53-
std::string str = sys::getHostCPUName();
54-
return strdup(str.c_str());
80+
return strdup((const char *)sys::getHostCPUName().bytes_begin());
5581
}
5682

5783
char *ZigLLVMGetNativeFeatures(void) {
@@ -63,11 +89,11 @@ char *ZigLLVMGetNativeFeatures(void) {
6389
features.AddFeature(F.first(), F.second);
6490
}
6591

66-
return strdup(features.getString().c_str());
92+
return strdup((const char *)StringRef(features.getString()).bytes_begin());
6793
}
6894

6995
static void addDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) {
70-
PM.add(createAddDiscriminatorsPass());
96+
PM.add(createAddDiscriminatorsPass());
7197
}
7298

7399
#ifndef NDEBUG
@@ -82,15 +108,15 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
82108
std::error_code EC;
83109
raw_fd_ostream dest(filename, EC, sys::fs::F_None);
84110
if (EC) {
85-
*error_message = strdup(EC.message().c_str());
111+
*error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
86112
return true;
87113
}
88114
TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);
89115
target_machine->setO0WantsFastISel(true);
90116

91117
Module* module = unwrap(module_ref);
92118

93-
PassManagerBuilder *PMBuilder = new PassManagerBuilder();
119+
PassManagerBuilder *PMBuilder = create<PassManagerBuilder>();
94120
PMBuilder->OptLevel = target_machine->getOptLevel();
95121
PMBuilder->SizeLevel = 0;
96122

@@ -123,7 +149,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
123149

124150
// Set up the per-function pass manager.
125151
legacy::FunctionPassManager FPM = legacy::FunctionPassManager(module);
126-
FPM.add(new TargetLibraryInfoWrapperPass(tlii));
152+
FPM.add(create<TargetLibraryInfoWrapperPass>(tlii));
127153
FPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));
128154
if (assertions_on) {
129155
FPM.add(createVerifierPass());
@@ -415,7 +441,10 @@ unsigned ZigLLVMTag_DW_union_type(void) {
415441
}
416442

417443
ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) {
418-
DIBuilder *di_builder = new DIBuilder(*unwrap(module), allow_unresolved);
444+
DIBuilder *di_builder = reinterpret_cast<DIBuilder*>(malloc(sizeof(DIBuilder)));
445+
if (di_builder == nullptr)
446+
return nullptr;
447+
new (di_builder) DIBuilder(*unwrap(module), allow_unresolved);
419448
return reinterpret_cast<ZigLLVMDIBuilder *>(di_builder);
420449
}
421450

@@ -617,7 +646,7 @@ void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn_ref) {
617646
func->setAttributes(new_attr_set);
618647
}
619648

620-
void ZigLLVMParseCommandLineOptions(int argc, const char *const *argv) {
649+
void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) {
621650
llvm::cl::ParseCommandLineOptions(argc, argv);
622651
}
623652

@@ -771,29 +800,35 @@ LLVMValueRef ZigLLVMBuildAShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLV
771800
}
772801

773802

774-
#include "buffer.hpp"
803+
class MyOStream: public raw_ostream {
804+
public:
805+
MyOStream(void (*_append_diagnostic)(void *, const char *, size_t), void *_context) :
806+
raw_ostream(true), append_diagnostic(_append_diagnostic), context(_context), pos(0) {
807+
808+
}
809+
void write_impl(const char *ptr, size_t len) override {
810+
append_diagnostic(context, ptr, len);
811+
pos += len;
812+
}
813+
uint64_t current_pos() const override {
814+
return pos;
815+
}
816+
void (*append_diagnostic)(void *, const char *, size_t);
817+
void *context;
818+
size_t pos;
819+
};
820+
775821

776-
bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag_buf) {
822+
bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count,
823+
void (*append_diagnostic)(void *, const char *, size_t), void *context)
824+
{
777825
ArrayRef<const char *> array_ref_args(args, arg_count);
778826

779-
buf_resize(diag_buf, 0);
780-
class MyOStream: public raw_ostream {
781-
public:
782-
MyOStream(Buf *_diag_buf) : raw_ostream(true), diag_buf(_diag_buf) {
783-
784-
}
785-
void write_impl(const char *ptr, size_t len) override {
786-
buf_append_mem(diag_buf, ptr, len);
787-
}
788-
uint64_t current_pos() const override {
789-
return buf_len(diag_buf);
790-
}
791-
Buf *diag_buf;
792-
} diag(diag_buf);
827+
MyOStream diag(append_diagnostic, context);
793828

794829
switch (oformat) {
795830
case ZigLLVM_UnknownObjectFormat:
796-
zig_unreachable();
831+
assert(false); // unreachable
797832

798833
case ZigLLVM_COFF:
799834
return lld::coff::link(array_ref_args, false, diag);
@@ -805,7 +840,8 @@ bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_
805840
return lld::mach_o::link(array_ref_args, diag);
806841

807842
case ZigLLVM_Wasm:
808-
zig_panic("ZigLLDLink for Wasm");
843+
assert(false); // TODO ZigLLDLink for Wasm
809844
}
810-
zig_unreachable();
845+
assert(false); // unreachable
846+
abort();
811847
}

‎src/zig_llvm.h‎

Lines changed: 394 additions & 0 deletions
Large diffs are not rendered by default.

‎src/zig_llvm.hpp‎

Lines changed: 0 additions & 383 deletions
This file was deleted.

‎std/build.zig‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,13 @@ const Target = union(enum) {
784784
};
785785
}
786786

787+
pub fn libFileExt(self: &const Target) -> []const u8 {
788+
return switch (self.getOs()) {
789+
builtin.Os.windows => ".lib",
790+
else => ".a",
791+
};
792+
}
793+
787794
pub fn getOs(self: &const Target) -> builtin.Os {
788795
return switch (*self) {
789796
Target.Native => builtin.os,

‎std/cstr.zig‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,57 @@ pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) -> %[]u8 {
4848
result[slice.len] = 0;
4949
return result;
5050
}
51+
52+
pub const NullTerminated2DArray = struct {
53+
allocator: &mem.Allocator,
54+
byte_count: usize,
55+
ptr: ?&?&u8,
56+
57+
/// Takes N lists of strings, concatenates the lists together, and adds a null terminator
58+
/// Caller must deinit result
59+
pub fn fromSlices(allocator: &mem.Allocator, slices: []const []const []const u8) -> %NullTerminated2DArray {
60+
var new_len: usize = 1; // 1 for the list null
61+
var byte_count: usize = 0;
62+
for (slices) |slice| {
63+
new_len += slice.len;
64+
for (slice) |inner| {
65+
byte_count += inner.len;
66+
}
67+
byte_count += slice.len; // for the null terminators of inner
68+
}
69+
70+
const index_size = @sizeOf(usize) * new_len; // size of the ptrs
71+
byte_count += index_size;
72+
73+
const buf = %return allocator.alignedAlloc(u8, @alignOf(?&u8), byte_count);
74+
%defer allocator.free(buf);
75+
76+
var write_index = index_size;
77+
const index_buf = ([]?&u8)(buf);
78+
79+
var i: usize = 0;
80+
for (slices) |slice| {
81+
for (slice) |inner| {
82+
index_buf[i] = &buf[write_index];
83+
i += 1;
84+
mem.copy(u8, buf[write_index..], inner);
85+
write_index += inner.len;
86+
buf[write_index] = 0;
87+
write_index += 1;
88+
}
89+
}
90+
index_buf[i] = null;
91+
92+
return NullTerminated2DArray {
93+
.allocator = allocator,
94+
.byte_count = byte_count,
95+
.ptr = @ptrCast(?&?&u8, buf.ptr),
96+
};
97+
}
98+
99+
pub fn deinit(self: &NullTerminated2DArray) {
100+
const buf = @ptrCast(&u8, self.ptr);
101+
self.allocator.free(buf[0..self.byte_count]);
102+
}
103+
};
104+

0 commit comments

Comments
 (0)
Please sign in to comment.