diff --git a/CMakeLists.txt b/CMakeLists.txt index d8e2d9ff7a..1cf2f2d8e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,8 @@ option(ZIG_FORCE_EXTERNAL_LLD "If your system has the LLD patches use it instead find_package(llvm) find_package(clang) +set(ZIG_CPP_LIB_DIR "${CMAKE_BINARY_DIR}/zig_cpp") + if(ZIG_FORCE_EXTERNAL_LLD) find_package(lld) include_directories(${LLVM_INCLUDE_DIRS}) @@ -192,6 +194,7 @@ else() embedded_lld_coff embedded_lld_lib ) + install(TARGETS embedded_lld_elf embedded_lld_coff embedded_lld_lib DESTINATION "${ZIG_CPP_LIB_DIR}") endif() # No patches have been applied to SoftFloat-3d @@ -345,6 +348,8 @@ set(ZIG_SOURCES "${CMAKE_SOURCE_DIR}/src/tokenizer.cpp" "${CMAKE_SOURCE_DIR}/src/util.cpp" "${CMAKE_SOURCE_DIR}/src/translate_c.cpp" +) +set(ZIG_CPP_SOURCES "${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp" ) @@ -390,6 +395,11 @@ if(ZIG_TEST_COVERAGE) set(EXE_LDFLAGS "${EXE_LDFLAGS} -fprofile-arcs -ftest-coverage") endif() +add_library(zig_cpp STATIC ${ZIG_CPP_SOURCES}) +set_target_properties(zig_cpp PROPERTIES + COMPILE_FLAGS ${EXE_CFLAGS} +) + add_executable(zig ${ZIG_SOURCES}) set_target_properties(zig PROPERTIES COMPILE_FLAGS ${EXE_CFLAGS} @@ -397,6 +407,7 @@ set_target_properties(zig PROPERTIES ) target_link_libraries(zig LINK_PUBLIC + zig_cpp ${SOFTFLOAT_LIBRARIES} ${CLANG_LIBRARIES} ${LLD_LIBRARIES} @@ -407,6 +418,7 @@ if(MSVC OR MINGW) target_link_libraries(zig LINK_PUBLIC version) endif() install(TARGETS zig DESTINATION bin) +install(TARGETS zig_cpp DESTINATION "${ZIG_CPP_LIB_DIR}") install(FILES "${CMAKE_SOURCE_DIR}/c_headers/__clang_cuda_builtin_vars.h" DESTINATION "${C_HEADERS_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/c_headers/__clang_cuda_cmath.h" DESTINATION "${C_HEADERS_DEST}") @@ -516,7 +528,8 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/c/index.zig" DESTINATION "${ZIG_STD_DEST} install(FILES "${CMAKE_SOURCE_DIR}/std/c/linux.zig" DESTINATION "${ZIG_STD_DEST}/c") install(FILES "${CMAKE_SOURCE_DIR}/std/c/windows.zig" DESTINATION "${ZIG_STD_DEST}/c") install(FILES "${CMAKE_SOURCE_DIR}/std/cstr.zig" DESTINATION "${ZIG_STD_DEST}") -install(FILES "${CMAKE_SOURCE_DIR}/std/debug.zig" DESTINATION "${ZIG_STD_DEST}") +install(FILES "${CMAKE_SOURCE_DIR}/std/debug/index.zig" DESTINATION "${ZIG_STD_DEST}/debug") +install(FILES "${CMAKE_SOURCE_DIR}/std/debug/failing_allocator.zig" DESTINATION "${ZIG_STD_DEST}/debug") install(FILES "${CMAKE_SOURCE_DIR}/std/dwarf.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/elf.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/empty.zig" DESTINATION "${ZIG_STD_DEST}") @@ -618,16 +631,3 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/udivti3.zig" DESTINAT install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/umodti3.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") install(FILES "${CMAKE_SOURCE_DIR}/std/special/panic.zig" DESTINATION "${ZIG_STD_DEST}/special") install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") - -if (ZIG_TEST_COVERAGE) - add_custom_target(coverage - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMAND lcov --directory . --zerocounters --rc lcov_branch_coverage=1 - COMMAND ./zig build --build-file ../build.zig test - COMMAND lcov --directory . --capture --output-file coverage.info --rc lcov_branch_coverage=1 - COMMAND lcov --remove coverage.info '/usr/*' --output-file coverage.info.cleaned --rc lcov_branch_coverage=1 - COMMAND genhtml -o coverage coverage.info.cleaned --rc lcov_branch_coverage=1 - COMMAND rm coverage.info coverage.info.cleaned - ) -endif() - diff --git a/README.md b/README.md index 7598c623c3..9143837299 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ clarity. always compiled against statically in source form. Compile units do not depend on libc unless explicitly linked. * Nullable type instead of null pointers. - * Tagged union type instead of raw unions. + * Safe unions, tagged unions, and C ABI compatible unions. * Generics so that one can write efficient data structures that work for any data type. * No header files required. Top level declarations are entirely @@ -35,7 +35,7 @@ clarity. * Partial compile-time function evaluation with eliminates the need for a preprocessor or macros. * The binaries produced by Zig have complete debugging information so you can, - for example, use GDB to debug your software. + for example, use GDB or MSVC to debug your software. * Built-in unit tests with `zig test`. * Friendly toward package maintainers. Reproducible build, bootstrapping process carefully documented. Issues filed by package maintainers are @@ -78,10 +78,10 @@ that counts as "freestanding" for the purposes of this table. ### Wanted: Windows Developers -Help get the tests passing on Windows, flesh out the standard library for -Windows, streamline Zig installation and distribution for Windows. Work with -LLVM and LLD teams to improve PDB/CodeView/MSVC debugging. Implement stack traces -for Windows in the MinGW environment and the MSVC environment. +Flesh out the standard library for Windows, streamline Zig installation and +distribution for Windows. Work with LLVM and LLD teams to improve +PDB/CodeView/MSVC debugging. Implement stack traces for Windows in the MinGW +environment and the MSVC environment. ### Wanted: MacOS and iOS Developers @@ -178,6 +178,10 @@ Dependencies are the same as Stage 1, except now you have a working zig compiler bin/zig build --build-file ../build.zig --prefix $(pwd)/stage2 install ``` +This produces `./stage2/bin/zig` which can be used for testing and development. +Once it is feature complete, it will be used to build stage 3 - the final compiler +binary. + ### Stage 3: Rebuild Self-Hosted Zig Using the Self-Hosted Compiler 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. ./stage2/bin/zig build --build-file ../build.zig install -Drelease-fast ``` -### Test Coverage - -To see test coverage in Zig, configure with `-DZIG_TEST_COVERAGE=ON` as an -additional parameter to the Debug build. - -You must have `lcov` installed and available. - -Then `make coverage`. - -With GCC you will get a nice HTML view of the coverage data. With clang, -the last step will fail, but you can execute -`llvm-cov gcov $(find CMakeFiles/ -name "*.gcda")` and then inspect the -produced .gcov files. - ### Related Projects * [zig-mode](https://github.com/AndreaOrru/zig-mode) - Emacs integration diff --git a/build.zig b/build.zig index dbb54f8c3e..cfc83cf424 100644 --- a/build.zig +++ b/build.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("std"); const Builder = std.build.Builder; const tests = @import("test/tests.zig"); @@ -33,11 +34,32 @@ pub fn build(b: &Builder) { docs_step.dependOn(&docgen_home_cmd.step); if (findLLVM(b)) |llvm| { + // find the stage0 build artifacts because we're going to re-use config.h and zig_cpp library + const build_info = b.exec([][]const u8{b.zig_exe, "BUILD_INFO"}); + var build_info_it = mem.split(build_info, "\n"); + const cmake_binary_dir = ??build_info_it.next(); + const cxx_compiler = ??build_info_it.next(); + var exe = b.addExecutable("zig", "src-self-hosted/main.zig"); exe.setBuildMode(mode); - exe.linkSystemLibrary("c"); + exe.addIncludeDir("src"); + exe.addIncludeDir(cmake_binary_dir); + addCppLib(b, exe, cmake_binary_dir, "libzig_cpp"); + addCppLib(b, exe, cmake_binary_dir, "libembedded_lld_elf"); + addCppLib(b, exe, cmake_binary_dir, "libembedded_lld_coff"); + addCppLib(b, exe, cmake_binary_dir, "libembedded_lld_lib"); dependOnLib(exe, llvm); + if (!exe.target.isWindows()) { + const libstdcxx_path_padded = b.exec([][]const u8{cxx_compiler, "-print-file-name=libstdc++.a"}); + const libstdcxx_path = ??mem.split(libstdcxx_path_padded, "\n").next(); + exe.addObjectFile(libstdcxx_path); + + exe.linkSystemLibrary("pthread"); + } + + exe.linkSystemLibrary("c"); + b.default_step.dependOn(&exe.step); b.default_step.dependOn(docs_step); @@ -91,6 +113,11 @@ fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) { } } +fn addCppLib(b: &Builder, lib_exe_obj: &std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) { + lib_exe_obj.addObjectFile(%%os.path.join(b.allocator, cmake_binary_dir, "zig_cpp", + b.fmt("{}{}", lib_name, lib_exe_obj.target.libFileExt()))); +} + const LibraryDep = struct { libdirs: ArrayList([]const u8), libs: ArrayList([]const u8), @@ -172,7 +199,8 @@ pub fn installStdLib(b: &Builder) { "c/linux.zig", "c/windows.zig", "cstr.zig", - "debug.zig", + "debug/failing_allocator.zig", + "debug/index.zig", "dwarf.zig", "elf.zig", "empty.zig", diff --git a/doc/langref.html.in b/doc/langref.html.in index 162c8b3e03..c35e326254 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -291,6 +291,15 @@ pub fn main() -> %void {
  • Errors
  • Root Source File
  • +

    Source encoding

    +

    Zig source code is encoded in UTF-8. An invalid UTF-8 byte sequence results in a compile error.

    +

    Throughout all zig source code (including in comments), some codepoints are never allowed:

    + +

    The codepoint U+000a (LF) (which is encoded as the single-byte value 0x0a) is the line terminator character. This character always terminates a line of zig source code. A non-empty zig source must end with the line terminator character.

    +

    For some discussion on the rationale behind these design decisions, see issue #663

    Values

    const warn = @import("std").debug.warn;
     const os = @import("std").os;
    diff --git a/src-self-hosted/c.zig b/src-self-hosted/c.zig
    index b7e057b941..9a4b56adea 100644
    --- a/src-self-hosted/c.zig
    +++ b/src-self-hosted/c.zig
    @@ -1,7 +1,4 @@
     pub use @cImport({
    -    @cInclude("llvm-c/Core.h");
    -    @cInclude("llvm-c/Analysis.h");
    -    @cInclude("llvm-c/Target.h");
    -    @cInclude("llvm-c/Initialization.h");
    -    @cInclude("llvm-c/TargetMachine.h");
    +    @cInclude("config.h");
    +    @cInclude("zig_llvm.h");
     });
    diff --git a/src-self-hosted/ir.zig b/src-self-hosted/ir.zig
    new file mode 100644
    index 0000000000..b25bb183c5
    --- /dev/null
    +++ b/src-self-hosted/ir.zig
    @@ -0,0 +1,112 @@
    +const Scope = @import("scope.zig").Scope;
    +
    +pub const Instruction = struct {
    +    id: Id,
    +    scope: &Scope,
    +
    +    pub const Id = enum {
    +        Br,
    +        CondBr,
    +        SwitchBr,
    +        SwitchVar,
    +        SwitchTarget,
    +        Phi,
    +        UnOp,
    +        BinOp,
    +        DeclVar,
    +        LoadPtr,
    +        StorePtr,
    +        FieldPtr,
    +        StructFieldPtr,
    +        UnionFieldPtr,
    +        ElemPtr,
    +        VarPtr,
    +        Call,
    +        Const,
    +        Return,
    +        Cast,
    +        ContainerInitList,
    +        ContainerInitFields,
    +        StructInit,
    +        UnionInit,
    +        Unreachable,
    +        TypeOf,
    +        ToPtrType,
    +        PtrTypeChild,
    +        SetDebugSafety,
    +        SetFloatMode,
    +        ArrayType,
    +        SliceType,
    +        Asm,
    +        SizeOf,
    +        TestNonNull,
    +        UnwrapMaybe,
    +        MaybeWrap,
    +        UnionTag,
    +        Clz,
    +        Ctz,
    +        Import,
    +        CImport,
    +        CInclude,
    +        CDefine,
    +        CUndef,
    +        ArrayLen,
    +        Ref,
    +        MinValue,
    +        MaxValue,
    +        CompileErr,
    +        CompileLog,
    +        ErrName,
    +        EmbedFile,
    +        Cmpxchg,
    +        Fence,
    +        Truncate,
    +        IntType,
    +        BoolNot,
    +        Memset,
    +        Memcpy,
    +        Slice,
    +        MemberCount,
    +        MemberType,
    +        MemberName,
    +        Breakpoint,
    +        ReturnAddress,
    +        FrameAddress,
    +        AlignOf,
    +        OverflowOp,
    +        TestErr,
    +        UnwrapErrCode,
    +        UnwrapErrPayload,
    +        ErrWrapCode,
    +        ErrWrapPayload,
    +        FnProto,
    +        TestComptime,
    +        PtrCast,
    +        BitCast,
    +        WidenOrShorten,
    +        IntToPtr,
    +        PtrToInt,
    +        IntToEnum,
    +        IntToErr,
    +        ErrToInt,
    +        CheckSwitchProngs,
    +        CheckStatementIsVoid,
    +        TypeName,
    +        CanImplicitCast,
    +        DeclRef,
    +        Panic,
    +        TagName,
    +        TagType,
    +        FieldParentPtr,
    +        OffsetOf,
    +        TypeId,
    +        SetEvalBranchQuota,
    +        PtrTypeOf,
    +        AlignCast,
    +        OpaqueType,
    +        SetAlignStack,
    +        ArgType,
    +        Export,
    +    };
    +
    +};
    diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig
    index 6fdacda4b2..ff8fb37b42 100644
    --- a/src-self-hosted/main.zig
    +++ b/src-self-hosted/main.zig
    @@ -12,6 +12,7 @@ const ErrColor = Module.ErrColor;
     const Emit = Module.Emit;
     const builtin = @import("builtin");
     const ArrayList = std.ArrayList;
    +const c = @import("c.zig");
     
     error InvalidCommandLineArguments;
     error ZigLibDirNotFound;
    @@ -462,7 +463,11 @@ pub fn main2() -> %void {
                     else => unreachable,
                 }
             },
    -        Cmd.Version => @panic("TODO zig version"),
    +        Cmd.Version => {
    +            var stdout_file = %return io.getStdErr();
    +            %return stdout_file.write(std.cstr.toSliceConst(c.ZIG_VERSION_STRING));
    +            %return stdout_file.write("\n");
    +        },
             Cmd.Targets => @panic("TODO zig targets"),
         }
     }
    diff --git a/src-self-hosted/module.zig b/src-self-hosted/module.zig
    index 700ccf0176..a0cbe9c864 100644
    --- a/src-self-hosted/module.zig
    +++ b/src-self-hosted/module.zig
    @@ -199,6 +199,13 @@ pub const Module = struct {
         }
     
         pub fn build(self: &Module) -> %void {
    +        if (self.llvm_argv.len != 0) {
    +            var c_compatible_args = %return std.cstr.NullTerminated2DArray.fromSlices(self.allocator,
    +                [][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, });
    +            defer c_compatible_args.deinit();
    +            c.ZigLLVMParseCommandLineOptions(self.llvm_argv.len + 1, c_compatible_args.ptr);
    +        }
    +
             const root_src_path = self.root_src_path ?? @panic("TODO handle null root src path");
             const root_src_real_path = os.path.real(self.allocator, root_src_path) %% |err| {
                 %return printError("unable to open '{}': {}", root_src_path, err);
    diff --git a/src-self-hosted/parser.zig b/src-self-hosted/parser.zig
    index c997536ce2..faba8e6059 100644
    --- a/src-self-hosted/parser.zig
    +++ b/src-self-hosted/parser.zig
    @@ -1119,18 +1119,24 @@ fn testCanonical(source: []const u8) {
             break :x failing_allocator.index;
         };
     
    -    // TODO make this pass
    -    //var fail_index = needed_alloc_count;
    -    //while (fail_index != 0) {
    -    //    fail_index -= 1;
    -    //    var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
    -    //    var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, fail_index);
    -    //    if (testParse(source, &failing_allocator.allocator)) |_| {
    -    //        @panic("non-deterministic memory usage");
    -    //    } else |err| {
    -    //        assert(err == error.OutOfMemory);
    -    //    }
    -    //}
    +    var fail_index: usize = 0;
    +    while (fail_index < needed_alloc_count) : (fail_index += 1) {
    +        var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
    +        var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, fail_index);
    +        if (testParse(source, &failing_allocator.allocator)) |_| {
    +            @panic("non-deterministic memory usage");
    +        } else |err| {
    +            assert(err == error.OutOfMemory);
    +            // TODO make this pass
    +            //if (failing_allocator.allocated_bytes != failing_allocator.freed_bytes) {
    +            //    warn("\nfail_index: {}/{}\nallocated bytes: {}\nfreed bytes: {}\nallocations: {}\ndeallocations: {}\n",
    +            //        fail_index, needed_alloc_count,
    +            //        failing_allocator.allocated_bytes, failing_allocator.freed_bytes,
    +            //        failing_allocator.index, failing_allocator.deallocations);
    +            //    @panic("memory leak detected");
    +            //}
    +        }
    +    }
     }
     
     test "zig fmt" {
    diff --git a/src-self-hosted/scope.zig b/src-self-hosted/scope.zig
    new file mode 100644
    index 0000000000..05e586daae
    --- /dev/null
    +++ b/src-self-hosted/scope.zig
    @@ -0,0 +1,16 @@
    +pub const Scope = struct {
    +    id: Id,
    +    parent: &Scope,
    +
    +    pub const Id = enum {
    +        Decls,
    +        Block,
    +        Defer,
    +        DeferExpr,
    +        VarDecl,
    +        CImport,
    +        Loop,
    +        FnDef,
    +        CompTime,
    +    };
    +};
    diff --git a/src-self-hosted/tokenizer.zig b/src-self-hosted/tokenizer.zig
    index 570d41fa7e..49225447a8 100644
    --- a/src-self-hosted/tokenizer.zig
    +++ b/src-self-hosted/tokenizer.zig
    @@ -70,6 +70,7 @@ pub const Token = struct {
             Identifier,
             StringLiteral: StrLitKind,
             Eof,
    +        NoEolAtEof,
             Builtin,
             Bang,
             Equal,
    @@ -139,6 +140,8 @@ pub const Token = struct {
     pub const Tokenizer = struct {
         buffer: []const u8,
         index: usize,
    +    actual_file_end: usize,
    +    pending_invalid_token: ?Token,
     
         pub const Location = struct {
             line: usize,
    @@ -177,9 +180,17 @@ pub const Tokenizer = struct {
         }
     
         pub fn init(buffer: []const u8) -> Tokenizer {
    +        var source_len = buffer.len;
    +        while (source_len > 0) : (source_len -= 1) {
    +            if (buffer[source_len - 1] == '\n') break;
    +            // last line is incomplete, so skip it, and give an error when we get there.
    +        }
    +
             return Tokenizer {
    -            .buffer = buffer,
    +            .buffer = buffer[0..source_len],
                 .index = 0,
    +            .actual_file_end = buffer.len,
    +            .pending_invalid_token = null,
             };
         }
     
    @@ -207,6 +218,10 @@ pub const Tokenizer = struct {
         };
     
         pub fn next(self: &Tokenizer) -> Token {
    +        if (self.pending_invalid_token) |token| {
    +            self.pending_invalid_token = null;
    +            return token;
    +        }
             var state = State.Start;
             var result = Token {
                 .id = Token.Id.Eof,
    @@ -352,7 +367,7 @@ pub const Tokenizer = struct {
                             break;
                         },
                         '\n' => break, // Look for this error later.
    -                    else => {},
    +                    else => self.checkLiteralCharacter(),
                     },
     
                     State.StringLiteralBackslash => switch (c) {
    @@ -439,7 +454,7 @@ pub const Tokenizer = struct {
                                 .end = undefined,
                             };
                         },
    -                    else => {},
    +                    else => self.checkLiteralCharacter(),
                     },
                     State.Zero => switch (c) {
                         'b', 'o', 'x' => {
    @@ -497,13 +512,211 @@ pub const Tokenizer = struct {
                 }
             }
             result.end = self.index;
    -        // TODO check state when returning EOF
    +        if (result.id == Token.Id.Eof) {
    +            if (self.pending_invalid_token) |token| {
    +                self.pending_invalid_token = null;
    +                return token;
    +            }
    +            if (self.actual_file_end != self.buffer.len) {
    +                // instead of an Eof, give an error token
    +                result.id = Token.Id.NoEolAtEof;
    +                result.end = self.actual_file_end;
    +            }
    +        }
             return result;
         }
     
         pub fn getTokenSlice(self: &const Tokenizer, token: &const Token) -> []const u8 {
             return self.buffer[token.start..token.end];
         }
    +
    +    fn checkLiteralCharacter(self: &Tokenizer) {
    +        if (self.pending_invalid_token != null) return;
    +        const invalid_length = self.getInvalidCharacterLength();
    +        if (invalid_length == 0) return;
    +        self.pending_invalid_token = Token {
    +            .id = Token.Id.Invalid,
    +            .start = self.index,
    +            .end = self.index + invalid_length,
    +        };
    +    }
    +
    +    fn getInvalidCharacterLength(self: &Tokenizer) -> u3 {
    +        const c0 = self.buffer[self.index];
    +        if (c0 < 0x80) {
    +            if (c0 < 0x20 or c0 == 0x7f) {
    +                // ascii control codes are never allowed
    +                // (note that \n was checked before we got here)
    +                return 1;
    +            }
    +            // looks fine to me.
    +            return 0;
    +        } else {
    +            // check utf8-encoded character.
    +            // remember that the last byte in the buffer is guaranteed to be '\n',
    +            // which means we really don't need to do bounds checks here,
    +            // as long as we check one byte at a time for being a continuation byte.
    +            var value: u32 = undefined;
    +            var length: u3 = undefined;
    +            if      (c0 & 0b11100000 == 0b11000000) {value = c0 & 0b00011111; length = 2;}
    +            else if (c0 & 0b11110000 == 0b11100000) {value = c0 & 0b00001111; length = 3;}
    +            else if (c0 & 0b11111000 == 0b11110000) {value = c0 & 0b00000111; length = 4;}
    +            else return 1; // unexpected continuation or too many leading 1's
    +
    +            const c1 = self.buffer[self.index + 1];
    +            if (c1 & 0b11000000 != 0b10000000) return 1; // expected continuation
    +            value <<= 6;
    +            value |= c1 & 0b00111111;
    +            if (length == 2) {
    +                if (value < 0x80) return length; // overlong
    +                if (value == 0x85) return length; // U+0085 (NEL)
    +                self.index += length - 1;
    +                return 0;
    +            }
    +            const c2 = self.buffer[self.index + 2];
    +            if (c2 & 0b11000000 != 0b10000000) return 2; // expected continuation
    +            value <<= 6;
    +            value |= c2 & 0b00111111;
    +            if (length == 3) {
    +                if (value < 0x800) return length; // overlong
    +                if (value == 0x2028) return length; // U+2028 (LS)
    +                if (value == 0x2029) return length; // U+2029 (PS)
    +                if (0xd800 <= value and value <= 0xdfff) return length; // surrogate halves not allowed in utf8
    +                self.index += length - 1;
    +                return 0;
    +            }
    +            const c3 = self.buffer[self.index + 3];
    +            if (c3 & 0b11000000 != 0b10000000) return 3; // expected continuation
    +            value <<= 6;
    +            value |= c3 & 0b00111111;
    +            if (length == 4) {
    +                if (value < 0x10000) return length; // overlong
    +                if (value > 0x10FFFF) return length; // out of bounds
    +                self.index += length - 1;
    +                return 0;
    +            }
    +            unreachable;
    +        }
    +    }
     };
     
     
    +
    +test "tokenizer - source must end with eol" {
    +    testTokenizeWithEol("", []Token.Id {
    +    }, true);
    +    testTokenizeWithEol("no newline", []Token.Id {
    +    }, false);
    +    testTokenizeWithEol("test\n", []Token.Id {
    +        Token.Id.Keyword_test,
    +    }, true);
    +    testTokenizeWithEol("test\nno newline", []Token.Id {
    +        Token.Id.Keyword_test,
    +    }, false);
    +}
    +
    +test "tokenizer - invalid token characters" {
    +    testTokenize("#\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("`\n", []Token.Id{Token.Id.Invalid});
    +}
    +
    +test "tokenizer - invalid literal/comment characters" {
    +    testTokenize("\"\x00\"\n", []Token.Id {
    +        Token.Id { .StringLiteral = Token.StrLitKind.Normal },
    +        Token.Id.Invalid,
    +    });
    +    testTokenize("//\x00\n", []Token.Id {
    +        Token.Id.Invalid,
    +    });
    +    testTokenize("//\x1f\n", []Token.Id {
    +        Token.Id.Invalid,
    +    });
    +    testTokenize("//\x7f\n", []Token.Id {
    +        Token.Id.Invalid,
    +    });
    +}
    +
    +test "tokenizer - valid unicode" {
    +    testTokenize("//\xc2\x80\n", []Token.Id{});
    +    testTokenize("//\xdf\xbf\n", []Token.Id{});
    +    testTokenize("//\xe0\xa0\x80\n", []Token.Id{});
    +    testTokenize("//\xe1\x80\x80\n", []Token.Id{});
    +    testTokenize("//\xef\xbf\xbf\n", []Token.Id{});
    +    testTokenize("//\xf0\x90\x80\x80\n", []Token.Id{});
    +    testTokenize("//\xf1\x80\x80\x80\n", []Token.Id{});
    +    testTokenize("//\xf3\xbf\xbf\xbf\n", []Token.Id{});
    +    testTokenize("//\xf4\x8f\xbf\xbf\n", []Token.Id{});
    +}
    +
    +test "tokenizer - invalid unicode continuation bytes" {
    +    // unexpected continuation
    +    testTokenize("//\x80\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xbf\n", []Token.Id{Token.Id.Invalid});
    +    // too many leading 1's
    +    testTokenize("//\xf8\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xff\n", []Token.Id{Token.Id.Invalid});
    +    // expected continuation for 2 byte sequences
    +    testTokenize("//\xc2\x00\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xc2\xc0\n", []Token.Id{Token.Id.Invalid});
    +    // expected continuation for 3 byte sequences
    +    testTokenize("//\xe0\x00\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xe0\xc0\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xe0\xa0\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xe0\xa0\x00\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xe0\xa0\xc0\n", []Token.Id{Token.Id.Invalid});
    +    // expected continuation for 4 byte sequences
    +    testTokenize("//\xf0\x00\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xf0\xc0\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xf0\x90\x00\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xf0\x90\xc0\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xf0\x90\x80\x00\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xf0\x90\x80\xc0\n", []Token.Id{Token.Id.Invalid});
    +}
    +
    +test "tokenizer - overlong utf8 codepoint" {
    +    testTokenize("//\xc0\x80\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xc1\xbf\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xe0\x80\x80\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xe0\x9f\xbf\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xf0\x80\x80\x80\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xf0\x8f\xbf\xbf\n", []Token.Id{Token.Id.Invalid});
    +}
    +
    +test "tokenizer - misc invalid utf8" {
    +    // codepoint out of bounds
    +    testTokenize("//\xf4\x90\x80\x80\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xf7\xbf\xbf\xbf\n", []Token.Id{Token.Id.Invalid});
    +    // unicode newline characters.U+0085, U+2028, U+2029
    +    testTokenize("//\xc2\x84\n", []Token.Id{});
    +    testTokenize("//\xc2\x85\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xc2\x86\n", []Token.Id{});
    +    testTokenize("//\xe2\x80\xa7\n", []Token.Id{});
    +    testTokenize("//\xe2\x80\xa8\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xe2\x80\xa9\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xe2\x80\xaa\n", []Token.Id{});
    +    // surrogate halves
    +    testTokenize("//\xed\x9f\x80\n", []Token.Id{});
    +    testTokenize("//\xed\xa0\x80\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xed\xbf\xbf\n", []Token.Id{Token.Id.Invalid});
    +    testTokenize("//\xee\x80\x80\n", []Token.Id{});
    +    // surrogate halves are invalid, even in surrogate pairs
    +    testTokenize("//\xed\xa0\xad\xed\xb2\xa9\n", []Token.Id{Token.Id.Invalid});
    +}
    +
    +fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) {
    +    testTokenizeWithEol(source, expected_tokens, true);
    +}
    +fn testTokenizeWithEol(source: []const u8, expected_tokens: []const Token.Id, expected_eol_at_eof: bool) {
    +    var tokenizer = Tokenizer.init(source);
    +    for (expected_tokens) |expected_token_id| {
    +        const token = tokenizer.next();
    +        std.debug.assert(@TagType(Token.Id)(token.id) == @TagType(Token.Id)(expected_token_id));
    +        switch (expected_token_id) {
    +            Token.Id.StringLiteral => |expected_kind| {
    +                std.debug.assert(expected_kind == switch (token.id) { Token.Id.StringLiteral => |kind| kind, else => unreachable });
    +            },
    +            else => {},
    +        }
    +    }
    +    std.debug.assert(tokenizer.next().id == if (expected_eol_at_eof) Token.Id.Eof else Token.Id.NoEolAtEof);
    +}
    diff --git a/src/all_types.hpp b/src/all_types.hpp
    index a582f561cc..12ecc84a86 100644
    --- a/src/all_types.hpp
    +++ b/src/all_types.hpp
    @@ -10,7 +10,7 @@
     
     #include "list.hpp"
     #include "buffer.hpp"
    -#include "zig_llvm.hpp"
    +#include "zig_llvm.h"
     #include "hash_map.hpp"
     #include "errmsg.hpp"
     #include "bigint.hpp"
    diff --git a/src/analyze.cpp b/src/analyze.cpp
    index 9ec4db824c..02cdb3485d 100644
    --- a/src/analyze.cpp
    +++ b/src/analyze.cpp
    @@ -14,7 +14,7 @@
     #include "os.hpp"
     #include "parser.hpp"
     #include "softfloat.hpp"
    -#include "zig_llvm.hpp"
    +#include "zig_llvm.h"
     
     
     static const size_t default_backward_branch_quota = 1000;
    diff --git a/src/codegen.cpp b/src/codegen.cpp
    index 339c643425..108b5e0e2e 100644
    --- a/src/codegen.cpp
    +++ b/src/codegen.cpp
    @@ -17,7 +17,7 @@
     #include "os.hpp"
     #include "translate_c.hpp"
     #include "target.hpp"
    -#include "zig_llvm.hpp"
    +#include "zig_llvm.h"
     
     #include 
     #include 
    @@ -3705,12 +3705,24 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *ar
         ConstParent *parent = &array_const_val->data.x_array.s_none.parent;
         LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent);
     
    -    TypeTableEntry *usize = g->builtin_types.entry_usize;
    -    LLVMValueRef indices[] = {
    -        LLVMConstNull(usize->type_ref),
    -        LLVMConstInt(usize->type_ref, index, false),
    -    };
    -    return LLVMConstInBoundsGEP(base_ptr, indices, 2);
    +    LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr)));
    +    if (el_type == LLVMArrayTypeKind) {
    +        TypeTableEntry *usize = g->builtin_types.entry_usize;
    +        LLVMValueRef indices[] = {
    +            LLVMConstNull(usize->type_ref),
    +            LLVMConstInt(usize->type_ref, index, false),
    +        };
    +        return LLVMConstInBoundsGEP(base_ptr, indices, 2);
    +    } else if (el_type == LLVMStructTypeKind) {
    +        TypeTableEntry *u32 = g->builtin_types.entry_u32;
    +        LLVMValueRef indices[] = {
    +            LLVMConstNull(u32->type_ref),
    +            LLVMConstInt(u32->type_ref, index, false),
    +        };
    +        return LLVMConstInBoundsGEP(base_ptr, indices, 2);
    +    } else {
    +        zig_unreachable();
    +    }
     }
     
     static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ConstExprValue *struct_const_val, size_t field_index) {
    @@ -3732,7 +3744,7 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *un
         TypeTableEntry *u32 = g->builtin_types.entry_u32;
         LLVMValueRef indices[] = {
             LLVMConstNull(u32->type_ref),
    -        LLVMConstInt(u32->type_ref, 0, false),
    +        LLVMConstInt(u32->type_ref, 0, false), // TODO test const union with more aligned tag type than payload
         };
         return LLVMConstInBoundsGEP(base_ptr, indices, 2);
     }
    diff --git a/src/config.h.in b/src/config.h.in
    index a596213a3d..73e1de27c1 100644
    --- a/src/config.h.in
    +++ b/src/config.h.in
    @@ -24,4 +24,8 @@
     // Only used for running tests before installing.
     #define ZIG_TEST_DIR "@CMAKE_SOURCE_DIR@/test"
     
    +// Used for communicating build information to self hosted build.
    +#define ZIG_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@"
    +#define ZIG_CXX_COMPILER "@CMAKE_CXX_COMPILER@"
    +
     #endif
    diff --git a/src/link.cpp b/src/link.cpp
    index bc84b27b89..f07364e5bc 100644
    --- a/src/link.cpp
    +++ b/src/link.cpp
    @@ -351,6 +351,16 @@ static void coff_append_machine_arg(CodeGen *g, ZigList *list) {
         }
     }
     
    +static void link_diag_callback(void *context, const char *ptr, size_t len) {
    +    Buf *diag = reinterpret_cast(context);
    +    buf_append_mem(diag, ptr, len);
    +}
    +
    +static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag) {
    +    buf_resize(diag, 0);
    +    return ZigLLDLink(oformat, args, arg_count, link_diag_callback, diag);
    +}
    +
     static void construct_linker_job_coff(LinkJob *lj) {
         CodeGen *g = lj->codegen;
     
    @@ -515,7 +525,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
                 gen_lib_args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path))));
                 gen_lib_args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(generated_lib_path))));
                 Buf diag = BUF_INIT;
    -            if (!ZigLLDLink(g->zig_target.oformat, gen_lib_args.items, gen_lib_args.length, &diag)) {
    +            if (!zig_lld_link(g->zig_target.oformat, gen_lib_args.items, gen_lib_args.length, &diag)) {
                     fprintf(stderr, "%s\n", buf_ptr(&diag));
                     exit(1);
                 }
    @@ -930,7 +940,7 @@ void codegen_link(CodeGen *g, const char *out_file) {
         Buf diag = BUF_INIT;
     
         codegen_add_time_event(g, "LLVM Link");
    -    if (!ZigLLDLink(g->zig_target.oformat, lj.args.items, lj.args.length, &diag)) {
    +    if (!zig_lld_link(g->zig_target.oformat, lj.args.items, lj.args.length, &diag)) {
             fprintf(stderr, "%s\n", buf_ptr(&diag));
             exit(1);
         }
    diff --git a/src/main.cpp b/src/main.cpp
    index 60d2750bde..66ffbbde82 100644
    --- a/src/main.cpp
    +++ b/src/main.cpp
    @@ -266,6 +266,11 @@ static void add_package(CodeGen *g, CliPkg *cli_pkg, PackageTableEntry *pkg) {
     }
     
     int main(int argc, char **argv) {
    +    if (argc == 2 && strcmp(argv[1], "BUILD_INFO") == 0) {
    +        printf("%s\n%s\n", ZIG_CMAKE_BINARY_DIR, ZIG_CXX_COMPILER);
    +        return 0;
    +    }
    +
         os_init();
     
         char *arg0 = argv[0];
    diff --git a/src/os.hpp b/src/os.hpp
    index d4d1676df6..5d29db0d07 100644
    --- a/src/os.hpp
    +++ b/src/os.hpp
    @@ -11,7 +11,7 @@
     #include "list.hpp"
     #include "buffer.hpp"
     #include "error.hpp"
    -#include "zig_llvm.hpp"
    +#include "zig_llvm.h"
     
     #include 
     #include 
    diff --git a/src/target.hpp b/src/target.hpp
    index 2b678b313d..9bcca776f4 100644
    --- a/src/target.hpp
    +++ b/src/target.hpp
    @@ -8,7 +8,7 @@
     #ifndef ZIG_TARGET_HPP
     #define ZIG_TARGET_HPP
     
    -#include 
    +#include 
     
     struct Buf;
     
    diff --git a/src/util.hpp b/src/util.hpp
    index 73608b3b08..ce6cc09a59 100644
    --- a/src/util.hpp
    +++ b/src/util.hpp
    @@ -13,8 +13,6 @@
     #include 
     #include 
     
    -#include 
    -
     #if defined(_MSC_VER)
     
     #include   
    diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp
    index bd3eadbee9..2a455c79d4 100644
    --- a/src/zig_llvm.cpp
    +++ b/src/zig_llvm.cpp
    @@ -13,7 +13,7 @@
      * 3. Prevent C++ from infecting the rest of the project.
      */
     
    -#include "zig_llvm.hpp"
    +#include "zig_llvm.h"
     
     #include 
     #include 
    @@ -39,8 +39,35 @@
     
     #include 
     
    +#include 
    +
    +#include 
    +
    +#if defined(_MSC_VER)
    +#define ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
    +#else
    +#define ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
    +#endif
    +
     using namespace llvm;
     
    +template
    +ATTRIBUTE_RETURNS_NOALIAS static inline T * create(Args... args) {
    +    T * ptr = reinterpret_cast(malloc(sizeof(T)));
    +    if (ptr == nullptr)
    +        return nullptr;
    +    new (ptr) T(args...);
    +    return ptr;
    +}
    +
    +template
    +static inline void destroy(T * ptr) {
    +    if (ptr != nullptr) {
    +        ptr[0].~T();
    +    }
    +    free(ptr);
    +}
    +
     void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) {
         initializeLoopStrengthReducePass(*unwrap(R));
     }
    @@ -50,8 +77,7 @@ void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R) {
     }
     
     char *ZigLLVMGetHostCPUName(void) {
    -    std::string str = sys::getHostCPUName();
    -    return strdup(str.c_str());
    +    return strdup((const char *)sys::getHostCPUName().bytes_begin());
     }
     
     char *ZigLLVMGetNativeFeatures(void) {
    @@ -63,11 +89,11 @@ char *ZigLLVMGetNativeFeatures(void) {
                 features.AddFeature(F.first(), F.second);
         }
     
    -    return strdup(features.getString().c_str());
    +    return strdup((const char *)StringRef(features.getString()).bytes_begin());
     }
     
     static void addDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) {
    -  PM.add(createAddDiscriminatorsPass());
    +    PM.add(createAddDiscriminatorsPass());
     }
     
     #ifndef NDEBUG
    @@ -82,7 +108,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
         std::error_code EC;
         raw_fd_ostream dest(filename, EC, sys::fs::F_None);
         if (EC) {
    -        *error_message = strdup(EC.message().c_str());
    +        *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
             return true;
         }
         TargetMachine* target_machine = reinterpret_cast(targ_machine_ref);
    @@ -90,7 +116,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
     
         Module* module = unwrap(module_ref);
     
    -    PassManagerBuilder *PMBuilder = new PassManagerBuilder();
    +    PassManagerBuilder *PMBuilder = create();
         PMBuilder->OptLevel = target_machine->getOptLevel();
         PMBuilder->SizeLevel = 0;
     
    @@ -123,7 +149,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
     
         // Set up the per-function pass manager.
         legacy::FunctionPassManager FPM = legacy::FunctionPassManager(module);
    -    FPM.add(new TargetLibraryInfoWrapperPass(tlii));
    +    FPM.add(create(tlii));
         FPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));
         if (assertions_on) {
             FPM.add(createVerifierPass());
    @@ -415,7 +441,10 @@ unsigned ZigLLVMTag_DW_union_type(void) {
     }
     
     ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) {
    -    DIBuilder *di_builder = new DIBuilder(*unwrap(module), allow_unresolved);
    +    DIBuilder *di_builder = reinterpret_cast(malloc(sizeof(DIBuilder)));
    +    if (di_builder == nullptr)
    +        return nullptr;
    +    new (di_builder) DIBuilder(*unwrap(module), allow_unresolved);
         return reinterpret_cast(di_builder);
     }
     
    @@ -617,7 +646,7 @@ void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn_ref) {
         func->setAttributes(new_attr_set);
     }
     
    -void ZigLLVMParseCommandLineOptions(int argc, const char *const *argv) {
    +void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) {
         llvm::cl::ParseCommandLineOptions(argc, argv);
     }
     
    @@ -775,29 +804,35 @@ LLVMValueRef ZigLLVMBuildAShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLV
     }
     
     
    -#include "buffer.hpp"
    +class MyOStream: public raw_ostream {
    +    public:
    +        MyOStream(void (*_append_diagnostic)(void *, const char *, size_t), void *_context) :
    +            raw_ostream(true), append_diagnostic(_append_diagnostic), context(_context), pos(0) {
     
    -bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag_buf) {
    +        }
    +        void write_impl(const char *ptr, size_t len) override {
    +            append_diagnostic(context, ptr, len);
    +            pos += len;
    +        }
    +        uint64_t current_pos() const override {
    +            return pos;
    +        }
    +        void (*append_diagnostic)(void *, const char *, size_t);
    +        void *context;
    +        size_t pos;
    +};
    +
    +
    +bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count,
    +        void (*append_diagnostic)(void *, const char *, size_t), void *context)
    +{
         ArrayRef array_ref_args(args, arg_count);
     
    -    buf_resize(diag_buf, 0);
    -    class MyOStream: public raw_ostream {
    -        public:
    -            MyOStream(Buf *_diag_buf) : raw_ostream(true), diag_buf(_diag_buf) {
    -
    -            }
    -            void write_impl(const char *ptr, size_t len) override {
    -                buf_append_mem(diag_buf, ptr, len);
    -            }
    -            uint64_t current_pos() const override {
    -                return buf_len(diag_buf);
    -            }
    -            Buf *diag_buf;
    -    } diag(diag_buf);
    +    MyOStream diag(append_diagnostic, context);
     
         switch (oformat) {
             case ZigLLVM_UnknownObjectFormat:
    -            zig_unreachable();
    +            assert(false); // unreachable
     
             case ZigLLVM_COFF:
                 return lld::coff::link(array_ref_args, false, diag);
    @@ -809,7 +844,8 @@ bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_
                 return lld::mach_o::link(array_ref_args, diag);
     
             case ZigLLVM_Wasm:
    -            zig_panic("ZigLLDLink for Wasm");
    +            assert(false); // TODO ZigLLDLink for Wasm
         }
    -    zig_unreachable();
    +    assert(false); // unreachable
    +    abort();
     }
    diff --git a/src/zig_llvm.h b/src/zig_llvm.h
    new file mode 100644
    index 0000000000..9cdb28dc58
    --- /dev/null
    +++ b/src/zig_llvm.h
    @@ -0,0 +1,398 @@
    +/*
    + * Copyright (c) 2015 Andrew Kelley
    + *
    + * This file is part of zig, which is MIT licensed.
    + * See http://opensource.org/licenses/MIT
    + */
    +
    +#ifndef ZIG_ZIG_LLVM_HPP
    +#define ZIG_ZIG_LLVM_HPP
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#ifdef __cplusplus
    +#define ZIG_EXTERN_C extern "C"
    +#else
    +#define ZIG_EXTERN_C
    +#endif
    +
    +struct ZigLLVMDIType;
    +struct ZigLLVMDIBuilder;
    +struct ZigLLVMDICompileUnit;
    +struct ZigLLVMDIScope;
    +struct ZigLLVMDIFile;
    +struct ZigLLVMDILexicalBlock;
    +struct ZigLLVMDISubprogram;
    +struct ZigLLVMDISubroutineType;
    +struct ZigLLVMDILocalVariable;
    +struct ZigLLVMDIGlobalVariable;
    +struct ZigLLVMDILocation;
    +struct ZigLLVMDIEnumerator;
    +struct ZigLLVMInsertionPoint;
    +
    +ZIG_EXTERN_C void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R);
    +ZIG_EXTERN_C void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R);
    +
    +/// Caller must free memory.
    +ZIG_EXTERN_C char *ZigLLVMGetHostCPUName(void);
    +ZIG_EXTERN_C char *ZigLLVMGetNativeFeatures(void);
    +
    +// We use a custom enum here since LLVM does not expose LLVMIr as an emit
    +// output through the same mechanism as assembly/binary.
    +enum ZigLLVM_EmitOutputType {
    +    ZigLLVM_EmitAssembly,
    +    ZigLLVM_EmitBinary,
    +    ZigLLVM_EmitLLVMIr,
    +};
    +
    +ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
    +        const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug);
    +
    +enum ZigLLVM_FnInline {
    +    ZigLLVM_FnInlineAuto,
    +    ZigLLVM_FnInlineAlways,
    +    ZigLLVM_FnInlineNever,
    +};
    +ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
    +        unsigned NumArgs, unsigned CC, enum ZigLLVM_FnInline fn_inline, const char *Name);
    +
    +ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef cmp,
    +        LLVMValueRef new_val, LLVMAtomicOrdering success_ordering,
    +        LLVMAtomicOrdering failure_ordering);
    +
    +ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNSWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
    +        const char *name);
    +ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNUWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
    +        const char *name);
    +ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildLShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
    +        const char *name);
    +ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildAShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
    +        const char *name);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugPointerType(struct ZigLLVMDIBuilder *dibuilder,
    +        struct ZigLLVMDIType *pointee_type, uint64_t size_in_bits, uint64_t align_in_bits, const char *name);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugBasicType(struct ZigLLVMDIBuilder *dibuilder, const char *name,
    +        uint64_t size_in_bits, unsigned encoding);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugArrayType(struct ZigLLVMDIBuilder *dibuilder,
    +        uint64_t size_in_bits, uint64_t align_in_bits, struct ZigLLVMDIType *elem_type,
    +        int elem_count);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(struct ZigLLVMDIBuilder *dibuilder,
    +        const char *name, int64_t val);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugEnumerationType(struct ZigLLVMDIBuilder *dibuilder,
    +        struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_number,
    +        uint64_t size_in_bits, uint64_t align_in_bits, struct ZigLLVMDIEnumerator **enumerator_array,
    +        int enumerator_array_len, struct ZigLLVMDIType *underlying_type, const char *unique_id);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugStructType(struct ZigLLVMDIBuilder *dibuilder,
    +        struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_number,
    +        uint64_t size_in_bits, uint64_t align_in_bits, unsigned flags, struct ZigLLVMDIType *derived_from,
    +        struct ZigLLVMDIType **types_array, int types_array_len, unsigned run_time_lang,
    +        struct ZigLLVMDIType *vtable_holder, const char *unique_id);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugUnionType(struct ZigLLVMDIBuilder *dibuilder,
    +        struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_number,
    +        uint64_t size_in_bits, uint64_t align_in_bits, unsigned flags, struct ZigLLVMDIType **types_array,
    +        int types_array_len, unsigned run_time_lang, const char *unique_id);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugMemberType(struct ZigLLVMDIBuilder *dibuilder,
    +        struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line,
    +        uint64_t size_in_bits, uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags,
    +        struct ZigLLVMDIType *type);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateReplaceableCompositeType(struct ZigLLVMDIBuilder *dibuilder,
    +        unsigned tag, const char *name, struct ZigLLVMDIScope *scope, struct ZigLLVMDIFile *file, unsigned line);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugForwardDeclType(struct ZigLLVMDIBuilder *dibuilder, unsigned tag,
    +        const char *name, struct ZigLLVMDIScope *scope, struct ZigLLVMDIFile *file, unsigned line);
    +
    +ZIG_EXTERN_C void ZigLLVMReplaceTemporary(struct ZigLLVMDIBuilder *dibuilder, struct ZigLLVMDIType *type,
    +        struct ZigLLVMDIType *replacement);
    +
    +ZIG_EXTERN_C void ZigLLVMReplaceDebugArrays(struct ZigLLVMDIBuilder *dibuilder, struct ZigLLVMDIType *type,
    +        struct ZigLLVMDIType **types_array, int types_array_len);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateSubroutineType(struct ZigLLVMDIBuilder *dibuilder_wrapped,
    +        struct ZigLLVMDIType **types_array, int types_array_len, unsigned flags);
    +
    +ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_unsigned(void);
    +ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_signed(void);
    +ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_float(void);
    +ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_boolean(void);
    +ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_unsigned_char(void);
    +ZIG_EXTERN_C unsigned ZigLLVMEncoding_DW_ATE_signed_char(void);
    +ZIG_EXTERN_C unsigned ZigLLVMLang_DW_LANG_C99(void);
    +ZIG_EXTERN_C unsigned ZigLLVMTag_DW_variable(void);
    +ZIG_EXTERN_C unsigned ZigLLVMTag_DW_structure_type(void);
    +ZIG_EXTERN_C unsigned ZigLLVMTag_DW_union_type(void);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved);
    +ZIG_EXTERN_C void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module);
    +ZIG_EXTERN_C void ZigLLVMAddModuleCodeViewFlag(LLVMModuleRef module);
    +
    +ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, int line, int column,
    +        struct ZigLLVMDIScope *scope);
    +ZIG_EXTERN_C void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(struct ZigLLVMDILexicalBlock *lexical_block);
    +ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMCompileUnitToScope(struct ZigLLVMDICompileUnit *compile_unit);
    +ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMFileToScope(struct ZigLLVMDIFile *difile);
    +ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMSubprogramToScope(struct ZigLLVMDISubprogram *subprogram);
    +ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMTypeToScope(struct ZigLLVMDIType *type);
    +
    +ZIG_EXTERN_C struct ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(struct ZigLLVMDIBuilder *dbuilder,
    +        struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_no,
    +        struct ZigLLVMDIType *type, bool always_preserve, unsigned flags);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIGlobalVariable *ZigLLVMCreateGlobalVariable(struct ZigLLVMDIBuilder *dbuilder,
    +    struct ZigLLVMDIScope *scope, const char *name, const char *linkage_name, struct ZigLLVMDIFile *file,
    +    unsigned line_no, struct ZigLLVMDIType *di_type, bool is_local_to_unit);
    +
    +ZIG_EXTERN_C struct ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(struct ZigLLVMDIBuilder *dbuilder,
    +        struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_no,
    +        struct ZigLLVMDIType *type, bool always_preserve, unsigned flags, unsigned arg_no);
    +
    +ZIG_EXTERN_C struct ZigLLVMDILexicalBlock *ZigLLVMCreateLexicalBlock(struct ZigLLVMDIBuilder *dbuilder,
    +        struct ZigLLVMDIScope *scope, struct ZigLLVMDIFile *file, unsigned line, unsigned col);
    +
    +ZIG_EXTERN_C struct ZigLLVMDICompileUnit *ZigLLVMCreateCompileUnit(struct ZigLLVMDIBuilder *dibuilder,
    +        unsigned lang, struct ZigLLVMDIFile *difile, const char *producer,
    +        bool is_optimized, const char *flags, unsigned runtime_version, const char *split_name,
    +        uint64_t dwo_id, bool emit_debug_info);
    +
    +ZIG_EXTERN_C struct ZigLLVMDIFile *ZigLLVMCreateFile(struct ZigLLVMDIBuilder *dibuilder, const char *filename,
    +        const char *directory);
    +
    +ZIG_EXTERN_C struct ZigLLVMDISubprogram *ZigLLVMCreateFunction(struct ZigLLVMDIBuilder *dibuilder,
    +        struct ZigLLVMDIScope *scope, const char *name, const char *linkage_name, struct ZigLLVMDIFile *file,
    +        unsigned lineno, struct ZigLLVMDIType *fn_di_type, bool is_local_to_unit, bool is_definition,
    +        unsigned scope_line, unsigned flags, bool is_optimized, struct ZigLLVMDISubprogram *decl_subprogram);
    +
    +ZIG_EXTERN_C void ZigLLVMFnSetSubprogram(LLVMValueRef fn, struct ZigLLVMDISubprogram *subprogram);
    +
    +ZIG_EXTERN_C void ZigLLVMDIBuilderFinalize(struct ZigLLVMDIBuilder *dibuilder);
    +
    +ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDeclareAtEnd(struct ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage,
    +        struct ZigLLVMDILocalVariable *var_info, struct ZigLLVMDILocation *debug_loc,
    +        LLVMBasicBlockRef basic_block_ref);
    +
    +ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDeclare(struct ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage,
    +        struct ZigLLVMDILocalVariable *var_info, struct ZigLLVMDILocation *debug_loc, LLVMValueRef insert_before_instr);
    +ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, struct ZigLLVMDIScope *scope);
    +
    +ZIG_EXTERN_C void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state);
    +
    +ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value);
    +ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn);
    +
    +ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv);
    +
    +
    +// copied from include/llvm/ADT/Triple.h
    +
    +enum ZigLLVM_ArchType {
    +    ZigLLVM_UnknownArch,
    +
    +    ZigLLVM_arm,            // ARM (little endian): arm, armv.*, xscale
    +    ZigLLVM_armeb,          // ARM (big endian): armeb
    +    ZigLLVM_aarch64,        // AArch64 (little endian): aarch64
    +    ZigLLVM_aarch64_be,     // AArch64 (big endian): aarch64_be
    +    ZigLLVM_arc,            // ARC: Synopsys ARC
    +    ZigLLVM_avr,            // AVR: Atmel AVR microcontroller
    +    ZigLLVM_bpfel,          // eBPF or extended BPF or 64-bit BPF (little endian)
    +    ZigLLVM_bpfeb,          // eBPF or extended BPF or 64-bit BPF (big endian)
    +    ZigLLVM_hexagon,        // Hexagon: hexagon
    +    ZigLLVM_mips,           // MIPS: mips, mipsallegrex
    +    ZigLLVM_mipsel,         // MIPSEL: mipsel, mipsallegrexel
    +    ZigLLVM_mips64,         // MIPS64: mips64
    +    ZigLLVM_mips64el,       // MIPS64EL: mips64el
    +    ZigLLVM_msp430,         // MSP430: msp430
    +    ZigLLVM_nios2,          // NIOSII: nios2
    +    ZigLLVM_ppc,            // PPC: powerpc
    +    ZigLLVM_ppc64,          // PPC64: powerpc64, ppu
    +    ZigLLVM_ppc64le,        // PPC64LE: powerpc64le
    +    ZigLLVM_r600,           // R600: AMD GPUs HD2XXX - HD6XXX
    +    ZigLLVM_amdgcn,         // AMDGCN: AMD GCN GPUs
    +    ZigLLVM_riscv32,        // RISC-V (32-bit): riscv32
    +    ZigLLVM_riscv64,        // RISC-V (64-bit): riscv64
    +    ZigLLVM_sparc,          // Sparc: sparc
    +    ZigLLVM_sparcv9,        // Sparcv9: Sparcv9
    +    ZigLLVM_sparcel,        // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant
    +    ZigLLVM_systemz,        // SystemZ: s390x
    +    ZigLLVM_tce,            // TCE (http://tce.cs.tut.fi/): tce
    +    ZigLLVM_tcele,          // TCE little endian (http://tce.cs.tut.fi/): tcele
    +    ZigLLVM_thumb,          // Thumb (little endian): thumb, thumbv.*
    +    ZigLLVM_thumbeb,        // Thumb (big endian): thumbeb
    +    ZigLLVM_x86,            // X86: i[3-9]86
    +    ZigLLVM_x86_64,         // X86-64: amd64, x86_64
    +    ZigLLVM_xcore,          // XCore: xcore
    +    ZigLLVM_nvptx,          // NVPTX: 32-bit
    +    ZigLLVM_nvptx64,        // NVPTX: 64-bit
    +    ZigLLVM_le32,           // le32: generic little-endian 32-bit CPU (PNaCl)
    +    ZigLLVM_le64,           // le64: generic little-endian 64-bit CPU (PNaCl)
    +    ZigLLVM_amdil,          // AMDIL
    +    ZigLLVM_amdil64,        // AMDIL with 64-bit pointers
    +    ZigLLVM_hsail,          // AMD HSAIL
    +    ZigLLVM_hsail64,        // AMD HSAIL with 64-bit pointers
    +    ZigLLVM_spir,           // SPIR: standard portable IR for OpenCL 32-bit version
    +    ZigLLVM_spir64,         // SPIR: standard portable IR for OpenCL 64-bit version
    +    ZigLLVM_kalimba,        // Kalimba: generic kalimba
    +    ZigLLVM_shave,          // SHAVE: Movidius vector VLIW processors
    +    ZigLLVM_lanai,          // Lanai: Lanai 32-bit
    +    ZigLLVM_wasm32,         // WebAssembly with 32-bit pointers
    +    ZigLLVM_wasm64,         // WebAssembly with 64-bit pointers
    +    ZigLLVM_renderscript32, // 32-bit RenderScript
    +    ZigLLVM_renderscript64, // 64-bit RenderScript
    +
    +    ZigLLVM_LastArchType = ZigLLVM_renderscript64
    +};
    +
    +enum ZigLLVM_SubArchType {
    +    ZigLLVM_NoSubArch,
    +
    +    ZigLLVM_ARMSubArch_v8_3a,
    +    ZigLLVM_ARMSubArch_v8_2a,
    +    ZigLLVM_ARMSubArch_v8_1a,
    +    ZigLLVM_ARMSubArch_v8,
    +    ZigLLVM_ARMSubArch_v8r,
    +    ZigLLVM_ARMSubArch_v8m_baseline,
    +    ZigLLVM_ARMSubArch_v8m_mainline,
    +    ZigLLVM_ARMSubArch_v7,
    +    ZigLLVM_ARMSubArch_v7em,
    +    ZigLLVM_ARMSubArch_v7m,
    +    ZigLLVM_ARMSubArch_v7s,
    +    ZigLLVM_ARMSubArch_v7k,
    +    ZigLLVM_ARMSubArch_v7ve,
    +    ZigLLVM_ARMSubArch_v6,
    +    ZigLLVM_ARMSubArch_v6m,
    +    ZigLLVM_ARMSubArch_v6k,
    +    ZigLLVM_ARMSubArch_v6t2,
    +    ZigLLVM_ARMSubArch_v5,
    +    ZigLLVM_ARMSubArch_v5te,
    +    ZigLLVM_ARMSubArch_v4t,
    +
    +    ZigLLVM_KalimbaSubArch_v3,
    +    ZigLLVM_KalimbaSubArch_v4,
    +    ZigLLVM_KalimbaSubArch_v5,
    +};
    +
    +enum ZigLLVM_VendorType {
    +    ZigLLVM_UnknownVendor,
    +
    +    ZigLLVM_Apple,
    +    ZigLLVM_PC,
    +    ZigLLVM_SCEI,
    +    ZigLLVM_BGP,
    +    ZigLLVM_BGQ,
    +    ZigLLVM_Freescale,
    +    ZigLLVM_IBM,
    +    ZigLLVM_ImaginationTechnologies,
    +    ZigLLVM_MipsTechnologies,
    +    ZigLLVM_NVIDIA,
    +    ZigLLVM_CSR,
    +    ZigLLVM_Myriad,
    +    ZigLLVM_AMD,
    +    ZigLLVM_Mesa,
    +    ZigLLVM_SUSE,
    +
    +    ZigLLVM_LastVendorType = ZigLLVM_SUSE
    +};
    +
    +enum ZigLLVM_OSType {
    +    ZigLLVM_UnknownOS,
    +
    +    ZigLLVM_Ananas,
    +    ZigLLVM_CloudABI,
    +    ZigLLVM_Darwin,
    +    ZigLLVM_DragonFly,
    +    ZigLLVM_FreeBSD,
    +    ZigLLVM_Fuchsia,
    +    ZigLLVM_IOS,
    +    ZigLLVM_KFreeBSD,
    +    ZigLLVM_Linux,
    +    ZigLLVM_Lv2,        // PS3
    +    ZigLLVM_MacOSX,
    +    ZigLLVM_NetBSD,
    +    ZigLLVM_OpenBSD,
    +    ZigLLVM_Solaris,
    +    ZigLLVM_Win32,
    +    ZigLLVM_Haiku,
    +    ZigLLVM_Minix,
    +    ZigLLVM_RTEMS,
    +    ZigLLVM_NaCl,       // Native Client
    +    ZigLLVM_CNK,        // BG/P Compute-Node Kernel
    +    ZigLLVM_Bitrig,
    +    ZigLLVM_AIX,
    +    ZigLLVM_CUDA,       // NVIDIA CUDA
    +    ZigLLVM_NVCL,       // NVIDIA OpenCL
    +    ZigLLVM_AMDHSA,     // AMD HSA Runtime
    +    ZigLLVM_PS4,
    +    ZigLLVM_ELFIAMCU,
    +    ZigLLVM_TvOS,       // Apple tvOS
    +    ZigLLVM_WatchOS,    // Apple watchOS
    +    ZigLLVM_Mesa3D,
    +    ZigLLVM_Contiki,
    +
    +    ZigLLVM_LastOSType = ZigLLVM_Contiki
    +};
    +
    +enum ZigLLVM_EnvironmentType {
    +    ZigLLVM_UnknownEnvironment,
    +
    +    ZigLLVM_GNU,
    +    ZigLLVM_GNUABIN32,
    +    ZigLLVM_GNUABI64,
    +    ZigLLVM_GNUEABI,
    +    ZigLLVM_GNUEABIHF,
    +    ZigLLVM_GNUX32,
    +    ZigLLVM_CODE16,
    +    ZigLLVM_EABI,
    +    ZigLLVM_EABIHF,
    +    ZigLLVM_Android,
    +    ZigLLVM_Musl,
    +    ZigLLVM_MuslEABI,
    +    ZigLLVM_MuslEABIHF,
    +
    +    ZigLLVM_MSVC,
    +    ZigLLVM_Itanium,
    +    ZigLLVM_Cygnus,
    +    ZigLLVM_AMDOpenCL,
    +    ZigLLVM_CoreCLR,
    +    ZigLLVM_OpenCL,
    +    ZigLLVM_Simulator,
    +
    +    ZigLLVM_LastEnvironmentType = ZigLLVM_Simulator
    +};
    +
    +enum ZigLLVM_ObjectFormatType {
    +    ZigLLVM_UnknownObjectFormat,
    +
    +    ZigLLVM_COFF,
    +    ZigLLVM_ELF,
    +    ZigLLVM_MachO,
    +    ZigLLVM_Wasm,
    +};
    +
    +ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch);
    +ZIG_EXTERN_C const char *ZigLLVMGetSubArchTypeName(enum ZigLLVM_SubArchType sub_arch);
    +ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor);
    +ZIG_EXTERN_C const char *ZigLLVMGetOSTypeName(enum ZigLLVM_OSType os);
    +ZIG_EXTERN_C const char *ZigLLVMGetEnvironmentTypeName(enum ZigLLVM_EnvironmentType env_type);
    +
    +ZIG_EXTERN_C bool ZigLLDLink(enum ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count,
    +        void (*append_diagnostic)(void *, const char *, size_t), void *context);
    +
    +ZIG_EXTERN_C void ZigLLVMGetNativeTarget(enum ZigLLVM_ArchType *arch_type, enum ZigLLVM_SubArchType *sub_arch_type,
    +        enum ZigLLVM_VendorType *vendor_type, enum ZigLLVM_OSType *os_type, enum ZigLLVM_EnvironmentType *environ_type,
    +        enum ZigLLVM_ObjectFormatType *oformat);
    +
    +#endif
    diff --git a/src/zig_llvm.hpp b/src/zig_llvm.hpp
    deleted file mode 100644
    index f335a8955a..0000000000
    --- a/src/zig_llvm.hpp
    +++ /dev/null
    @@ -1,387 +0,0 @@
    -/*
    - * Copyright (c) 2015 Andrew Kelley
    - *
    - * This file is part of zig, which is MIT licensed.
    - * See http://opensource.org/licenses/MIT
    - */
    -
    -#ifndef ZIG_ZIG_LLVM_HPP
    -#define ZIG_ZIG_LLVM_HPP
    -
    -#include 
    -#include 
    -#include 
    -#include 
    -#include 
    -
    -struct ZigLLVMDIType;
    -struct ZigLLVMDIBuilder;
    -struct ZigLLVMDICompileUnit;
    -struct ZigLLVMDIScope;
    -struct ZigLLVMDIFile;
    -struct ZigLLVMDILexicalBlock;
    -struct ZigLLVMDISubprogram;
    -struct ZigLLVMDISubroutineType;
    -struct ZigLLVMDILocalVariable;
    -struct ZigLLVMDIGlobalVariable;
    -struct ZigLLVMDILocation;
    -struct ZigLLVMDIEnumerator;
    -struct ZigLLVMInsertionPoint;
    -
    -void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R);
    -void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R);
    -
    -char *ZigLLVMGetHostCPUName(void);
    -char *ZigLLVMGetNativeFeatures(void);
    -
    -// We use a custom enum here since LLVM does not expose LLVMIr as an emit
    -// output through the same mechanism as assembly/binary.
    -enum ZigLLVM_EmitOutputType {
    -    ZigLLVM_EmitAssembly,
    -    ZigLLVM_EmitBinary,
    -    ZigLLVM_EmitLLVMIr,
    -};
    -
    -bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
    -        const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug);
    -
    -enum ZigLLVM_FnInline {
    -    ZigLLVM_FnInlineAuto,
    -    ZigLLVM_FnInlineAlways,
    -    ZigLLVM_FnInlineNever,
    -};
    -LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
    -        unsigned NumArgs, unsigned CC, ZigLLVM_FnInline fn_inline, const char *Name);
    -
    -LLVMValueRef ZigLLVMBuildCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef cmp,
    -        LLVMValueRef new_val, LLVMAtomicOrdering success_ordering,
    -        LLVMAtomicOrdering failure_ordering);
    -
    -LLVMValueRef ZigLLVMBuildNSWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
    -        const char *name);
    -LLVMValueRef ZigLLVMBuildNUWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
    -        const char *name);
    -LLVMValueRef ZigLLVMBuildLShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
    -        const char *name);
    -LLVMValueRef ZigLLVMBuildAShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
    -        const char *name);
    -
    -ZigLLVMDIType *ZigLLVMCreateDebugPointerType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *pointee_type,
    -        uint64_t size_in_bits, uint64_t align_in_bits, const char *name);
    -
    -ZigLLVMDIType *ZigLLVMCreateDebugBasicType(ZigLLVMDIBuilder *dibuilder, const char *name,
    -        uint64_t size_in_bits, unsigned encoding);
    -
    -ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder,
    -        uint64_t size_in_bits, uint64_t align_in_bits, ZigLLVMDIType *elem_type,
    -        int elem_count);
    -
    -ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(ZigLLVMDIBuilder *dibuilder, const char *name, int64_t val);
    -
    -ZigLLVMDIType *ZigLLVMCreateDebugEnumerationType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
    -        const char *name, ZigLLVMDIFile *file, unsigned line_number, uint64_t size_in_bits,
    -        uint64_t align_in_bits, ZigLLVMDIEnumerator **enumerator_array, int enumerator_array_len,
    -        ZigLLVMDIType *underlying_type, const char *unique_id);
    -
    -ZigLLVMDIType *ZigLLVMCreateDebugStructType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
    -        const char *name, ZigLLVMDIFile *file, unsigned line_number, uint64_t size_in_bits,
    -        uint64_t align_in_bits, unsigned flags, ZigLLVMDIType *derived_from,
    -        ZigLLVMDIType **types_array, int types_array_len, unsigned run_time_lang, ZigLLVMDIType *vtable_holder,
    -        const char *unique_id);
    -
    -ZigLLVMDIType *ZigLLVMCreateDebugUnionType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
    -        const char *name, ZigLLVMDIFile *file, unsigned line_number, uint64_t size_in_bits,
    -        uint64_t align_in_bits, unsigned flags, ZigLLVMDIType **types_array, int types_array_len,
    -        unsigned run_time_lang, const char *unique_id);
    -
    -ZigLLVMDIType *ZigLLVMCreateDebugMemberType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
    -        const char *name, ZigLLVMDIFile *file, unsigned line, uint64_t size_in_bits,
    -        uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, ZigLLVMDIType *type);
    -
    -ZigLLVMDIType *ZigLLVMCreateReplaceableCompositeType(ZigLLVMDIBuilder *dibuilder, unsigned tag,
    -        const char *name, ZigLLVMDIScope *scope, ZigLLVMDIFile *file, unsigned line);
    -
    -ZigLLVMDIType *ZigLLVMCreateDebugForwardDeclType(ZigLLVMDIBuilder *dibuilder, unsigned tag,
    -        const char *name, ZigLLVMDIScope *scope, ZigLLVMDIFile *file, unsigned line);
    -
    -void ZigLLVMReplaceTemporary(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *type,
    -        ZigLLVMDIType *replacement);
    -
    -void ZigLLVMReplaceDebugArrays(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *type,
    -        ZigLLVMDIType **types_array, int types_array_len);
    -
    -ZigLLVMDIType *ZigLLVMCreateSubroutineType(ZigLLVMDIBuilder *dibuilder_wrapped,
    -        ZigLLVMDIType **types_array, int types_array_len, unsigned flags);
    -
    -unsigned ZigLLVMEncoding_DW_ATE_unsigned(void);
    -unsigned ZigLLVMEncoding_DW_ATE_signed(void);
    -unsigned ZigLLVMEncoding_DW_ATE_float(void);
    -unsigned ZigLLVMEncoding_DW_ATE_boolean(void);
    -unsigned ZigLLVMEncoding_DW_ATE_unsigned_char(void);
    -unsigned ZigLLVMEncoding_DW_ATE_signed_char(void);
    -unsigned ZigLLVMLang_DW_LANG_C99(void);
    -unsigned ZigLLVMTag_DW_variable(void);
    -unsigned ZigLLVMTag_DW_structure_type(void);
    -unsigned ZigLLVMTag_DW_union_type(void);
    -
    -ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved);
    -void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module);
    -void ZigLLVMAddModuleCodeViewFlag(LLVMModuleRef module);
    -
    -void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, int line, int column, ZigLLVMDIScope *scope);
    -void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder);
    -
    -ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(ZigLLVMDILexicalBlock *lexical_block);
    -ZigLLVMDIScope *ZigLLVMCompileUnitToScope(ZigLLVMDICompileUnit *compile_unit);
    -ZigLLVMDIScope *ZigLLVMFileToScope(ZigLLVMDIFile *difile);
    -ZigLLVMDIScope *ZigLLVMSubprogramToScope(ZigLLVMDISubprogram *subprogram);
    -ZigLLVMDIScope *ZigLLVMTypeToScope(ZigLLVMDIType *type);
    -
    -ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder,
    -        ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,
    -        ZigLLVMDIType *type, bool always_preserve, unsigned flags);
    -
    -ZigLLVMDIGlobalVariable *ZigLLVMCreateGlobalVariable(ZigLLVMDIBuilder *dbuilder,
    -    ZigLLVMDIScope *scope, const char *name, const char *linkage_name, ZigLLVMDIFile *file,
    -    unsigned line_no, ZigLLVMDIType *di_type, bool is_local_to_unit);
    -
    -ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilder,
    -        ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,
    -        ZigLLVMDIType *type, bool always_preserve, unsigned flags, unsigned arg_no);
    -
    -ZigLLVMDILexicalBlock *ZigLLVMCreateLexicalBlock(ZigLLVMDIBuilder *dbuilder, ZigLLVMDIScope *scope,
    -        ZigLLVMDIFile *file, unsigned line, unsigned col);
    -
    -ZigLLVMDICompileUnit *ZigLLVMCreateCompileUnit(ZigLLVMDIBuilder *dibuilder,
    -        unsigned lang, ZigLLVMDIFile *difile, const char *producer,
    -        bool is_optimized, const char *flags, unsigned runtime_version, const char *split_name,
    -        uint64_t dwo_id, bool emit_debug_info);
    -
    -ZigLLVMDIFile *ZigLLVMCreateFile(ZigLLVMDIBuilder *dibuilder, const char *filename, const char *directory);
    -
    -ZigLLVMDISubprogram *ZigLLVMCreateFunction(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
    -        const char *name, const char *linkage_name, ZigLLVMDIFile *file, unsigned lineno,
    -        ZigLLVMDIType *fn_di_type, bool is_local_to_unit, bool is_definition, unsigned scope_line,
    -        unsigned flags, bool is_optimized, ZigLLVMDISubprogram *decl_subprogram);
    -
    -void ZigLLVMFnSetSubprogram(LLVMValueRef fn, ZigLLVMDISubprogram *subprogram);
    -
    -void ZigLLVMDIBuilderFinalize(ZigLLVMDIBuilder *dibuilder);
    -
    -LLVMValueRef ZigLLVMInsertDeclareAtEnd(ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage,
    -        ZigLLVMDILocalVariable *var_info, ZigLLVMDILocation *debug_loc, LLVMBasicBlockRef basic_block_ref);
    -LLVMValueRef ZigLLVMInsertDeclare(ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage,
    -        ZigLLVMDILocalVariable *var_info, ZigLLVMDILocation *debug_loc, LLVMValueRef insert_before_instr);
    -ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScope *scope);
    -
    -void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state);
    -
    -void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value);
    -void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn);
    -
    -void ZigLLVMParseCommandLineOptions(int argc, const char *const *argv);
    -
    -
    -// copied from include/llvm/ADT/Triple.h
    -
    -enum ZigLLVM_ArchType {
    -    ZigLLVM_UnknownArch,
    -
    -    ZigLLVM_arm,            // ARM (little endian): arm, armv.*, xscale
    -    ZigLLVM_armeb,          // ARM (big endian): armeb
    -    ZigLLVM_aarch64,        // AArch64 (little endian): aarch64
    -    ZigLLVM_aarch64_be,     // AArch64 (big endian): aarch64_be
    -    ZigLLVM_arc,            // ARC: Synopsys ARC
    -    ZigLLVM_avr,            // AVR: Atmel AVR microcontroller
    -    ZigLLVM_bpfel,          // eBPF or extended BPF or 64-bit BPF (little endian)
    -    ZigLLVM_bpfeb,          // eBPF or extended BPF or 64-bit BPF (big endian)
    -    ZigLLVM_hexagon,        // Hexagon: hexagon
    -    ZigLLVM_mips,           // MIPS: mips, mipsallegrex
    -    ZigLLVM_mipsel,         // MIPSEL: mipsel, mipsallegrexel
    -    ZigLLVM_mips64,         // MIPS64: mips64
    -    ZigLLVM_mips64el,       // MIPS64EL: mips64el
    -    ZigLLVM_msp430,         // MSP430: msp430
    -    ZigLLVM_nios2,          // NIOSII: nios2
    -    ZigLLVM_ppc,            // PPC: powerpc
    -    ZigLLVM_ppc64,          // PPC64: powerpc64, ppu
    -    ZigLLVM_ppc64le,        // PPC64LE: powerpc64le
    -    ZigLLVM_r600,           // R600: AMD GPUs HD2XXX - HD6XXX
    -    ZigLLVM_amdgcn,         // AMDGCN: AMD GCN GPUs
    -    ZigLLVM_riscv32,        // RISC-V (32-bit): riscv32
    -    ZigLLVM_riscv64,        // RISC-V (64-bit): riscv64
    -    ZigLLVM_sparc,          // Sparc: sparc
    -    ZigLLVM_sparcv9,        // Sparcv9: Sparcv9
    -    ZigLLVM_sparcel,        // Sparc: (endianness = little). NB: 'Sparcle' is a CPU variant
    -    ZigLLVM_systemz,        // SystemZ: s390x
    -    ZigLLVM_tce,            // TCE (http://tce.cs.tut.fi/): tce
    -    ZigLLVM_tcele,          // TCE little endian (http://tce.cs.tut.fi/): tcele
    -    ZigLLVM_thumb,          // Thumb (little endian): thumb, thumbv.*
    -    ZigLLVM_thumbeb,        // Thumb (big endian): thumbeb
    -    ZigLLVM_x86,            // X86: i[3-9]86
    -    ZigLLVM_x86_64,         // X86-64: amd64, x86_64
    -    ZigLLVM_xcore,          // XCore: xcore
    -    ZigLLVM_nvptx,          // NVPTX: 32-bit
    -    ZigLLVM_nvptx64,        // NVPTX: 64-bit
    -    ZigLLVM_le32,           // le32: generic little-endian 32-bit CPU (PNaCl)
    -    ZigLLVM_le64,           // le64: generic little-endian 64-bit CPU (PNaCl)
    -    ZigLLVM_amdil,          // AMDIL
    -    ZigLLVM_amdil64,        // AMDIL with 64-bit pointers
    -    ZigLLVM_hsail,          // AMD HSAIL
    -    ZigLLVM_hsail64,        // AMD HSAIL with 64-bit pointers
    -    ZigLLVM_spir,           // SPIR: standard portable IR for OpenCL 32-bit version
    -    ZigLLVM_spir64,         // SPIR: standard portable IR for OpenCL 64-bit version
    -    ZigLLVM_kalimba,        // Kalimba: generic kalimba
    -    ZigLLVM_shave,          // SHAVE: Movidius vector VLIW processors
    -    ZigLLVM_lanai,          // Lanai: Lanai 32-bit
    -    ZigLLVM_wasm32,         // WebAssembly with 32-bit pointers
    -    ZigLLVM_wasm64,         // WebAssembly with 64-bit pointers
    -    ZigLLVM_renderscript32, // 32-bit RenderScript
    -    ZigLLVM_renderscript64, // 64-bit RenderScript
    -
    -    ZigLLVM_LastArchType = ZigLLVM_renderscript64
    -};
    -
    -enum ZigLLVM_SubArchType {
    -    ZigLLVM_NoSubArch,
    -
    -    ZigLLVM_ARMSubArch_v8_3a,
    -    ZigLLVM_ARMSubArch_v8_2a,
    -    ZigLLVM_ARMSubArch_v8_1a,
    -    ZigLLVM_ARMSubArch_v8,
    -    ZigLLVM_ARMSubArch_v8r,
    -    ZigLLVM_ARMSubArch_v8m_baseline,
    -    ZigLLVM_ARMSubArch_v8m_mainline,
    -    ZigLLVM_ARMSubArch_v7,
    -    ZigLLVM_ARMSubArch_v7em,
    -    ZigLLVM_ARMSubArch_v7m,
    -    ZigLLVM_ARMSubArch_v7s,
    -    ZigLLVM_ARMSubArch_v7k,
    -    ZigLLVM_ARMSubArch_v7ve,
    -    ZigLLVM_ARMSubArch_v6,
    -    ZigLLVM_ARMSubArch_v6m,
    -    ZigLLVM_ARMSubArch_v6k,
    -    ZigLLVM_ARMSubArch_v6t2,
    -    ZigLLVM_ARMSubArch_v5,
    -    ZigLLVM_ARMSubArch_v5te,
    -    ZigLLVM_ARMSubArch_v4t,
    -
    -    ZigLLVM_KalimbaSubArch_v3,
    -    ZigLLVM_KalimbaSubArch_v4,
    -    ZigLLVM_KalimbaSubArch_v5,
    -};
    -
    -enum ZigLLVM_VendorType {
    -    ZigLLVM_UnknownVendor,
    -
    -    ZigLLVM_Apple,
    -    ZigLLVM_PC,
    -    ZigLLVM_SCEI,
    -    ZigLLVM_BGP,
    -    ZigLLVM_BGQ,
    -    ZigLLVM_Freescale,
    -    ZigLLVM_IBM,
    -    ZigLLVM_ImaginationTechnologies,
    -    ZigLLVM_MipsTechnologies,
    -    ZigLLVM_NVIDIA,
    -    ZigLLVM_CSR,
    -    ZigLLVM_Myriad,
    -    ZigLLVM_AMD,
    -    ZigLLVM_Mesa,
    -    ZigLLVM_SUSE,
    -
    -    ZigLLVM_LastVendorType = ZigLLVM_SUSE
    -};
    -
    -enum ZigLLVM_OSType {
    -    ZigLLVM_UnknownOS,
    -
    -    ZigLLVM_Ananas,
    -    ZigLLVM_CloudABI,
    -    ZigLLVM_Darwin,
    -    ZigLLVM_DragonFly,
    -    ZigLLVM_FreeBSD,
    -    ZigLLVM_Fuchsia,
    -    ZigLLVM_IOS,
    -    ZigLLVM_KFreeBSD,
    -    ZigLLVM_Linux,
    -    ZigLLVM_Lv2,        // PS3
    -    ZigLLVM_MacOSX,
    -    ZigLLVM_NetBSD,
    -    ZigLLVM_OpenBSD,
    -    ZigLLVM_Solaris,
    -    ZigLLVM_Win32,
    -    ZigLLVM_Haiku,
    -    ZigLLVM_Minix,
    -    ZigLLVM_RTEMS,
    -    ZigLLVM_NaCl,       // Native Client
    -    ZigLLVM_CNK,        // BG/P Compute-Node Kernel
    -    ZigLLVM_Bitrig,
    -    ZigLLVM_AIX,
    -    ZigLLVM_CUDA,       // NVIDIA CUDA
    -    ZigLLVM_NVCL,       // NVIDIA OpenCL
    -    ZigLLVM_AMDHSA,     // AMD HSA Runtime
    -    ZigLLVM_PS4,
    -    ZigLLVM_ELFIAMCU,
    -    ZigLLVM_TvOS,       // Apple tvOS
    -    ZigLLVM_WatchOS,    // Apple watchOS
    -    ZigLLVM_Mesa3D,
    -    ZigLLVM_Contiki,
    -
    -    ZigLLVM_LastOSType = ZigLLVM_Contiki
    -};
    -
    -enum ZigLLVM_EnvironmentType {
    -    ZigLLVM_UnknownEnvironment,
    -
    -    ZigLLVM_GNU,
    -    ZigLLVM_GNUABIN32,
    -    ZigLLVM_GNUABI64,
    -    ZigLLVM_GNUEABI,
    -    ZigLLVM_GNUEABIHF,
    -    ZigLLVM_GNUX32,
    -    ZigLLVM_CODE16,
    -    ZigLLVM_EABI,
    -    ZigLLVM_EABIHF,
    -    ZigLLVM_Android,
    -    ZigLLVM_Musl,
    -    ZigLLVM_MuslEABI,
    -    ZigLLVM_MuslEABIHF,
    -
    -    ZigLLVM_MSVC,
    -    ZigLLVM_Itanium,
    -    ZigLLVM_Cygnus,
    -    ZigLLVM_AMDOpenCL,
    -    ZigLLVM_CoreCLR,
    -    ZigLLVM_OpenCL,
    -    ZigLLVM_Simulator,  // Simulator variants of other systems, e.g., Apple's iOS
    -
    -    ZigLLVM_LastEnvironmentType = ZigLLVM_Simulator
    -};
    -
    -enum ZigLLVM_ObjectFormatType {
    -    ZigLLVM_UnknownObjectFormat,
    -
    -    ZigLLVM_COFF,
    -    ZigLLVM_ELF,
    -    ZigLLVM_MachO,
    -    ZigLLVM_Wasm,
    -};
    -
    -const char *ZigLLVMGetArchTypeName(ZigLLVM_ArchType arch);
    -const char *ZigLLVMGetSubArchTypeName(ZigLLVM_SubArchType sub_arch);
    -const char *ZigLLVMGetVendorTypeName(ZigLLVM_VendorType vendor);
    -const char *ZigLLVMGetOSTypeName(ZigLLVM_OSType os);
    -const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type);
    -
    -/*
    - * This stuff is not LLVM API but it depends on the LLVM C++ API so we put it here.
    - */
    -struct Buf;
    -
    -bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag);
    -
    -void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *sub_arch_type,
    -        ZigLLVM_VendorType *vendor_type, ZigLLVM_OSType *os_type, ZigLLVM_EnvironmentType *environ_type,
    -        ZigLLVM_ObjectFormatType *oformat);
    -
    -#endif
    diff --git a/std/array_list.zig b/std/array_list.zig
    index 04db4dd280..db5581dc08 100644
    --- a/std/array_list.zig
    +++ b/std/array_list.zig
    @@ -1,6 +1,7 @@
    -const debug = @import("debug.zig");
    +const std = @import("index.zig");
    +const debug = std.debug;
     const assert = debug.assert;
    -const mem = @import("mem.zig");
    +const mem = std.mem;
     const Allocator = mem.Allocator;
     
     pub fn ArrayList(comptime T: type) -> type {
    diff --git a/std/base64.zig b/std/base64.zig
    index 840643b565..0b405b1f4c 100644
    --- a/std/base64.zig
    +++ b/std/base64.zig
    @@ -1,5 +1,6 @@
    -const assert = @import("debug.zig").assert;
    -const mem = @import("mem.zig");
    +const std = @import("index.zig");
    +const assert = std.debug.assert;
    +const mem = std.mem;
     
     pub const standard_alphabet_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     pub const standard_pad_char = '=';
    diff --git a/std/buffer.zig b/std/buffer.zig
    index 4f5d281f48..2bb395d0fb 100644
    --- a/std/buffer.zig
    +++ b/std/buffer.zig
    @@ -1,10 +1,11 @@
    -const debug = @import("debug.zig");
    -const mem = @import("mem.zig");
    +const std = @import("index.zig");
    +const debug = std.debug;
    +const mem = std.mem;
     const Allocator = mem.Allocator;
     const assert = debug.assert;
    -const ArrayList = @import("array_list.zig").ArrayList;
    +const ArrayList = std.ArrayList;
     
    -const fmt = @import("fmt/index.zig");
    +const fmt = std.fmt;
     
     /// A buffer that allocates memory and maintains a null byte at the end.
     pub const Buffer = struct {
    diff --git a/std/build.zig b/std/build.zig
    index 3a2079db15..bb5280837f 100644
    --- a/std/build.zig
    +++ b/std/build.zig
    @@ -784,6 +784,13 @@ const Target = union(enum) {
             };
         }
     
    +    pub fn libFileExt(self: &const Target) -> []const u8 {
    +        return switch (self.getOs()) {
    +            builtin.Os.windows => ".lib",
    +            else => ".a",
    +        };
    +    }
    +
         pub fn getOs(self: &const Target) -> builtin.Os {
             return switch (*self) {
                 Target.Native => builtin.os,
    diff --git a/std/cstr.zig b/std/cstr.zig
    index 445f7ab892..1610f12481 100644
    --- a/std/cstr.zig
    +++ b/std/cstr.zig
    @@ -1,5 +1,6 @@
    -const debug = @import("debug.zig");
    -const mem = @import("mem.zig");
    +const std = @import("index.zig");
    +const debug = std.debug;
    +const mem = std.mem;
     const assert = debug.assert;
     
     pub fn len(ptr: &const u8) -> usize {
    @@ -47,3 +48,57 @@ pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) -> %[]u8 {
         result[slice.len] = 0;
         return result;
     }
    +
    +pub const NullTerminated2DArray = struct {
    +    allocator: &mem.Allocator,
    +    byte_count: usize,
    +    ptr: ?&?&u8,
    +
    +    /// Takes N lists of strings, concatenates the lists together, and adds a null terminator
    +    /// Caller must deinit result
    +    pub fn fromSlices(allocator: &mem.Allocator, slices: []const []const []const u8) -> %NullTerminated2DArray {
    +        var new_len: usize = 1; // 1 for the list null
    +        var byte_count: usize = 0;
    +        for (slices) |slice| {
    +            new_len += slice.len;
    +            for (slice) |inner| {
    +                byte_count += inner.len;
    +            }
    +            byte_count += slice.len; // for the null terminators of inner
    +        }
    +
    +        const index_size = @sizeOf(usize) * new_len; // size of the ptrs
    +        byte_count += index_size;
    +
    +        const buf = %return allocator.alignedAlloc(u8, @alignOf(?&u8), byte_count);
    +        %defer allocator.free(buf);
    +
    +        var write_index = index_size;
    +        const index_buf = ([]?&u8)(buf);
    +
    +        var i: usize = 0;
    +        for (slices) |slice| {
    +            for (slice) |inner| {
    +                index_buf[i] = &buf[write_index];
    +                i += 1;
    +                mem.copy(u8, buf[write_index..], inner);
    +                write_index += inner.len;
    +                buf[write_index] = 0;
    +                write_index += 1;
    +            }
    +        }
    +        index_buf[i] = null;
    +
    +        return NullTerminated2DArray {
    +            .allocator = allocator,
    +            .byte_count = byte_count,
    +            .ptr = @ptrCast(?&?&u8, buf.ptr),
    +        };
    +    }
    +
    +    pub fn deinit(self: &NullTerminated2DArray) {
    +        const buf = @ptrCast(&u8, self.ptr);
    +        self.allocator.free(buf[0..self.byte_count]);
    +    }
    +};
    +
    diff --git a/std/debug/failing_allocator.zig b/std/debug/failing_allocator.zig
    new file mode 100644
    index 0000000000..9b12ff5cb7
    --- /dev/null
    +++ b/std/debug/failing_allocator.zig
    @@ -0,0 +1,64 @@
    +const std = @import("../index.zig");
    +const mem = std.mem;
    +
    +/// Allocator that fails after N allocations, useful for making sure out of
    +/// memory conditions are handled correctly.
    +pub const FailingAllocator = struct {
    +    allocator: mem.Allocator,
    +    index: usize,
    +    fail_index: usize,
    +    internal_allocator: &mem.Allocator,
    +    allocated_bytes: usize,
    +    freed_bytes: usize,
    +    deallocations: usize,
    +
    +    pub fn init(allocator: &mem.Allocator, fail_index: usize) -> FailingAllocator {
    +        return FailingAllocator {
    +            .internal_allocator = allocator,
    +            .fail_index = fail_index,
    +            .index = 0,
    +            .allocated_bytes = 0,
    +            .freed_bytes = 0,
    +            .deallocations = 0,
    +            .allocator = mem.Allocator {
    +                .allocFn = alloc,
    +                .reallocFn = realloc,
    +                .freeFn = free,
    +            },
    +        };
    +    }
    +
    +    fn alloc(allocator: &mem.Allocator, n: usize, alignment: u29) -> %[]u8 {
    +        const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
    +        if (self.index == self.fail_index) {
    +            return error.OutOfMemory;
    +        }
    +        const result = %return self.internal_allocator.allocFn(self.internal_allocator, n, alignment);
    +        self.allocated_bytes += result.len;
    +        self.index += 1;
    +        return result;
    +    }
    +
    +    fn realloc(allocator: &mem.Allocator, old_mem: []u8, new_size: usize, alignment: u29) -> %[]u8 {
    +        const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
    +        if (new_size <= old_mem.len) {
    +            self.freed_bytes += old_mem.len - new_size;
    +            return self.internal_allocator.reallocFn(self.internal_allocator, old_mem, new_size, alignment);
    +        }
    +        if (self.index == self.fail_index) {
    +            return error.OutOfMemory;
    +        }
    +        const result = %return self.internal_allocator.reallocFn(self.internal_allocator, old_mem, new_size, alignment);
    +        self.allocated_bytes += new_size - old_mem.len;
    +        self.deallocations += 1;
    +        self.index += 1;
    +        return result;
    +    }
    +
    +    fn free(allocator: &mem.Allocator, bytes: []u8) {
    +        const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
    +        self.freed_bytes += bytes.len;
    +        self.deallocations += 1;
    +        return self.internal_allocator.freeFn(self.internal_allocator, bytes);
    +    }
    +};
    diff --git a/std/debug.zig b/std/debug/index.zig
    similarity index 94%
    rename from std/debug.zig
    rename to std/debug/index.zig
    index a683b5ae15..251b6f6f93 100644
    --- a/std/debug.zig
    +++ b/std/debug/index.zig
    @@ -1,13 +1,15 @@
    -const std = @import("index.zig");
    +const std = @import("../index.zig");
     const math = std.math;
     const mem = std.mem;
     const io = std.io;
     const os = std.os;
    -const elf = @import("elf.zig");
    -const DW = @import("dwarf.zig");
    +const elf = std.elf;
    +const DW = std.dwarf;
     const ArrayList = std.ArrayList;
     const builtin = @import("builtin");
     
    +pub const FailingAllocator = @import("failing_allocator.zig").FailingAllocator;
    +
     error MissingDebugInfo;
     error InvalidDebugInfo;
     error UnsupportedDebugInfo;
    @@ -992,59 +994,3 @@ fn readILeb128(in_stream: &io.InStream) -> %i64 {
     pub const global_allocator = &global_fixed_allocator.allocator;
     var global_fixed_allocator = mem.FixedBufferAllocator.init(global_allocator_mem[0..]);
     var global_allocator_mem: [100 * 1024]u8 = undefined;
    -
    -/// Allocator that fails after N allocations, useful for making sure out of
    -/// memory conditions are handled correctly.
    -pub const FailingAllocator = struct {
    -    allocator: mem.Allocator,
    -    index: usize,
    -    fail_index: usize,
    -    internal_allocator: &mem.Allocator,
    -    allocated_bytes: usize,
    -
    -    pub fn init(allocator: &mem.Allocator, fail_index: usize) -> FailingAllocator {
    -        return FailingAllocator {
    -            .internal_allocator = allocator,
    -            .fail_index = fail_index,
    -            .index = 0,
    -            .allocated_bytes = 0,
    -            .allocator = mem.Allocator {
    -                .allocFn = alloc,
    -                .reallocFn = realloc,
    -                .freeFn = free,
    -            },
    -        };
    -    }
    -
    -    fn alloc(allocator: &mem.Allocator, n: usize, alignment: u29) -> %[]u8 {
    -        const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
    -        if (self.index == self.fail_index) {
    -            return error.OutOfMemory;
    -        }
    -        self.index += 1;
    -        const result = %return self.internal_allocator.allocFn(self.internal_allocator, n, alignment);
    -        self.allocated_bytes += result.len;
    -        return result;
    -    }
    -
    -    fn realloc(allocator: &mem.Allocator, old_mem: []u8, new_size: usize, alignment: u29) -> %[]u8 {
    -        const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
    -        if (new_size <= old_mem.len) {
    -            self.allocated_bytes -= old_mem.len - new_size;
    -            return self.internal_allocator.reallocFn(self.internal_allocator, old_mem, new_size, alignment);
    -        }
    -        if (self.index == self.fail_index) {
    -            return error.OutOfMemory;
    -        }
    -        self.index += 1;
    -        const result = %return self.internal_allocator.reallocFn(self.internal_allocator, old_mem, new_size, alignment);
    -        self.allocated_bytes += new_size - old_mem.len;
    -        return result;
    -    }
    -
    -    fn free(allocator: &mem.Allocator, bytes: []u8) {
    -        const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
    -        self.allocated_bytes -= bytes.len;
    -        return self.internal_allocator.freeFn(self.internal_allocator, bytes);
    -    }
    -};
    diff --git a/std/fmt/errol/index.zig b/std/fmt/errol/index.zig
    index 0a1ea7deef..ba4447c631 100644
    --- a/std/fmt/errol/index.zig
    +++ b/std/fmt/errol/index.zig
    @@ -1,10 +1,11 @@
    +const std = @import("../../index.zig");
     const enum3 = @import("enum3.zig").enum3;
     const enum3_data = @import("enum3.zig").enum3_data;
     const lookup_table = @import("lookup.zig").lookup_table;
     const HP = @import("lookup.zig").HP;
    -const math = @import("../../math/index.zig");
    -const mem = @import("../../mem.zig");
    -const assert = @import("../../debug.zig").assert;
    +const math = std.math;
    +const mem = std.mem;
    +const assert = std.debug.assert;
     
     pub const FloatDecimal = struct {
         digits: []u8,
    diff --git a/std/fmt/index.zig b/std/fmt/index.zig
    index fef968a1d5..550fa1ce1f 100644
    --- a/std/fmt/index.zig
    +++ b/std/fmt/index.zig
    @@ -1,7 +1,8 @@
    -const math = @import("../math/index.zig");
    -const debug = @import("../debug.zig");
    +const std = @import("../index.zig");
    +const math = std.math;
    +const debug = std.debug;
     const assert = debug.assert;
    -const mem = @import("../mem.zig");
    +const mem = std.mem;
     const builtin = @import("builtin");
     const errol3 = @import("errol/index.zig").errol3;
     
    diff --git a/std/hash_map.zig b/std/hash_map.zig
    index 837ee07423..cf83815798 100644
    --- a/std/hash_map.zig
    +++ b/std/hash_map.zig
    @@ -1,7 +1,8 @@
    -const debug = @import("debug.zig");
    +const std = @import("index.zig");
    +const debug = std.debug;
     const assert = debug.assert;
    -const math = @import("math/index.zig");
    -const mem = @import("mem.zig");
    +const math = std.math;
    +const mem = std.mem;
     const Allocator = mem.Allocator;
     const builtin = @import("builtin");
     
    diff --git a/std/heap.zig b/std/heap.zig
    index ec447c1aa8..6a78692ec6 100644
    --- a/std/heap.zig
    +++ b/std/heap.zig
    @@ -1,10 +1,11 @@
    -const debug = @import("debug.zig");
    +const std = @import("index.zig");
    +const debug = std.debug;
     const assert = debug.assert;
    -const mem = @import("mem.zig");
    -const os = @import("os/index.zig");
    +const mem = std.mem;
    +const os = std.os;
     const builtin = @import("builtin");
     const Os = builtin.Os;
    -const c = @import("c/index.zig");
    +const c = std.c;
     
     const Allocator = mem.Allocator;
     
    diff --git a/std/index.zig b/std/index.zig
    index 323eee203e..07da469b5e 100644
    --- a/std/index.zig
    +++ b/std/index.zig
    @@ -11,7 +11,7 @@ pub const base64 = @import("base64.zig");
     pub const build = @import("build.zig");
     pub const c = @import("c/index.zig");
     pub const cstr = @import("cstr.zig");
    -pub const debug = @import("debug.zig");
    +pub const debug = @import("debug/index.zig");
     pub const dwarf = @import("dwarf.zig");
     pub const elf = @import("elf.zig");
     pub const empty_import = @import("empty.zig");
    @@ -39,7 +39,7 @@ test "std" {
         _ = @import("build.zig");
         _ = @import("c/index.zig");
         _ = @import("cstr.zig");
    -    _ = @import("debug.zig");
    +    _ = @import("debug/index.zig");
         _ = @import("dwarf.zig");
         _ = @import("elf.zig");
         _ = @import("empty.zig");
    diff --git a/std/linked_list.zig b/std/linked_list.zig
    index f4b6d274c9..3c516dab7d 100644
    --- a/std/linked_list.zig
    +++ b/std/linked_list.zig
    @@ -1,6 +1,7 @@
    -const debug = @import("debug.zig");
    +const std = @import("index.zig");
    +const debug = std.debug;
     const assert = debug.assert;
    -const mem = @import("mem.zig");
    +const mem = std.mem;
     const Allocator = mem.Allocator;
     
     /// Generic doubly linked list.
    diff --git a/std/math/acos.zig b/std/math/acos.zig
    index 7690497da5..478d5a846d 100644
    --- a/std/math/acos.zig
    +++ b/std/math/acos.zig
    @@ -2,8 +2,9 @@
     //
     // - acos(x)   = nan if x < -1 or x > 1
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn acos(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/acosh.zig b/std/math/acosh.zig
    index 3b2c2c0f31..150bcd4543 100644
    --- a/std/math/acosh.zig
    +++ b/std/math/acosh.zig
    @@ -4,8 +4,9 @@
     // - acosh(nan) = nan
     
     const builtin = @import("builtin");
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn acosh(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/asin.zig b/std/math/asin.zig
    index c5d24c35e5..a0209be0c8 100644
    --- a/std/math/asin.zig
    +++ b/std/math/asin.zig
    @@ -3,8 +3,9 @@
     // - asin(+-0) = +-0
     // - asin(x)   = nan if x < -1 or x > 1
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn asin(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/asinh.zig b/std/math/asinh.zig
    index f963dae77b..d95565fc6d 100644
    --- a/std/math/asinh.zig
    +++ b/std/math/asinh.zig
    @@ -4,8 +4,9 @@
     // - asinh(+-inf) = +-inf
     // - asinh(nan)   = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn asinh(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/atan.zig b/std/math/atan.zig
    index cf244eb762..fbfade50a0 100644
    --- a/std/math/atan.zig
    +++ b/std/math/atan.zig
    @@ -3,8 +3,9 @@
     // - atan(+-0)   = +-0
     // - atan(+-inf) = +-pi/2
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn atan(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/atan2.zig b/std/math/atan2.zig
    index b3af18cd9e..11e1b8cd89 100644
    --- a/std/math/atan2.zig
    +++ b/std/math/atan2.zig
    @@ -18,8 +18,9 @@
     //  atan2(+inf, x)    = +pi/2
     //  atan2(-inf, x)    = -pi/2
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     fn atan2(comptime T: type, x: T, y: T) -> T {
         return switch (T) {
    diff --git a/std/math/atanh.zig b/std/math/atanh.zig
    index 13de90279b..e787506765 100644
    --- a/std/math/atanh.zig
    +++ b/std/math/atanh.zig
    @@ -4,8 +4,9 @@
     // - atanh(x)   = nan if |x| > 1 with signal
     // - atanh(nan) = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn atanh(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/cbrt.zig b/std/math/cbrt.zig
    index a8df75dff2..9725716f3b 100644
    --- a/std/math/cbrt.zig
    +++ b/std/math/cbrt.zig
    @@ -4,8 +4,9 @@
     // - cbrt(+-inf) = +-inf
     // - cbrt(nan)   = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn cbrt(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/ceil.zig b/std/math/ceil.zig
    index 8e27132e25..141b5c0fc5 100644
    --- a/std/math/ceil.zig
    +++ b/std/math/ceil.zig
    @@ -5,8 +5,9 @@
     // - ceil(nan)   = nan
     
     const builtin = @import("builtin");
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn ceil(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/copysign.zig b/std/math/copysign.zig
    index 05205e1a0e..ebf12313ff 100644
    --- a/std/math/copysign.zig
    +++ b/std/math/copysign.zig
    @@ -1,5 +1,6 @@
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn copysign(comptime T: type, x: T, y: T) -> T {
         return switch (T) {
    diff --git a/std/math/cos.zig b/std/math/cos.zig
    index 4c3b8e1282..a65ea1ace8 100644
    --- a/std/math/cos.zig
    +++ b/std/math/cos.zig
    @@ -4,8 +4,9 @@
     // - cos(nan)   = nan
     
     const builtin = @import("builtin");
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn cos(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/cosh.zig b/std/math/cosh.zig
    index 6d40d71b8d..05565d6b3a 100644
    --- a/std/math/cosh.zig
    +++ b/std/math/cosh.zig
    @@ -5,9 +5,10 @@
     // - cosh(nan)   = nan
     
     const builtin = @import("builtin");
    -const math = @import("index.zig");
    +const std = @import("../index.zig");
    +const math = std.math;
     const expo2 = @import("expo2.zig").expo2;
    -const assert = @import("../debug.zig").assert;
    +const assert = std.debug.assert;
     
     pub fn cosh(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/exp.zig b/std/math/exp.zig
    index 6e591daea3..4cce18ffe5 100644
    --- a/std/math/exp.zig
    +++ b/std/math/exp.zig
    @@ -3,8 +3,9 @@
     // - exp(+inf) = +inf
     // - exp(nan)  = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn exp(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/exp2.zig b/std/math/exp2.zig
    index 6061f32391..4ce7de909e 100644
    --- a/std/math/exp2.zig
    +++ b/std/math/exp2.zig
    @@ -3,8 +3,9 @@
     // - exp2(+inf) = +inf
     // - exp2(nan)  = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn exp2(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/expm1.zig b/std/math/expm1.zig
    index fbe1841030..10670c4cfc 100644
    --- a/std/math/expm1.zig
    +++ b/std/math/expm1.zig
    @@ -4,8 +4,9 @@
     // - expm1(-inf) = -1
     // - expm1(nan)  = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn expm1(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/fabs.zig b/std/math/fabs.zig
    index cf1b8f1f14..dc1184dcc8 100644
    --- a/std/math/fabs.zig
    +++ b/std/math/fabs.zig
    @@ -3,8 +3,9 @@
     // - fabs(+-inf) = +inf
     // - fabs(nan)   = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn fabs(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/floor.zig b/std/math/floor.zig
    index d7de45e9d0..910dfd1901 100644
    --- a/std/math/floor.zig
    +++ b/std/math/floor.zig
    @@ -5,8 +5,9 @@
     // - floor(nan)   = nan
     
     const builtin = @import("builtin");
    -const assert = @import("../debug.zig").assert;
    -const math = @import("index.zig");
    +const assert = std.debug.assert;
    +const std = @import("../index.zig");
    +const math = std.math;
     
     pub fn floor(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/fma.zig b/std/math/fma.zig
    index 8e5adc80b2..b48cfc83b2 100644
    --- a/std/math/fma.zig
    +++ b/std/math/fma.zig
    @@ -1,5 +1,6 @@
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn fma(comptime T: type, x: T, y: T, z: T) -> T {
         return switch (T) {
    diff --git a/std/math/frexp.zig b/std/math/frexp.zig
    index 1a317a2c80..a90121e5fe 100644
    --- a/std/math/frexp.zig
    +++ b/std/math/frexp.zig
    @@ -4,8 +4,9 @@
     // - frexp(+-inf) = +-inf, 0
     // - frexp(nan)   = nan, undefined
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     fn frexp_result(comptime T: type) -> type {
         return struct {
    diff --git a/std/math/hypot.zig b/std/math/hypot.zig
    index 9b09ed53a4..6c0039b176 100644
    --- a/std/math/hypot.zig
    +++ b/std/math/hypot.zig
    @@ -5,8 +5,9 @@
     // - hypot(nan, y)    = nan
     // - hypot(x, nan)    = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn hypot(comptime T: type, x: T, y: T) -> T {
         return switch (T) {
    diff --git a/std/math/ilogb.zig b/std/math/ilogb.zig
    index 41a1e2d83f..db8e24d6c8 100644
    --- a/std/math/ilogb.zig
    +++ b/std/math/ilogb.zig
    @@ -4,8 +4,9 @@
     // - ilogb(0)     = @maxValue(i32)
     // - ilogb(nan)   = @maxValue(i32)
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn ilogb(x: var) -> i32 {
         const T = @typeOf(x);
    diff --git a/std/math/index.zig b/std/math/index.zig
    index 1991864f69..d382154059 100644
    --- a/std/math/index.zig
    +++ b/std/math/index.zig
    @@ -1,6 +1,7 @@
     const builtin = @import("builtin");
    +const std = @import("../index.zig");
     const TypeId = builtin.TypeId;
    -const assert = @import("../debug.zig").assert;
    +const assert = std.debug.assert;
     
     pub const e = 2.71828182845904523536028747135266249775724709369995;
     pub const pi = 3.14159265358979323846264338327950288419716939937510;
    diff --git a/std/math/inf.zig b/std/math/inf.zig
    index 546e6f3af8..b253124c84 100644
    --- a/std/math/inf.zig
    +++ b/std/math/inf.zig
    @@ -1,5 +1,6 @@
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn inf(comptime T: type) -> T {
         return switch (T) {
    diff --git a/std/math/isfinite.zig b/std/math/isfinite.zig
    index d44d373cf1..67fcf3cd18 100644
    --- a/std/math/isfinite.zig
    +++ b/std/math/isfinite.zig
    @@ -1,5 +1,6 @@
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn isFinite(x: var) -> bool {
         const T = @typeOf(x);
    diff --git a/std/math/isinf.zig b/std/math/isinf.zig
    index 98c90e72a9..75529fbb5e 100644
    --- a/std/math/isinf.zig
    +++ b/std/math/isinf.zig
    @@ -1,5 +1,6 @@
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn isInf(x: var) -> bool {
         const T = @typeOf(x);
    diff --git a/std/math/isnan.zig b/std/math/isnan.zig
    index e996a72693..d494dddca8 100644
    --- a/std/math/isnan.zig
    +++ b/std/math/isnan.zig
    @@ -1,5 +1,6 @@
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn isNan(x: var) -> bool {
         const T = @typeOf(x);
    diff --git a/std/math/isnormal.zig b/std/math/isnormal.zig
    index f815c2680b..4d07bf4cb3 100644
    --- a/std/math/isnormal.zig
    +++ b/std/math/isnormal.zig
    @@ -1,5 +1,6 @@
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn isNormal(x: var) -> bool {
         const T = @typeOf(x);
    diff --git a/std/math/ln.zig b/std/math/ln.zig
    index 4ded89d328..c5a5c93842 100644
    --- a/std/math/ln.zig
    +++ b/std/math/ln.zig
    @@ -5,8 +5,9 @@
     // - ln(x)     = nan if x < 0
     // - ln(nan)   = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     const builtin = @import("builtin");
     const TypeId = builtin.TypeId;
     
    diff --git a/std/math/log.zig b/std/math/log.zig
    index 1ff226f7e5..4edb77bb1a 100644
    --- a/std/math/log.zig
    +++ b/std/math/log.zig
    @@ -1,7 +1,8 @@
    -const math = @import("index.zig");
    +const std = @import("../index.zig");
    +const math = std.math;
     const builtin = @import("builtin");
     const TypeId = builtin.TypeId;
    -const assert = @import("../debug.zig").assert;
    +const assert = std.debug.assert;
     
     pub fn log(comptime T: type, base: T, x: T) -> T {
         if (base == 2) {
    diff --git a/std/math/log10.zig b/std/math/log10.zig
    index 73168dec8d..0b6fc31aa7 100644
    --- a/std/math/log10.zig
    +++ b/std/math/log10.zig
    @@ -5,8 +5,9 @@
     // - log10(x)     = nan if x < 0
     // - log10(nan)   = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     const builtin = @import("builtin");
     const TypeId = builtin.TypeId;
     
    diff --git a/std/math/log1p.zig b/std/math/log1p.zig
    index b369385038..ce5aad1d85 100644
    --- a/std/math/log1p.zig
    +++ b/std/math/log1p.zig
    @@ -6,8 +6,9 @@
     // - log1p(x)     = nan if x < -1
     // - log1p(nan)   = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn log1p(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/log2.zig b/std/math/log2.zig
    index 1b38a9ecee..a9789e47cf 100644
    --- a/std/math/log2.zig
    +++ b/std/math/log2.zig
    @@ -5,8 +5,9 @@
     // - log2(x)     = nan if x < 0
     // - log2(nan)   = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     const builtin = @import("builtin");
     const TypeId = builtin.TypeId;
     
    diff --git a/std/math/modf.zig b/std/math/modf.zig
    index 72730b67d7..dc17f35b54 100644
    --- a/std/math/modf.zig
    +++ b/std/math/modf.zig
    @@ -3,8 +3,9 @@
     // - modf(+-inf) = +-inf, nan
     // - modf(nan)   = nan, nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     fn modf_result(comptime T: type) -> type {
         return struct {
    diff --git a/std/math/pow.zig b/std/math/pow.zig
    index 55a2cd8c3e..b21fb3a921 100644
    --- a/std/math/pow.zig
    +++ b/std/math/pow.zig
    @@ -22,8 +22,9 @@
     //  pow(x, y)      = nan for finite x < 0 and finite non-integer y
     
     const builtin = @import("builtin");
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     // This implementation is taken from the go stlib, musl is a bit more complex.
     pub fn pow(comptime T: type, x: T, y: T) -> T {
    diff --git a/std/math/round.zig b/std/math/round.zig
    index 1e193fb1d7..3abee040ef 100644
    --- a/std/math/round.zig
    +++ b/std/math/round.zig
    @@ -5,8 +5,9 @@
     // - round(nan)   = nan
     
     const builtin = @import("builtin");
    -const assert = @import("../debug.zig").assert;
    -const math = @import("index.zig");
    +const assert = std.debug.assert;
    +const std = @import("../index.zig");
    +const math = std.math;
     
     pub fn round(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/scalbn.zig b/std/math/scalbn.zig
    index 0be6a3d47e..6d1c776593 100644
    --- a/std/math/scalbn.zig
    +++ b/std/math/scalbn.zig
    @@ -1,5 +1,6 @@
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn scalbn(x: var, n: i32) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/signbit.zig b/std/math/signbit.zig
    index b8ccecfa1b..b9bfe818de 100644
    --- a/std/math/signbit.zig
    +++ b/std/math/signbit.zig
    @@ -1,5 +1,6 @@
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn signbit(x: var) -> bool {
         const T = @typeOf(x);
    diff --git a/std/math/sin.zig b/std/math/sin.zig
    index 392bef1bc0..99008af469 100644
    --- a/std/math/sin.zig
    +++ b/std/math/sin.zig
    @@ -5,8 +5,9 @@
     // - sin(nan)   = nan
     
     const builtin = @import("builtin");
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn sin(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/sinh.zig b/std/math/sinh.zig
    index 4c575f10ec..ca06bc615a 100644
    --- a/std/math/sinh.zig
    +++ b/std/math/sinh.zig
    @@ -5,8 +5,9 @@
     // - sinh(nan)   = nan
     
     const builtin = @import("builtin");
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     const expo2 = @import("expo2.zig").expo2;
     
     pub fn sinh(x: var) -> @typeOf(x) {
    diff --git a/std/math/sqrt.zig b/std/math/sqrt.zig
    index 263e616617..4d84756b4a 100644
    --- a/std/math/sqrt.zig
    +++ b/std/math/sqrt.zig
    @@ -5,8 +5,9 @@
     // - sqrt(x)     = nan if x < 0
     // - sqrt(nan)   = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     const builtin = @import("builtin");
     const TypeId = builtin.TypeId;
     
    diff --git a/std/math/tan.zig b/std/math/tan.zig
    index ff53a758b4..e62e9b8899 100644
    --- a/std/math/tan.zig
    +++ b/std/math/tan.zig
    @@ -5,8 +5,9 @@
     // - tan(nan)   = nan
     
     const builtin = @import("builtin");
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn tan(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/math/tanh.zig b/std/math/tanh.zig
    index 7715029361..813b4f4561 100644
    --- a/std/math/tanh.zig
    +++ b/std/math/tanh.zig
    @@ -5,8 +5,9 @@
     // - sinh(nan)   = nan
     
     const builtin = @import("builtin");
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     const expo2 = @import("expo2.zig").expo2;
     
     pub fn tanh(x: var) -> @typeOf(x) {
    diff --git a/std/math/trunc.zig b/std/math/trunc.zig
    index 81eacb30ba..1d9032a22c 100644
    --- a/std/math/trunc.zig
    +++ b/std/math/trunc.zig
    @@ -4,8 +4,9 @@
     // - trunc(+-inf) = +-inf
     // - trunc(nan)   = nan
     
    -const math = @import("index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const math = std.math;
    +const assert = std.debug.assert;
     
     pub fn trunc(x: var) -> @typeOf(x) {
         const T = @typeOf(x);
    diff --git a/std/mem.zig b/std/mem.zig
    index 7438eba70a..41a4155b60 100644
    --- a/std/mem.zig
    +++ b/std/mem.zig
    @@ -1,6 +1,7 @@
    -const debug = @import("debug.zig");
    +const std = @import("index.zig");
    +const debug = std.debug;
     const assert = debug.assert;
    -const math = @import("math/index.zig");
    +const math = std.math;
     const builtin = @import("builtin");
     
     error OutOfMemory;
    diff --git a/std/net.zig b/std/net.zig
    index a5fd4d6036..da078eab3f 100644
    --- a/std/net.zig
    +++ b/std/net.zig
    @@ -1,6 +1,7 @@
    -const linux = @import("os/linux.zig");
    -const assert = @import("debug.zig").assert;
    -const endian = @import("endian.zig");
    +const std = @import("index.zig");
    +const linux = std.os.linux;
    +const assert = std.debug.assert;
    +const endian = std.endian;
     
     error SigInterrupt;
     error Io;
    diff --git a/std/os/darwin.zig b/std/os/darwin.zig
    index e230826b7e..7e3e5e823e 100644
    --- a/std/os/darwin.zig
    +++ b/std/os/darwin.zig
    @@ -1,5 +1,6 @@
    -const c = @import("../c/index.zig");
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const c = std.c;
    +const assert = std.debug.assert;
     
     pub use @import("darwin_errno.zig");
     
    diff --git a/std/os/index.zig b/std/os/index.zig
    index 8e79eda40b..0fd3f02e9a 100644
    --- a/std/os/index.zig
    +++ b/std/os/index.zig
    @@ -1,3 +1,4 @@
    +const std = @import("../index.zig");
     const builtin = @import("builtin");
     const Os = builtin.Os;
     const is_windows = builtin.os == Os.windows;
    @@ -37,22 +38,22 @@ pub const createWindowsEnvBlock = windows_util.createWindowsEnvBlock;
     
     pub const FileHandle = if (is_windows) windows.HANDLE else i32;
     
    -const debug = @import("../debug.zig");
    +const debug = std.debug;
     const assert = debug.assert;
     
    -const c = @import("../c/index.zig");
    +const c = std.c;
     
    -const mem = @import("../mem.zig");
    +const mem = std.mem;
     const Allocator = mem.Allocator;
     
    -const BufMap = @import("../buf_map.zig").BufMap;
    -const cstr = @import("../cstr.zig");
    +const BufMap = std.BufMap;
    +const cstr = std.cstr;
     
    -const io = @import("../io.zig");
    -const base64 = @import("../base64.zig");
    -const ArrayList = @import("../array_list.zig").ArrayList;
    -const Buffer = @import("../buffer.zig").Buffer;
    -const math = @import("../index.zig").math;
    +const io = std.io;
    +const base64 = std.base64;
    +const ArrayList = std.ArrayList;
    +const Buffer = std.Buffer;
    +const math = std.math;
     
     error SystemResources;
     error AccessDenied;
    diff --git a/std/os/linux.zig b/std/os/linux.zig
    index f9baa43098..c254f83d10 100644
    --- a/std/os/linux.zig
    +++ b/std/os/linux.zig
    @@ -1,4 +1,5 @@
    -const assert = @import("../debug.zig").assert;
    +const std = @import("../index.zig");
    +const assert = std.debug.assert;
     const builtin = @import("builtin");
     const arch = switch (builtin.arch) {
         builtin.Arch.x86_64 => @import("linux_x86_64.zig"),
    diff --git a/std/os/path.zig b/std/os/path.zig
    index db514add9c..9417cb4299 100644
    --- a/std/os/path.zig
    +++ b/std/os/path.zig
    @@ -1,16 +1,16 @@
    +const std = @import("../index.zig");
     const builtin = @import("builtin");
     const Os = builtin.Os;
    -const debug = @import("../debug.zig");
    +const debug = std.debug;
     const assert = debug.assert;
    -const mem = @import("../mem.zig");
    -const fmt = @import("../fmt/index.zig");
    +const mem = std.mem;
    +const fmt = std.fmt;
     const Allocator = mem.Allocator;
    -const os = @import("index.zig");
    -const math = @import("../math/index.zig");
    +const os = std.os;
    +const math = std.math;
     const posix = os.posix;
     const windows = os.windows;
    -const c = @import("../c/index.zig");
    -const cstr = @import("../cstr.zig");
    +const cstr = std.cstr;
     
     pub const sep_windows = '\\';
     pub const sep_posix = '/';
    diff --git a/std/rand.zig b/std/rand.zig
    index 73801a078f..f35229ea3c 100644
    --- a/std/rand.zig
    +++ b/std/rand.zig
    @@ -1,8 +1,9 @@
    +const std = @import("index.zig");
     const builtin = @import("builtin");
    -const assert = @import("debug.zig").assert;
    +const assert = std.debug.assert;
     const rand_test = @import("rand_test.zig");
    -const mem = @import("mem.zig");
    -const math = @import("math/index.zig");
    +const mem = std.mem;
    +const math = std.math;
     
     pub const MT19937_32 = MersenneTwister(
         u32, 624, 397, 31,
    diff --git a/std/special/compiler_rt/fixunsdfdi_test.zig b/std/special/compiler_rt/fixunsdfdi_test.zig
    index cb4a52b9ed..2a0e778ba3 100644
    --- a/std/special/compiler_rt/fixunsdfdi_test.zig
    +++ b/std/special/compiler_rt/fixunsdfdi_test.zig
    @@ -1,5 +1,5 @@
     const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi;
    -const assert = @import("../../debug.zig").assert;
    +const assert = @import("../../index.zig").debug.assert;
     
     fn test__fixunsdfdi(a: f64, expected: u64) {
         const x = __fixunsdfdi(a);
    diff --git a/std/special/compiler_rt/fixunsdfsi_test.zig b/std/special/compiler_rt/fixunsdfsi_test.zig
    index eef374773d..6116391391 100644
    --- a/std/special/compiler_rt/fixunsdfsi_test.zig
    +++ b/std/special/compiler_rt/fixunsdfsi_test.zig
    @@ -1,5 +1,5 @@
     const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi;
    -const assert = @import("../../debug.zig").assert;
    +const assert = @import("../../index.zig").debug.assert;
     
     fn test__fixunsdfsi(a: f64, expected: u32) {
         const x = __fixunsdfsi(a);
    diff --git a/std/special/compiler_rt/fixunsdfti_test.zig b/std/special/compiler_rt/fixunsdfti_test.zig
    index cd348fffde..dc7f1c29cd 100644
    --- a/std/special/compiler_rt/fixunsdfti_test.zig
    +++ b/std/special/compiler_rt/fixunsdfti_test.zig
    @@ -1,5 +1,5 @@
     const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti;
    -const assert = @import("../../debug.zig").assert;
    +const assert = @import("../../index.zig").debug.assert;
     
     fn test__fixunsdfti(a: f64, expected: u128) {
         const x = __fixunsdfti(a);
    diff --git a/std/special/compiler_rt/fixunssfdi_test.zig b/std/special/compiler_rt/fixunssfdi_test.zig
    index 67e3cd24c4..41827a0834 100644
    --- a/std/special/compiler_rt/fixunssfdi_test.zig
    +++ b/std/special/compiler_rt/fixunssfdi_test.zig
    @@ -1,5 +1,5 @@
     const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi;
    -const assert = @import("../../debug.zig").assert;
    +const assert = @import("../../index.zig").debug.assert;
     
     fn test__fixunssfdi(a: f32, expected: u64) {
         const x = __fixunssfdi(a);
    diff --git a/std/special/compiler_rt/fixunssfsi_test.zig b/std/special/compiler_rt/fixunssfsi_test.zig
    index bdb0339335..664c02ea73 100644
    --- a/std/special/compiler_rt/fixunssfsi_test.zig
    +++ b/std/special/compiler_rt/fixunssfsi_test.zig
    @@ -1,5 +1,5 @@
     const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi;
    -const assert = @import("../../debug.zig").assert;
    +const assert = @import("../../index.zig").debug.assert;
     
     fn test__fixunssfsi(a: f32, expected: u32) {
         const x = __fixunssfsi(a);
    diff --git a/std/special/compiler_rt/fixunssfti_test.zig b/std/special/compiler_rt/fixunssfti_test.zig
    index aaa7c70ab7..712df893c1 100644
    --- a/std/special/compiler_rt/fixunssfti_test.zig
    +++ b/std/special/compiler_rt/fixunssfti_test.zig
    @@ -1,5 +1,5 @@
     const __fixunssfti = @import("fixunssfti.zig").__fixunssfti;
    -const assert = @import("../../debug.zig").assert;
    +const assert = @import("../../index.zig").debug.assert;
     
     fn test__fixunssfti(a: f32, expected: u128) {
         const x = __fixunssfti(a);
    diff --git a/std/special/compiler_rt/fixunstfdi_test.zig b/std/special/compiler_rt/fixunstfdi_test.zig
    index c33062fad8..b5526f62a6 100644
    --- a/std/special/compiler_rt/fixunstfdi_test.zig
    +++ b/std/special/compiler_rt/fixunstfdi_test.zig
    @@ -1,5 +1,5 @@
     const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi;
    -const assert = @import("../../debug.zig").assert;
    +const assert = @import("../../index.zig").debug.assert;
     
     fn test__fixunstfdi(a: f128, expected: u64) {
         const x = __fixunstfdi(a);
    diff --git a/std/special/compiler_rt/fixunstfsi_test.zig b/std/special/compiler_rt/fixunstfsi_test.zig
    index 87bb1b9fa7..74b3507c44 100644
    --- a/std/special/compiler_rt/fixunstfsi_test.zig
    +++ b/std/special/compiler_rt/fixunstfsi_test.zig
    @@ -1,5 +1,5 @@
     const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi;
    -const assert = @import("../../debug.zig").assert;
    +const assert = @import("../../index.zig").debug.assert;
     
     fn test__fixunstfsi(a: f128, expected: u32) {
         const x = __fixunstfsi(a);
    diff --git a/std/special/compiler_rt/fixunstfti_test.zig b/std/special/compiler_rt/fixunstfti_test.zig
    index f18c39d04d..a6c9ea0f68 100644
    --- a/std/special/compiler_rt/fixunstfti_test.zig
    +++ b/std/special/compiler_rt/fixunstfti_test.zig
    @@ -1,5 +1,5 @@
     const __fixunstfti = @import("fixunstfti.zig").__fixunstfti;
    -const assert = @import("../../debug.zig").assert;
    +const assert = @import("../../index.zig").debug.assert;
     
     fn test__fixunstfti(a: f128, expected: u128) {
         const x = __fixunstfti(a);
    diff --git a/std/special/compiler_rt/index.zig b/std/special/compiler_rt/index.zig
    index 5e8c91c8d5..a554da5bf2 100644
    --- a/std/special/compiler_rt/index.zig
    +++ b/std/special/compiler_rt/index.zig
    @@ -68,7 +68,7 @@ comptime {
         }
     }
     
    -const assert = @import("../../debug.zig").assert;
    +const assert = @import("../../index.zig").debug.assert;
     
     const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
     
    diff --git a/test/cases/union.zig b/test/cases/union.zig
    index 90d869289f..6db43fc14b 100644
    --- a/test/cases/union.zig
    +++ b/test/cases/union.zig
    @@ -220,3 +220,18 @@ fn assertIsTheUnion2Item1(value: &const TheUnion2) {
         assert(*value == TheUnion2.Item1);
     }
     
    +
    +pub const PackThis = union(enum) {
    +    Invalid: bool,
    +    StringLiteral: u2,
    +};
    +
    +test "constant packed union" {
    +    testConstPackedUnion([]PackThis {
    +        PackThis { .StringLiteral = 1 },
    +    });
    +}
    +
    +fn testConstPackedUnion(expected_tokens: []const PackThis) {
    +    assert(expected_tokens[0].StringLiteral == 1);
    +}