Skip to content

Commit

Permalink
Type: clean up attribute handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ehaas committed Sep 4, 2024
1 parent 3da6f81 commit 5d4561a
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 182 deletions.
78 changes: 55 additions & 23 deletions src/aro/Attribute.zig
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,57 @@ pub const Kind = enum {
}
};

pub const Iterator = struct {
source: union(enum) {
ty: Type,
slice: []const Attribute,
},
index: usize,

pub fn initSlice(slice: ?[]const Attribute) Iterator {
return .{ .source = .{ .slice = slice orelse &.{} }, .index = 0 };
}

pub fn initType(ty: Type) Iterator {
return .{ .source = .{ .ty = ty }, .index = 0 };
}

/// returns the next attribute as well as its index within the slice or current type
/// The index can be used to determine when a nested type has been recursed into
pub fn next(self: *Iterator) ?struct { Attribute, usize } {
switch (self.source) {
.slice => |slice| {
if (self.index < slice.len) {
defer self.index += 1;
return .{ slice[self.index], self.index };
}
},
.ty => |ty| {
switch (ty.specifier) {
.typeof_type => {
self.* = .{ .source = .{ .ty = ty.data.sub_type.* }, .index = 0 };
return self.next();
},
.typeof_expr => {
self.* = .{ .source = .{ .ty = ty.data.expr.ty }, .index = 0 };
return self.next();
},
.attributed => {
if (self.index < ty.data.attributed.attributes.len) {
defer self.index += 1;
return .{ ty.data.attributed.attributes[self.index], self.index };
}
self.* = .{ .source = .{ .ty = ty.data.attributed.base }, .index = 0 };
return self.next();
},
else => {},
}
},
}
return null;
}
};

pub const ArgumentType = enum {
string,
identifier,
Expand Down Expand Up @@ -740,7 +791,6 @@ pub fn applyVariableAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag:
const toks = p.attr_buf.items(.tok)[attr_buf_start..];
p.attr_application_buf.items.len = 0;
var base_ty = ty;
if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
var common = false;
var nocommon = false;
for (attrs, toks) |attr, tok| switch (attr.tag) {
Expand Down Expand Up @@ -785,12 +835,7 @@ pub fn applyVariableAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag:
=> |t| try p.errExtra(.attribute_todo, tok, .{ .attribute_todo = .{ .tag = t, .kind = .variables } }),
else => try ignoredAttrErr(p, tok, attr.tag, "variables"),
};
const existing = ty.getAttributes();
if (existing.len == 0 and p.attr_application_buf.items.len == 0) return base_ty;
if (existing.len == 0) return base_ty.withAttributes(p.arena, p.attr_application_buf.items);

const attributed_type = try Type.Attributed.create(p.arena, base_ty, existing, p.attr_application_buf.items);
return Type{ .specifier = .attributed, .data = .{ .attributed = attributed_type } };
return base_ty.withAttributes(p.arena, p.attr_application_buf.items);
}

pub fn applyFieldAttributes(p: *Parser, field_ty: *Type, attr_buf_start: usize) ![]const Attribute {
Expand All @@ -815,7 +860,6 @@ pub fn applyTypeAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag: ?Di
const toks = p.attr_buf.items(.tok)[attr_buf_start..];
p.attr_application_buf.items.len = 0;
var base_ty = ty;
if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
for (attrs, toks) |attr, tok| switch (attr.tag) {
// zig fmt: off
.@"packed", .may_alias, .deprecated, .unavailable, .unused, .warn_if_not_aligned, .mode,
Expand All @@ -836,27 +880,14 @@ pub fn applyTypeAttributes(p: *Parser, ty: Type, attr_buf_start: usize, tag: ?Di
=> |t| try p.errExtra(.attribute_todo, tok, .{ .attribute_todo = .{ .tag = t, .kind = .types } }),
else => try ignoredAttrErr(p, tok, attr.tag, "types"),
};

const existing = ty.getAttributes();
// TODO: the alignment annotation on a type should override
// the decl it refers to. This might not be true for others. Maybe bug.

// if there are annotations on this type def use those.
if (p.attr_application_buf.items.len > 0) {
return try base_ty.withAttributes(p.arena, p.attr_application_buf.items);
} else if (existing.len > 0) {
// else use the ones on the typedef decl we were refering to.
return try base_ty.withAttributes(p.arena, existing);
}
return base_ty;
return base_ty.withAttributes(p.arena, p.attr_application_buf.items);
}

pub fn applyFunctionAttributes(p: *Parser, ty: Type, attr_buf_start: usize) !Type {
const attrs = p.attr_buf.items(.attr)[attr_buf_start..];
const toks = p.attr_buf.items(.tok)[attr_buf_start..];
p.attr_application_buf.items.len = 0;
var base_ty = ty;
if (base_ty.specifier == .attributed) base_ty = base_ty.data.attributed.base;
var hot = false;
var cold = false;
var @"noinline" = false;
Expand Down Expand Up @@ -1059,6 +1090,7 @@ fn applyTransparentUnion(attr: Attribute, p: *Parser, tok: TokenIndex, ty: Type)
}

fn applyVectorSize(attr: Attribute, p: *Parser, tok: TokenIndex, ty: *Type) !void {
const base = ty.base();
const is_enum = ty.is(.@"enum");
if (!(ty.isInt() or ty.isFloat()) or !ty.isReal() or (is_enum and p.comp.langopts.emulate == .gcc)) {
try p.errStr(.invalid_vec_elem_ty, tok, try p.typeStr(ty.*));
Expand All @@ -1075,7 +1107,7 @@ fn applyVectorSize(attr: Attribute, p: *Parser, tok: TokenIndex, ty: *Type) !voi

const arr_ty = try p.arena.create(Type.Array);
arr_ty.* = .{ .elem = ty.*, .len = vec_size };
ty.* = Type{
base.* = .{
.specifier = .vector,
.data = .{ .array = arr_ty },
};
Expand Down
6 changes: 1 addition & 5 deletions src/aro/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1037,10 +1037,8 @@ fn decl(p: *Parser) Error!bool {

// Collect old style parameter declarations.
if (init_d.d.old_style_func != null) {
const attrs = init_d.d.ty.getAttributes();
var base_ty = if (init_d.d.ty.specifier == .attributed) init_d.d.ty.data.attributed.base else init_d.d.ty;
var base_ty = init_d.d.ty.base();
base_ty.specifier = .func;
init_d.d.ty = try base_ty.withAttributes(p.arena, attrs);

const param_buf_top = p.param_buf.items.len;
defer p.param_buf.items.len = param_buf_top;
Expand Down Expand Up @@ -3901,8 +3899,6 @@ fn convertInitList(p: *Parser, il: InitList, init_ty: Type) Error!NodeIndex {
.specifier = .array,
.data = .{ .array = arr_ty },
};
const attrs = init_ty.getAttributes();
arr_init_node.ty = try arr_init_node.ty.withAttributes(p.arena, attrs);
} else if (start < max_items) {
const elem = try p.addNode(.{
.tag = .array_filler_expr,
Expand Down
4 changes: 3 additions & 1 deletion src/aro/Tree.zig
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,9 @@ fn dumpNode(

if (ty.specifier == .attributed) {
try config.setColor(w, ATTRIBUTE);
for (ty.data.attributed.attributes) |attr| {
var it = Attribute.Iterator.initType(ty);
while (it.next()) |item| {
const attr, _ = item;
try w.writeByteNTimes(' ', level + half);
try w.print("attr: {s}", .{@tagName(attr.tag)});
try tree.dumpAttribute(attr, w);
Expand Down
Loading

0 comments on commit 5d4561a

Please sign in to comment.