stage2: rework the C backend

* std.ArrayList gains `moveToUnmanaged` and dead code
   `ArrayListUnmanaged.appendWrite` is deleted.
 * emit_h state is attached to Module rather than Compilation.
 * remove the implementation of emit-h because it did not properly
   integrate with incremental compilation. I will re-implement it
   in a follow-up commit.
 * Compilation: use the .codegen_failure tag rather than
   .dependency_failure tag for when `bin_file.updateDecl` fails.

C backend:
 * Use a CValue tagged union instead of strings for C values.
 * Cleanly separate state into Object and DeclGen:
   - Object is present only when generating a .c file
   - DeclGen is present for both generating a .c and .h
 * Move some functions into their respective Object/DeclGen namespace.
 * Forward decls are managed by the incremental compilation frontend; C
   backend no longer renders function signatures based on callsites.
   For simplicity, all functions always get forward decls.
 * Constants are managed by the incremental compilation frontend. C
   backend no longer has a "constants" section.
 * Participate in incremental compilation. Each Decl gets an ArrayList
   for its generated C code and it is updated when the Decl is updated.
   During flush(), all these are joined together in the output file.
 * The new CValue tagged union is used to clean up using of assigning to
   locals without an additional pointer local.
 * Fix bug with bitcast of non-pointers making the memcpy destination
   immutable.
This commit is contained in:
Andrew Kelley
2021-01-05 11:08:34 -07:00
parent 9360e5887c
commit 7b8cede61f
9 changed files with 661 additions and 613 deletions

View File

@@ -94,6 +94,8 @@ stage1_flags: packed struct {
reserved: u2 = 0,
} = .{},
emit_h: ?Compilation.EmitLoc,
pub const Export = struct {
options: std.builtin.ExportOptions,
/// Byte offset into the file that contains the export directive.
@@ -1943,14 +1945,14 @@ fn allocateNewDecl(
.coff => .{ .coff = link.File.Coff.TextBlock.empty },
.elf => .{ .elf = link.File.Elf.TextBlock.empty },
.macho => .{ .macho = link.File.MachO.TextBlock.empty },
.c => .{ .c = {} },
.c => .{ .c = link.File.C.DeclBlock.empty },
.wasm => .{ .wasm = {} },
},
.fn_link = switch (self.comp.bin_file.tag) {
.coff => .{ .coff = {} },
.elf => .{ .elf = link.File.Elf.SrcFn.empty },
.macho => .{ .macho = link.File.MachO.SrcFn.empty },
.c => .{ .c = {} },
.c => .{ .c = link.File.C.FnBlock.empty },
.wasm => .{ .wasm = null },
},
.generation = 0,