| ... | ... | @@ -3,6 +3,7 @@ const Autodoc = @This(); |
| 3 | 3 | const Compilation = @import("Compilation.zig"); |
| 4 | 4 | const Module = @import("Module.zig"); |
| 5 | 5 | const Zir = @import("Zir.zig"); |
| 6 | const Ref = Zir.Inst.Ref; |
| 6 | 7 | |
| 7 | 8 | module: *Module, |
| 8 | 9 | doc_location: ?Compilation.EmitLoc, |
| ... | ... | @@ -53,12 +54,12 @@ pub fn generateZirData(self: *Autodoc) !void { |
| 53 | 54 | |
| 54 | 55 | // TODO: we don't want to add .none, but the index math has to check out |
| 55 | 56 | var i: u32 = 0; |
| 56 | | while (i <= @enumToInt(Zir.Inst.Ref.anyerror_void_error_union_type)) : (i += 1) { |
| 57 | while (i <= @enumToInt(Ref.anyerror_void_error_union_type)) : (i += 1) { |
| 57 | 58 | var tmpbuf = std.ArrayList(u8).init(self.arena); |
| 58 | | try Zir.Inst.Ref.typed_value_map[i].val.format("", .{}, tmpbuf.writer()); |
| 59 | try Ref.typed_value_map[i].val.format("", .{}, tmpbuf.writer()); |
| 59 | 60 | try self.types.append(self.arena, .{ |
| 60 | 61 | .name = tmpbuf.toOwnedSlice(), |
| 61 | | .kind = switch (@intToEnum(Zir.Inst.Ref, i)) { |
| 62 | .kind = switch (@intToEnum(Ref, i)) { |
| 62 | 63 | else => |t| blk: { |
| 63 | 64 | std.debug.print("TODO: categorize `{s}` in typeKinds\n", .{ |
| 64 | 65 | @tagName(t), |
| ... | ... | @@ -87,6 +88,7 @@ pub fn generateZirData(self: *Autodoc) !void { |
| 87 | 88 | .c_longlong_type, |
| 88 | 89 | .c_ulonglong_type, |
| 89 | 90 | .c_longdouble_type, |
| 91 | .comptime_int_type, |
| 90 | 92 | => @enumToInt(std.builtin.TypeId.Int), |
| 91 | 93 | .f16_type, |
| 92 | 94 | .f32_type, |
| ... | ... | @@ -234,7 +236,11 @@ const DocData = struct { |
| 234 | 236 | failure: bool, |
| 235 | 237 | type: usize, // index in `types` |
| 236 | 238 | decl_ref: usize, // index in `decls` |
| 237 | | |
| 239 | int: struct { |
| 240 | type: usize, // index in `types` |
| 241 | value: usize, // direct value |
| 242 | negated: bool = false, |
| 243 | }, |
| 238 | 244 | pub fn jsonStringify( |
| 239 | 245 | self: WalkResult, |
| 240 | 246 | _: std.json.StringifyOptions, |
| ... | ... | @@ -251,6 +257,12 @@ const DocData = struct { |
| 251 | 257 | \\{{ "{s}":{} }} |
| 252 | 258 | , .{ @tagName(self), v }); |
| 253 | 259 | }, |
| 260 | .int => |v| { |
| 261 | const neg = if (v.negated) "-" else ""; |
| 262 | try w.print( |
| 263 | \\{{ "int": {{ "type": {}, "value": {s}{} }} }} |
| 264 | , .{ v.type, neg, v.value }); |
| 265 | }, |
| 254 | 266 | |
| 255 | 267 | // .decl_ref => |v| { |
| 256 | 268 | // try w.print( |
| ... | ... | @@ -282,6 +294,31 @@ fn walkInstruction( |
| 282 | 294 | ); |
| 283 | 295 | return DocData.WalkResult{ .failure = true }; |
| 284 | 296 | }, |
| 297 | .int => { |
| 298 | const int = data[inst_index].int; |
| 299 | return DocData.WalkResult{ |
| 300 | .int = .{ |
| 301 | .type = @enumToInt(Ref.comptime_int_type), |
| 302 | .value = int, |
| 303 | }, |
| 304 | }; |
| 305 | }, |
| 306 | .negate => { |
| 307 | const un_node = data[inst_index].un_node; |
| 308 | var operand = try self.walkRef(zir, parent_scope, un_node.operand); |
| 309 | operand.int.negated = true; // only support ints for now |
| 310 | return operand; |
| 311 | }, |
| 312 | .as_node => { |
| 313 | const pl_node = data[inst_index].pl_node; |
| 314 | const extra = zir.extraData(Zir.Inst.As, pl_node.payload_index); |
| 315 | const dest_type_walk = try self.walkRef(zir, parent_scope, extra.data.dest_type); |
| 316 | const dest_type = dest_type_walk.type; // asserts that we got a type |
| 317 | |
| 318 | var operand = try self.walkRef(zir, parent_scope, extra.data.operand); |
| 319 | operand.int.type = dest_type; // only support ints for now |
| 320 | return operand; |
| 321 | }, |
| 285 | 322 | .decl_val => { |
| 286 | 323 | const str_tok = data[inst_index].str_tok; |
| 287 | 324 | const decls_slot_index = parent_scope.resolveDeclName(str_tok.start); |
| ... | ... | @@ -313,7 +350,7 @@ fn walkInstruction( |
| 313 | 350 | const break_operand = data[break_index].@"break".operand; |
| 314 | 351 | return if (Zir.refToIndex(break_operand)) |bi| |
| 315 | 352 | self.walkInstruction(zir, parent_scope, bi) |
| 316 | | else if (@enumToInt(break_operand) <= @enumToInt(Zir.Inst.Ref.anyerror_void_error_union_type)) |
| 353 | else if (@enumToInt(break_operand) <= @enumToInt(Ref.anyerror_void_error_union_type)) |
| 317 | 354 | // we append all the types in ref first, so we can just do this if we encounter a ref that is a type |
| 318 | 355 | return DocData.WalkResult{ .type = @enumToInt(break_operand) } |
| 319 | 356 | else |
| ... | ... | @@ -525,10 +562,15 @@ fn walkDecls( |
| 525 | 562 | try priv_decl_indexes.append(self.arena, decls_slot_index); |
| 526 | 563 | } |
| 527 | 564 | |
| 565 | const decl_type = switch (walk_result) { |
| 566 | .int => |i| i.type, |
| 567 | else => @enumToInt(Ref.type_type), |
| 568 | }; |
| 569 | |
| 528 | 570 | self.decls.items[decls_slot_index] = .{ |
| 529 | 571 | .name = name, |
| 530 | 572 | .src = ast_node_index, |
| 531 | | .type = @enumToInt(Zir.Inst.Ref.type_type), |
| 573 | .type = decl_type, |
| 532 | 574 | .value = walk_result, |
| 533 | 575 | .kind = "const", // find where this information can be found |
| 534 | 576 | }; |
| ... | ... | @@ -581,42 +623,8 @@ fn collectFieldInfo( |
| 581 | 623 | |
| 582 | 624 | // type |
| 583 | 625 | { |
| 584 | | switch (field_type) { |
| 585 | | .void_type => { |
| 586 | | try field_type_indexes.append(self.arena, .{ |
| 587 | | .type = self.types.items.len, |
| 588 | | }); |
| 589 | | try self.types.append(self.arena, .{ |
| 590 | | .kind = @enumToInt(std.builtin.TypeId.Void), |
| 591 | | .name = "void", |
| 592 | | }); |
| 593 | | }, |
| 594 | | .usize_type => { |
| 595 | | try field_type_indexes.append(self.arena, .{ .type = self.types.items.len }); |
| 596 | | try self.types.append(self.arena, .{ |
| 597 | | .kind = @enumToInt(std.builtin.TypeId.Int), |
| 598 | | .name = "usize", |
| 599 | | }); |
| 600 | | }, |
| 601 | | |
| 602 | | else => { |
| 603 | | const enum_value = @enumToInt(field_type); |
| 604 | | if (enum_value < Zir.Inst.Ref.typed_value_map.len) { |
| 605 | | try field_type_indexes.append( |
| 606 | | self.arena, |
| 607 | | DocData.WalkResult{ .type = enum_value }, |
| 608 | | ); |
| 609 | | } else { |
| 610 | | const zir_index = enum_value - Zir.Inst.Ref.typed_value_map.len; |
| 611 | | const walk_result = try self.walkInstruction( |
| 612 | | zir, |
| 613 | | scope, |
| 614 | | zir_index, |
| 615 | | ); |
| 616 | | try field_type_indexes.append(self.arena, walk_result); |
| 617 | | } |
| 618 | | }, |
| 619 | | } |
| 626 | const walk_result = try self.walkRef(zir, scope, field_type); |
| 627 | try field_type_indexes.append(self.arena, walk_result); |
| 620 | 628 | } |
| 621 | 629 | |
| 622 | 630 | // ast node |
| ... | ... | @@ -633,3 +641,19 @@ fn collectFieldInfo( |
| 633 | 641 | } |
| 634 | 642 | } |
| 635 | 643 | } |
| 644 | |
| 645 | fn walkRef( |
| 646 | self: *Autodoc, |
| 647 | zir: Zir, |
| 648 | parent_scope: *Scope, |
| 649 | ref: Ref, |
| 650 | ) !DocData.WalkResult { |
| 651 | const enum_value = @enumToInt(ref); |
| 652 | if (enum_value < Zir.Inst.Ref.typed_value_map.len) { |
| 653 | // TODO: well... Refs are not all types |
| 654 | return DocData.WalkResult{ .type = enum_value }; |
| 655 | } else { |
| 656 | const zir_index = enum_value - Ref.typed_value_map.len; |
| 657 | return self.walkInstruction(zir, parent_scope, zir_index); |
| 658 | } |
| 659 | } |