Merge pull request #5378 from ziglang/speed-up-stage2-parsing
improve std.zig.parse performance using flat arrays for AST nodes and tokensmaster
commit
2ff3995a70
|
@ -776,7 +776,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
|||
next_tok_is_fn = false;
|
||||
|
||||
const token = tokenizer.next();
|
||||
try writeEscaped(out, src[index..token.start]);
|
||||
try writeEscaped(out, src[index..token.loc.start]);
|
||||
switch (token.id) {
|
||||
.Eof => break,
|
||||
|
||||
|
@ -827,13 +827,13 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
|||
.Keyword_while,
|
||||
=> {
|
||||
try out.writeAll("<span class=\"tok-kw\">");
|
||||
try writeEscaped(out, src[token.start..token.end]);
|
||||
try writeEscaped(out, src[token.loc.start..token.loc.end]);
|
||||
try out.writeAll("</span>");
|
||||
},
|
||||
|
||||
.Keyword_fn => {
|
||||
try out.writeAll("<span class=\"tok-kw\">");
|
||||
try writeEscaped(out, src[token.start..token.end]);
|
||||
try writeEscaped(out, src[token.loc.start..token.loc.end]);
|
||||
try out.writeAll("</span>");
|
||||
next_tok_is_fn = true;
|
||||
},
|
||||
|
@ -844,7 +844,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
|||
.Keyword_false,
|
||||
=> {
|
||||
try out.writeAll("<span class=\"tok-null\">");
|
||||
try writeEscaped(out, src[token.start..token.end]);
|
||||
try writeEscaped(out, src[token.loc.start..token.loc.end]);
|
||||
try out.writeAll("</span>");
|
||||
},
|
||||
|
||||
|
@ -853,13 +853,13 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
|||
.CharLiteral,
|
||||
=> {
|
||||
try out.writeAll("<span class=\"tok-str\">");
|
||||
try writeEscaped(out, src[token.start..token.end]);
|
||||
try writeEscaped(out, src[token.loc.start..token.loc.end]);
|
||||
try out.writeAll("</span>");
|
||||
},
|
||||
|
||||
.Builtin => {
|
||||
try out.writeAll("<span class=\"tok-builtin\">");
|
||||
try writeEscaped(out, src[token.start..token.end]);
|
||||
try writeEscaped(out, src[token.loc.start..token.loc.end]);
|
||||
try out.writeAll("</span>");
|
||||
},
|
||||
|
||||
|
@ -869,34 +869,34 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
|||
.ShebangLine,
|
||||
=> {
|
||||
try out.writeAll("<span class=\"tok-comment\">");
|
||||
try writeEscaped(out, src[token.start..token.end]);
|
||||
try writeEscaped(out, src[token.loc.start..token.loc.end]);
|
||||
try out.writeAll("</span>");
|
||||
},
|
||||
|
||||
.Identifier => {
|
||||
if (prev_tok_was_fn) {
|
||||
try out.writeAll("<span class=\"tok-fn\">");
|
||||
try writeEscaped(out, src[token.start..token.end]);
|
||||
try writeEscaped(out, src[token.loc.start..token.loc.end]);
|
||||
try out.writeAll("</span>");
|
||||
} else {
|
||||
const is_int = blk: {
|
||||
if (src[token.start] != 'i' and src[token.start] != 'u')
|
||||
if (src[token.loc.start] != 'i' and src[token.loc.start] != 'u')
|
||||
break :blk false;
|
||||
var i = token.start + 1;
|
||||
if (i == token.end)
|
||||
var i = token.loc.start + 1;
|
||||
if (i == token.loc.end)
|
||||
break :blk false;
|
||||
while (i != token.end) : (i += 1) {
|
||||
while (i != token.loc.end) : (i += 1) {
|
||||
if (src[i] < '0' or src[i] > '9')
|
||||
break :blk false;
|
||||
}
|
||||
break :blk true;
|
||||
};
|
||||
if (is_int or isType(src[token.start..token.end])) {
|
||||
if (is_int or isType(src[token.loc.start..token.loc.end])) {
|
||||
try out.writeAll("<span class=\"tok-type\">");
|
||||
try writeEscaped(out, src[token.start..token.end]);
|
||||
try writeEscaped(out, src[token.loc.start..token.loc.end]);
|
||||
try out.writeAll("</span>");
|
||||
} else {
|
||||
try writeEscaped(out, src[token.start..token.end]);
|
||||
try writeEscaped(out, src[token.loc.start..token.loc.end]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -905,7 +905,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
|||
.FloatLiteral,
|
||||
=> {
|
||||
try out.writeAll("<span class=\"tok-number\">");
|
||||
try writeEscaped(out, src[token.start..token.end]);
|
||||
try writeEscaped(out, src[token.loc.start..token.loc.end]);
|
||||
try out.writeAll("</span>");
|
||||
},
|
||||
|
||||
|
@ -963,7 +963,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
|||
.AngleBracketAngleBracketRight,
|
||||
.AngleBracketAngleBracketRightEqual,
|
||||
.Tilde,
|
||||
=> try writeEscaped(out, src[token.start..token.end]),
|
||||
=> try writeEscaped(out, src[token.loc.start..token.loc.end]),
|
||||
|
||||
.Invalid, .Invalid_ampersands => return parseError(
|
||||
docgen_tokenizer,
|
||||
|
@ -972,7 +972,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
|||
.{},
|
||||
),
|
||||
}
|
||||
index = token.end;
|
||||
index = token.loc.end;
|
||||
}
|
||||
try out.writeAll("</code>");
|
||||
}
|
||||
|
|
|
@ -46,13 +46,9 @@ pub const ArenaAllocator = struct {
|
|||
}
|
||||
|
||||
fn createNode(self: *ArenaAllocator, prev_len: usize, minimum_size: usize) !*BufNode {
|
||||
const actual_min_size = minimum_size + @sizeOf(BufNode);
|
||||
var len = prev_len;
|
||||
while (true) {
|
||||
len += len / 2;
|
||||
len += mem.page_size - @rem(len, mem.page_size);
|
||||
if (len >= actual_min_size) break;
|
||||
}
|
||||
const actual_min_size = minimum_size + (@sizeOf(BufNode) + 16);
|
||||
const big_enough_len = prev_len + actual_min_size;
|
||||
const len = big_enough_len + big_enough_len / 2;
|
||||
const buf = try self.child_allocator.alignedAlloc(u8, @alignOf(BufNode), len);
|
||||
const buf_node_slice = mem.bytesAsSlice(BufNode, buf[0..@sizeOf(BufNode)]);
|
||||
const buf_node = &buf_node_slice[0];
|
||||
|
|
|
@ -21,6 +21,8 @@ pub fn SinglyLinkedList(comptime T: type) type {
|
|||
next: ?*Node = null,
|
||||
data: T,
|
||||
|
||||
pub const Data = T;
|
||||
|
||||
pub fn init(data: T) Node {
|
||||
return Node{
|
||||
.data = data,
|
||||
|
@ -47,29 +49,30 @@ pub fn SinglyLinkedList(comptime T: type) type {
|
|||
node.next = next_node.next;
|
||||
return next_node;
|
||||
}
|
||||
|
||||
/// Iterate over the singly-linked list from this node, until the final node is found.
|
||||
/// This operation is O(N).
|
||||
pub fn findLast(node: *Node) *Node {
|
||||
var it = node;
|
||||
while (true) {
|
||||
it = it.next orelse return it;
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate over each next node, returning the count of all nodes except the starting one.
|
||||
/// This operation is O(N).
|
||||
pub fn countChildren(node: *const Node) usize {
|
||||
var count: usize = 0;
|
||||
var it: ?*const Node = node;
|
||||
while (it) |n| : (it = n.next) {
|
||||
count += 1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
};
|
||||
|
||||
first: ?*Node = null,
|
||||
|
||||
/// Initialize a linked list.
|
||||
///
|
||||
/// Returns:
|
||||
/// An empty linked list.
|
||||
pub fn init() Self {
|
||||
return Self{
|
||||
.first = null,
|
||||
};
|
||||
}
|
||||
|
||||
/// Insert a new node after an existing one.
|
||||
///
|
||||
/// Arguments:
|
||||
/// node: Pointer to a node in the list.
|
||||
/// new_node: Pointer to the new node to insert.
|
||||
pub fn insertAfter(list: *Self, node: *Node, new_node: *Node) void {
|
||||
node.insertAfter(new_node);
|
||||
}
|
||||
|
||||
/// Insert a new node at the head.
|
||||
///
|
||||
/// Arguments:
|
||||
|
@ -105,64 +108,33 @@ pub fn SinglyLinkedList(comptime T: type) type {
|
|||
return first;
|
||||
}
|
||||
|
||||
/// Allocate a new node.
|
||||
///
|
||||
/// Arguments:
|
||||
/// allocator: Dynamic memory allocator.
|
||||
///
|
||||
/// Returns:
|
||||
/// A pointer to the new node.
|
||||
pub fn allocateNode(list: *Self, allocator: *Allocator) !*Node {
|
||||
return allocator.create(Node);
|
||||
}
|
||||
|
||||
/// Deallocate a node.
|
||||
///
|
||||
/// Arguments:
|
||||
/// node: Pointer to the node to deallocate.
|
||||
/// allocator: Dynamic memory allocator.
|
||||
pub fn destroyNode(list: *Self, node: *Node, allocator: *Allocator) void {
|
||||
allocator.destroy(node);
|
||||
}
|
||||
|
||||
/// Allocate and initialize a node and its data.
|
||||
///
|
||||
/// Arguments:
|
||||
/// data: The data to put inside the node.
|
||||
/// allocator: Dynamic memory allocator.
|
||||
///
|
||||
/// Returns:
|
||||
/// A pointer to the new node.
|
||||
pub fn createNode(list: *Self, data: T, allocator: *Allocator) !*Node {
|
||||
var node = try list.allocateNode(allocator);
|
||||
node.* = Node.init(data);
|
||||
return node;
|
||||
/// Iterate over all nodes, returning the count.
|
||||
/// This operation is O(N).
|
||||
pub fn len(list: Self) usize {
|
||||
if (list.first) |n| {
|
||||
return 1 + n.countChildren();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test "basic SinglyLinkedList test" {
|
||||
const allocator = testing.allocator;
|
||||
var list = SinglyLinkedList(u32).init();
|
||||
const L = SinglyLinkedList(u32);
|
||||
var list = L{};
|
||||
|
||||
var one = try list.createNode(1, allocator);
|
||||
var two = try list.createNode(2, allocator);
|
||||
var three = try list.createNode(3, allocator);
|
||||
var four = try list.createNode(4, allocator);
|
||||
var five = try list.createNode(5, allocator);
|
||||
defer {
|
||||
list.destroyNode(one, allocator);
|
||||
list.destroyNode(two, allocator);
|
||||
list.destroyNode(three, allocator);
|
||||
list.destroyNode(four, allocator);
|
||||
list.destroyNode(five, allocator);
|
||||
}
|
||||
var one = L.Node{.data = 1};
|
||||
var two = L.Node{.data = 2};
|
||||
var three = L.Node{.data = 3};
|
||||
var four = L.Node{.data = 4};
|
||||
var five = L.Node{.data = 5};
|
||||
|
||||
list.prepend(two); // {2}
|
||||
list.insertAfter(two, five); // {2, 5}
|
||||
list.prepend(one); // {1, 2, 5}
|
||||
list.insertAfter(two, three); // {1, 2, 3, 5}
|
||||
list.insertAfter(three, four); // {1, 2, 3, 4, 5}
|
||||
list.prepend(&two); // {2}
|
||||
two.insertAfter(&five); // {2, 5}
|
||||
list.prepend(&one); // {1, 2, 5}
|
||||
two.insertAfter(&three); // {1, 2, 3, 5}
|
||||
three.insertAfter(&four); // {1, 2, 3, 4, 5}
|
||||
|
||||
// Traverse forwards.
|
||||
{
|
||||
|
@ -175,7 +147,7 @@ test "basic SinglyLinkedList test" {
|
|||
}
|
||||
|
||||
_ = list.popFirst(); // {2, 3, 4, 5}
|
||||
_ = list.remove(five); // {2, 3, 4}
|
||||
_ = list.remove(&five); // {2, 3, 4}
|
||||
_ = two.removeNext(); // {2, 4}
|
||||
|
||||
testing.expect(list.first.?.data == 2);
|
||||
|
|
|
@ -658,7 +658,7 @@ pub const Xoroshiro128 = struct {
|
|||
self.s[1] = s1;
|
||||
}
|
||||
|
||||
fn seed(self: *Xoroshiro128, init_s: u64) void {
|
||||
pub fn seed(self: *Xoroshiro128, init_s: u64) void {
|
||||
// Xoroshiro requires 128-bits of seed.
|
||||
var gen = SplitMix64.init(init_s);
|
||||
|
||||
|
|
|
@ -320,10 +320,11 @@ fn printWithVisibleNewlines(source: []const u8) void {
|
|||
}
|
||||
|
||||
fn printLine(line: []const u8) void {
|
||||
switch (line[line.len - 1]) {
|
||||
if (line.len != 0) switch (line[line.len - 1]) {
|
||||
' ', '\t' => warn("{}⏎\n", .{line}), // Carriage return symbol,
|
||||
else => warn("{}\n", .{line}),
|
||||
}
|
||||
else => {},
|
||||
};
|
||||
warn("{}\n", .{line});
|
||||
}
|
||||
|
||||
test "" {
|
||||
|
|
1120
lib/std/zig/ast.zig
1120
lib/std/zig/ast.zig
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -3180,9 +3180,8 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
|
|||
const tree = try std.zig.parse(allocator, source);
|
||||
defer tree.deinit();
|
||||
|
||||
var error_it = tree.errors.iterator(0);
|
||||
while (error_it.next()) |parse_error| {
|
||||
const token = tree.tokens.at(parse_error.loc());
|
||||
for (tree.errors) |*parse_error| {
|
||||
const token = tree.token_locs[parse_error.loc()];
|
||||
const loc = tree.tokenLocation(0, parse_error.loc());
|
||||
try stderr.print("(memory buffer):{}:{}: error: ", .{ loc.line + 1, loc.column + 1 });
|
||||
try tree.renderError(parse_error, stderr);
|
||||
|
@ -3271,8 +3270,6 @@ fn testError(source: []const u8, expected_errors: []const Error) !void {
|
|||
|
||||
std.testing.expect(tree.errors.len == expected_errors.len);
|
||||
for (expected_errors) |expected, i| {
|
||||
const err = tree.errors.at(i);
|
||||
|
||||
std.testing.expect(expected == err.*);
|
||||
std.testing.expect(expected == tree.errors[i]);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,8 +3,12 @@ const mem = std.mem;
|
|||
|
||||
pub const Token = struct {
|
||||
id: Id,
|
||||
start: usize,
|
||||
end: usize,
|
||||
loc: Loc,
|
||||
|
||||
pub const Loc = struct {
|
||||
start: usize,
|
||||
end: usize,
|
||||
};
|
||||
|
||||
pub const Keyword = struct {
|
||||
bytes: []const u8,
|
||||
|
@ -426,8 +430,10 @@ pub const Tokenizer = struct {
|
|||
var state: State = .start;
|
||||
var result = Token{
|
||||
.id = .Eof,
|
||||
.start = self.index,
|
||||
.end = undefined,
|
||||
.loc = .{
|
||||
.start = self.index,
|
||||
.end = undefined,
|
||||
},
|
||||
};
|
||||
var seen_escape_digits: usize = undefined;
|
||||
var remaining_code_units: usize = undefined;
|
||||
|
@ -436,7 +442,7 @@ pub const Tokenizer = struct {
|
|||
switch (state) {
|
||||
.start => switch (c) {
|
||||
' ', '\n', '\t', '\r' => {
|
||||
result.start = self.index + 1;
|
||||
result.loc.start = self.index + 1;
|
||||
},
|
||||
'"' => {
|
||||
state = .string_literal;
|
||||
|
@ -686,7 +692,7 @@ pub const Tokenizer = struct {
|
|||
.identifier => switch (c) {
|
||||
'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
|
||||
else => {
|
||||
if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {
|
||||
if (Token.getKeyword(self.buffer[result.loc.start..self.index])) |id| {
|
||||
result.id = id;
|
||||
}
|
||||
break;
|
||||
|
@ -1313,7 +1319,7 @@ pub const Tokenizer = struct {
|
|||
=> {},
|
||||
|
||||
.identifier => {
|
||||
if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {
|
||||
if (Token.getKeyword(self.buffer[result.loc.start..self.index])) |id| {
|
||||
result.id = id;
|
||||
}
|
||||
},
|
||||
|
@ -1420,7 +1426,7 @@ pub const Tokenizer = struct {
|
|||
}
|
||||
}
|
||||
|
||||
result.end = self.index;
|
||||
result.loc.end = self.index;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1430,8 +1436,10 @@ pub const Tokenizer = struct {
|
|||
if (invalid_length == 0) return;
|
||||
self.pending_invalid_token = .{
|
||||
.id = .Invalid,
|
||||
.start = self.index,
|
||||
.end = self.index + invalid_length,
|
||||
.loc = .{
|
||||
.start = self.index,
|
||||
.end = self.index + invalid_length,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ pub const struct_ZigClangCompoundStmt = @Type(.Opaque);
|
|||
pub const struct_ZigClangConstantArrayType = @Type(.Opaque);
|
||||
pub const struct_ZigClangContinueStmt = @Type(.Opaque);
|
||||
pub const struct_ZigClangDecayedType = @Type(.Opaque);
|
||||
pub const struct_ZigClangDecl = @Type(.Opaque);
|
||||
pub const ZigClangDecl = @Type(.Opaque);
|
||||
pub const struct_ZigClangDeclRefExpr = @Type(.Opaque);
|
||||
pub const struct_ZigClangDeclStmt = @Type(.Opaque);
|
||||
pub const struct_ZigClangDefaultStmt = @Type(.Opaque);
|
||||
|
@ -63,7 +63,7 @@ pub const struct_ZigClangReturnStmt = @Type(.Opaque);
|
|||
pub const struct_ZigClangSkipFunctionBodiesScope = @Type(.Opaque);
|
||||
pub const struct_ZigClangSourceManager = @Type(.Opaque);
|
||||
pub const struct_ZigClangSourceRange = @Type(.Opaque);
|
||||
pub const struct_ZigClangStmt = @Type(.Opaque);
|
||||
pub const ZigClangStmt = @Type(.Opaque);
|
||||
pub const struct_ZigClangStringLiteral = @Type(.Opaque);
|
||||
pub const struct_ZigClangStringRef = @Type(.Opaque);
|
||||
pub const struct_ZigClangSwitchStmt = @Type(.Opaque);
|
||||
|
@ -781,7 +781,7 @@ pub extern fn ZigClangSourceManager_getCharacterData(self: ?*const struct_ZigCla
|
|||
pub extern fn ZigClangASTContext_getPointerType(self: ?*const struct_ZigClangASTContext, T: struct_ZigClangQualType) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangASTUnit_getASTContext(self: ?*struct_ZigClangASTUnit) ?*struct_ZigClangASTContext;
|
||||
pub extern fn ZigClangASTUnit_getSourceManager(self: *struct_ZigClangASTUnit) *struct_ZigClangSourceManager;
|
||||
pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTUnit, context: ?*c_void, Fn: ?fn (?*c_void, *const struct_ZigClangDecl) callconv(.C) bool) bool;
|
||||
pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTUnit, context: ?*c_void, Fn: ?fn (?*c_void, *const ZigClangDecl) callconv(.C) bool) bool;
|
||||
pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) *const struct_ZigClangRecordDecl;
|
||||
pub extern fn ZigClangTagDecl_isThisDeclarationADefinition(self: *const ZigClangTagDecl) bool;
|
||||
pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) *const struct_ZigClangEnumDecl;
|
||||
|
@ -817,7 +817,7 @@ pub extern fn ZigClangEnumDecl_enumerator_end(*const ZigClangEnumDecl) ZigClangE
|
|||
pub extern fn ZigClangEnumDecl_enumerator_iterator_next(ZigClangEnumDecl_enumerator_iterator) ZigClangEnumDecl_enumerator_iterator;
|
||||
pub extern fn ZigClangEnumDecl_enumerator_iterator_deref(ZigClangEnumDecl_enumerator_iterator) *const ZigClangEnumConstantDecl;
|
||||
pub extern fn ZigClangEnumDecl_enumerator_iterator_neq(ZigClangEnumDecl_enumerator_iterator, ZigClangEnumDecl_enumerator_iterator) bool;
|
||||
pub extern fn ZigClangDecl_castToNamedDecl(decl: *const struct_ZigClangDecl) ?*const ZigClangNamedDecl;
|
||||
pub extern fn ZigClangDecl_castToNamedDecl(decl: *const ZigClangDecl) ?*const ZigClangNamedDecl;
|
||||
pub extern fn ZigClangNamedDecl_getName_bytes_begin(decl: ?*const struct_ZigClangNamedDecl) [*:0]const u8;
|
||||
pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: struct_ZigClangSourceLocation) bool;
|
||||
pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) *const struct_ZigClangTypedefNameDecl;
|
||||
|
@ -842,9 +842,9 @@ pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*
|
|||
pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType;
|
||||
pub extern fn ZigClangType_getAsRecordType(self: *const ZigClangType) ?*const ZigClangRecordType;
|
||||
pub extern fn ZigClangType_getAsUnionType(self: *const ZigClangType) ?*const ZigClangRecordType;
|
||||
pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;
|
||||
pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;
|
||||
pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;
|
||||
pub extern fn ZigClangStmt_getBeginLoc(self: *const ZigClangStmt) struct_ZigClangSourceLocation;
|
||||
pub extern fn ZigClangStmt_getStmtClass(self: ?*const ZigClangStmt) ZigClangStmtClass;
|
||||
pub extern fn ZigClangStmt_classof_Expr(self: ?*const ZigClangStmt) bool;
|
||||
pub extern fn ZigClangExpr_getStmtClass(self: *const struct_ZigClangExpr) ZigClangStmtClass;
|
||||
pub extern fn ZigClangExpr_getType(self: *const struct_ZigClangExpr) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;
|
||||
|
@ -873,7 +873,7 @@ pub extern fn ZigClangFunctionDecl_getLocation(self: *const ZigClangFunctionDecl
|
|||
pub extern fn ZigClangFunctionDecl_hasBody(self: *const ZigClangFunctionDecl) bool;
|
||||
pub extern fn ZigClangFunctionDecl_getStorageClass(self: *const ZigClangFunctionDecl) ZigClangStorageClass;
|
||||
pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const ZigClangFunctionDecl, i: c_uint) *const struct_ZigClangParmVarDecl;
|
||||
pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const struct_ZigClangStmt;
|
||||
pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const ZigClangStmt;
|
||||
pub extern fn ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(self: *const ZigClangFunctionDecl) bool;
|
||||
pub extern fn ZigClangFunctionDecl_isThisDeclarationADefinition(self: *const ZigClangFunctionDecl) bool;
|
||||
pub extern fn ZigClangFunctionDecl_doesThisDeclarationHaveABody(self: *const ZigClangFunctionDecl) bool;
|
||||
|
@ -918,7 +918,6 @@ pub const ZigClangCompoundStmt = struct_ZigClangCompoundStmt;
|
|||
pub const ZigClangConstantArrayType = struct_ZigClangConstantArrayType;
|
||||
pub const ZigClangContinueStmt = struct_ZigClangContinueStmt;
|
||||
pub const ZigClangDecayedType = struct_ZigClangDecayedType;
|
||||
pub const ZigClangDecl = struct_ZigClangDecl;
|
||||
pub const ZigClangDeclRefExpr = struct_ZigClangDeclRefExpr;
|
||||
pub const ZigClangDeclStmt = struct_ZigClangDeclStmt;
|
||||
pub const ZigClangDefaultStmt = struct_ZigClangDefaultStmt;
|
||||
|
@ -959,7 +958,6 @@ pub const ZigClangReturnStmt = struct_ZigClangReturnStmt;
|
|||
pub const ZigClangSkipFunctionBodiesScope = struct_ZigClangSkipFunctionBodiesScope;
|
||||
pub const ZigClangSourceManager = struct_ZigClangSourceManager;
|
||||
pub const ZigClangSourceRange = struct_ZigClangSourceRange;
|
||||
pub const ZigClangStmt = struct_ZigClangStmt;
|
||||
pub const ZigClangStringLiteral = struct_ZigClangStringLiteral;
|
||||
pub const ZigClangStringRef = struct_ZigClangStringRef;
|
||||
pub const ZigClangSwitchStmt = struct_ZigClangSwitchStmt;
|
||||
|
@ -1016,14 +1014,14 @@ pub extern fn ZigClangLoadFromCommandLine(
|
|||
) ?*ZigClangASTUnit;
|
||||
|
||||
pub extern fn ZigClangDecl_getKind(decl: *const ZigClangDecl) ZigClangDeclKind;
|
||||
pub extern fn ZigClangDecl_getDeclKindName(decl: *const struct_ZigClangDecl) [*:0]const u8;
|
||||
pub extern fn ZigClangDecl_getDeclKindName(decl: *const ZigClangDecl) [*:0]const u8;
|
||||
|
||||
pub const ZigClangCompoundStmt_const_body_iterator = [*]const *struct_ZigClangStmt;
|
||||
pub const ZigClangCompoundStmt_const_body_iterator = [*]const *ZigClangStmt;
|
||||
|
||||
pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
|
||||
pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
|
||||
|
||||
pub const ZigClangDeclStmt_const_decl_iterator = [*]const *struct_ZigClangDecl;
|
||||
pub const ZigClangDeclStmt_const_decl_iterator = [*]const *ZigClangDecl;
|
||||
|
||||
pub extern fn ZigClangDeclStmt_decl_begin(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator;
|
||||
pub extern fn ZigClangDeclStmt_decl_end(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator;
|
||||
|
|
|
@ -600,8 +600,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void {
|
|||
};
|
||||
defer tree.deinit();
|
||||
|
||||
var error_it = tree.errors.iterator(0);
|
||||
while (error_it.next()) |parse_error| {
|
||||
for (tree.errors) |parse_error| {
|
||||
try printErrMsgToFile(gpa, parse_error, tree, "<stdin>", stderr_file, color);
|
||||
}
|
||||
if (tree.errors.len != 0) {
|
||||
|
@ -701,8 +700,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
|
|||
};
|
||||
defer tree.deinit();
|
||||
|
||||
var error_it = tree.errors.iterator(0);
|
||||
while (error_it.next()) |parse_error| {
|
||||
for (tree.errors) |parse_error| {
|
||||
try printErrMsgToFile(fmt.gpa, parse_error, tree, file_path, std.io.getStdErr(), fmt.color);
|
||||
}
|
||||
if (tree.errors.len != 0) {
|
||||
|
@ -730,7 +728,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
|
|||
|
||||
fn printErrMsgToFile(
|
||||
gpa: *mem.Allocator,
|
||||
parse_error: *const ast.Error,
|
||||
parse_error: ast.Error,
|
||||
tree: *ast.Tree,
|
||||
path: []const u8,
|
||||
file: fs.File,
|
||||
|
@ -745,15 +743,15 @@ fn printErrMsgToFile(
|
|||
const span_first = lok_token;
|
||||
const span_last = lok_token;
|
||||
|
||||
const first_token = tree.tokens.at(span_first);
|
||||
const last_token = tree.tokens.at(span_last);
|
||||
const start_loc = tree.tokenLocationPtr(0, first_token);
|
||||
const end_loc = tree.tokenLocationPtr(first_token.end, last_token);
|
||||
const first_token = tree.token_locs[span_first];
|
||||
const last_token = tree.token_locs[span_last];
|
||||
const start_loc = tree.tokenLocationLoc(0, first_token);
|
||||
const end_loc = tree.tokenLocationLoc(first_token.end, last_token);
|
||||
|
||||
var text_buf = std.ArrayList(u8).init(gpa);
|
||||
defer text_buf.deinit();
|
||||
const out_stream = text_buf.outStream();
|
||||
try parse_error.render(&tree.tokens, out_stream);
|
||||
try parse_error.render(tree.token_ids, out_stream);
|
||||
const text = text_buf.span();
|
||||
|
||||
const stream = file.outStream();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3612,6 +3612,12 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
|
|||
auto entry = decls_scope->decl_table.put_unique(tld->name, tld);
|
||||
if (entry) {
|
||||
Tld *other_tld = entry->value;
|
||||
if (other_tld->id == TldIdVar) {
|
||||
ZigVar *var = reinterpret_cast<TldVar *>(other_tld)->var;
|
||||
if (var != nullptr && var->var_type != nullptr && type_is_invalid(var->var_type)) {
|
||||
return; // already reported compile error
|
||||
}
|
||||
}
|
||||
ErrorMsg *msg = add_node_error(g, tld->source_node, buf_sprintf("redefinition of '%s'", buf_ptr(tld->name)));
|
||||
add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition is here"));
|
||||
return;
|
||||
|
@ -3887,9 +3893,18 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
|
|||
if (search_scope != nullptr) {
|
||||
Tld *tld = find_decl(g, search_scope, name);
|
||||
if (tld != nullptr && tld != src_tld) {
|
||||
ErrorMsg *msg = add_node_error(g, source_node,
|
||||
buf_sprintf("redefinition of '%s'", buf_ptr(name)));
|
||||
add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here"));
|
||||
bool want_err_msg = true;
|
||||
if (tld->id == TldIdVar) {
|
||||
ZigVar *var = reinterpret_cast<TldVar *>(tld)->var;
|
||||
if (var != nullptr && var->var_type != nullptr && type_is_invalid(var->var_type)) {
|
||||
want_err_msg = false;
|
||||
}
|
||||
}
|
||||
if (want_err_msg) {
|
||||
ErrorMsg *msg = add_node_error(g, source_node,
|
||||
buf_sprintf("redefinition of '%s'", buf_ptr(name)));
|
||||
add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here"));
|
||||
}
|
||||
variable_entry->var_type = g->builtin_types.entry_invalid;
|
||||
}
|
||||
}
|
||||
|
|
15
src/ir.cpp
15
src/ir.cpp
|
@ -5300,9 +5300,18 @@ static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_s
|
|||
} else {
|
||||
Tld *tld = find_decl(codegen, parent_scope, name);
|
||||
if (tld != nullptr) {
|
||||
ErrorMsg *msg = add_node_error(codegen, node,
|
||||
buf_sprintf("redefinition of '%s'", buf_ptr(name)));
|
||||
add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here"));
|
||||
bool want_err_msg = true;
|
||||
if (tld->id == TldIdVar) {
|
||||
ZigVar *var = reinterpret_cast<TldVar *>(tld)->var;
|
||||
if (var != nullptr && var->var_type != nullptr && type_is_invalid(var->var_type)) {
|
||||
want_err_msg = false;
|
||||
}
|
||||
}
|
||||
if (want_err_msg) {
|
||||
ErrorMsg *msg = add_node_error(codegen, node,
|
||||
buf_sprintf("redefinition of '%s'", buf_ptr(name)));
|
||||
add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here"));
|
||||
}
|
||||
variable_entry->var_type = codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue