Skip to content

Commit

Permalink
Merge pull request #320 from ehaas/string-intern
Browse files Browse the repository at this point in the history
 String interning for identifiers
  • Loading branch information
Vexu authored Jul 20, 2022
2 parents 6aec5db + 0acf64c commit 365d3b5
Show file tree
Hide file tree
Showing 11 changed files with 413 additions and 281 deletions.
3 changes: 2 additions & 1 deletion src/Attribute.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1282,7 +1282,8 @@ fn applyTransparentUnion(attr: Attribute, p: *Parser, tok: TokenIndex, ty: Type)
for (fields[1..]) |field| {
const field_size = field.ty.bitSizeof(p.comp).?;
if (field_size == first_field_size) continue;
const str = try std.fmt.allocPrint(p.comp.diag.arena.allocator(), "'{s}' ({d}", .{ field.name, field_size });
const mapper = p.comp.string_interner.getSlowTypeMapper();
const str = try std.fmt.allocPrint(p.comp.diag.arena.allocator(), "'{s}' ({d}", .{ mapper.lookup(field.name), field_size });
try p.errStr(.transparent_union_size, field.name_tok, str);
return p.errExtra(.transparent_union_size_note, fields[0].name_tok, .{ .unsigned = first_field_size });
}
Expand Down
2 changes: 1 addition & 1 deletion src/Builtins.zig
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn add(
) void {
var params = a.alloc(Type.Func.Param, param_types.len) catch unreachable; // fib
for (param_types) |param_ty, i| {
params[i] = .{ .name_tok = 0, .ty = param_ty, .name = "" };
params[i] = .{ .name_tok = 0, .ty = param_ty, .name = .empty };
}
b.putAssumeCapacity(name, .{
.spec = spec,
Expand Down
40 changes: 24 additions & 16 deletions src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const Tokenizer = @import("Tokenizer.zig");
const Token = Tokenizer.Token;
const Type = @import("Type.zig");
const Pragma = @import("Pragma.zig");
const StringInterner = @import("StringInterner.zig");

const Compilation = @This();

Expand Down Expand Up @@ -41,6 +42,7 @@ types: struct {
} = undefined,
/// Mapping from Source.Id to byte offset of first non-utf8 byte
invalid_utf8_locs: std.AutoHashMapUnmanaged(Source.Id, u32) = .{},
string_interner: StringInterner = .{},

pub fn init(gpa: Allocator) Compilation {
return .{
Expand Down Expand Up @@ -72,6 +74,11 @@ pub fn deinit(comp: *Compilation) void {
comp.generated_buf.deinit();
comp.builtins.deinit(comp.gpa);
comp.invalid_utf8_locs.deinit(comp.gpa);
comp.string_interner.deinit(comp.gpa);
}

pub fn intern(comp: *Compilation, str: []const u8) !StringInterner.StringId {
return comp.string_interner.intern(comp.gpa, str);
}

fn generateDateAndTime(w: anytype) !void {
Expand Down Expand Up @@ -337,16 +344,17 @@ pub fn generateBuiltinMacros(comp: *Compilation) !Source {
// try comp.generateSizeofType(w, "__SIZEOF_WINT_T__", .{ .specifier = .pointer });

// various int types
try generateTypeMacro(w, "__PTRDIFF_TYPE__", comp.types.ptrdiff);
try generateTypeMacro(w, "__SIZE_TYPE__", comp.types.size);
try generateTypeMacro(w, "__WCHAR_TYPE__", comp.types.wchar);
const mapper = comp.string_interner.getSlowTypeMapper();
try generateTypeMacro(w, mapper, "__PTRDIFF_TYPE__", comp.types.ptrdiff);
try generateTypeMacro(w, mapper, "__SIZE_TYPE__", comp.types.size);
try generateTypeMacro(w, mapper, "__WCHAR_TYPE__", comp.types.wchar);

return comp.addSourceFromBuffer("<builtin>", buf.items);
}

fn generateTypeMacro(w: anytype, name: []const u8, ty: Type) !void {
fn generateTypeMacro(w: anytype, mapper: StringInterner.TypeMapper, name: []const u8, ty: Type) !void {
try w.print("#define {s} ", .{name});
try ty.print(w);
try ty.print(mapper, w);
try w.writeByte('\n');
}

Expand Down Expand Up @@ -422,7 +430,7 @@ fn generateVaListType(comp: *Compilation) !Type {
.aarch64_va_list => {
const record_ty = try arena.create(Type.Record);
record_ty.* = .{
.name = "__va_list_tag",
.name = try comp.intern("__va_list_tag"),
.fields = try arena.alloc(Type.Record.Field, 5),
.size = 32,
.alignment = 8,
Expand All @@ -431,17 +439,17 @@ fn generateVaListType(comp: *Compilation) !Type {
const void_ty = try arena.create(Type);
void_ty.* = .{ .specifier = .void };
const void_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = void_ty } };
record_ty.fields[0] = .{ .name = "__stack", .ty = void_ptr };
record_ty.fields[1] = .{ .name = "__gr_top", .ty = void_ptr };
record_ty.fields[2] = .{ .name = "__vr_top", .ty = void_ptr };
record_ty.fields[3] = .{ .name = "__gr_offs", .ty = .{ .specifier = .int } };
record_ty.fields[4] = .{ .name = "__vr_offs", .ty = .{ .specifier = .int } };
record_ty.fields[0] = .{ .name = try comp.intern("__stack"), .ty = void_ptr };
record_ty.fields[1] = .{ .name = try comp.intern("__gr_top"), .ty = void_ptr };
record_ty.fields[2] = .{ .name = try comp.intern("__vr_top"), .ty = void_ptr };
record_ty.fields[3] = .{ .name = try comp.intern("__gr_offs"), .ty = .{ .specifier = .int } };
record_ty.fields[4] = .{ .name = try comp.intern("__vr_offs"), .ty = .{ .specifier = .int } };
ty = .{ .specifier = .@"struct", .data = .{ .record = record_ty } };
},
.x86_64_va_list => {
const record_ty = try arena.create(Type.Record);
record_ty.* = .{
.name = "__va_list_tag",
.name = try comp.intern("__va_list_tag"),
.fields = try arena.alloc(Type.Record.Field, 4),
.size = 24,
.alignment = 8,
Expand All @@ -450,10 +458,10 @@ fn generateVaListType(comp: *Compilation) !Type {
const void_ty = try arena.create(Type);
void_ty.* = .{ .specifier = .void };
const void_ptr = Type{ .specifier = .pointer, .data = .{ .sub_type = void_ty } };
record_ty.fields[0] = .{ .name = "gp_offset", .ty = .{ .specifier = .uint } };
record_ty.fields[1] = .{ .name = "fp_offset", .ty = .{ .specifier = .uint } };
record_ty.fields[2] = .{ .name = "overflow_arg_area", .ty = void_ptr };
record_ty.fields[3] = .{ .name = "reg_save_area", .ty = void_ptr };
record_ty.fields[0] = .{ .name = try comp.intern("gp_offset"), .ty = .{ .specifier = .uint } };
record_ty.fields[1] = .{ .name = try comp.intern("fp_offset"), .ty = .{ .specifier = .uint } };
record_ty.fields[2] = .{ .name = try comp.intern("overflow_arg_area"), .ty = void_ptr };
record_ty.fields[3] = .{ .name = try comp.intern("reg_save_area"), .ty = void_ptr };
ty = .{ .specifier = .@"struct", .data = .{ .record = record_ty } };
},
}
Expand Down
Loading

0 comments on commit 365d3b5

Please sign in to comment.