Merge pull request #4025 from ziglang/Vexu-stage-2-cimport

Use self hosted translate-c for cImport
This commit is contained in:
Andrew Kelley 2020-01-01 22:46:46 -05:00 committed by GitHub
commit 576320e6d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1382 additions and 7937 deletions

View File

@ -448,7 +448,6 @@ set(ZIG_SOURCES
"${CMAKE_SOURCE_DIR}/src/bigfloat.cpp" "${CMAKE_SOURCE_DIR}/src/bigfloat.cpp"
"${CMAKE_SOURCE_DIR}/src/bigint.cpp" "${CMAKE_SOURCE_DIR}/src/bigint.cpp"
"${CMAKE_SOURCE_DIR}/src/buffer.cpp" "${CMAKE_SOURCE_DIR}/src/buffer.cpp"
"${CMAKE_SOURCE_DIR}/src/c_tokenizer.cpp"
"${CMAKE_SOURCE_DIR}/src/cache_hash.cpp" "${CMAKE_SOURCE_DIR}/src/cache_hash.cpp"
"${CMAKE_SOURCE_DIR}/src/codegen.cpp" "${CMAKE_SOURCE_DIR}/src/codegen.cpp"
"${CMAKE_SOURCE_DIR}/src/compiler.cpp" "${CMAKE_SOURCE_DIR}/src/compiler.cpp"
@ -465,7 +464,6 @@ set(ZIG_SOURCES
"${CMAKE_SOURCE_DIR}/src/range_set.cpp" "${CMAKE_SOURCE_DIR}/src/range_set.cpp"
"${CMAKE_SOURCE_DIR}/src/target.cpp" "${CMAKE_SOURCE_DIR}/src/target.cpp"
"${CMAKE_SOURCE_DIR}/src/tokenizer.cpp" "${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"
"${CMAKE_SOURCE_DIR}/src/translate_c.cpp"
"${CMAKE_SOURCE_DIR}/src/util.cpp" "${CMAKE_SOURCE_DIR}/src/util.cpp"
"${ZIG_SOURCES_MEM_PROFILE}" "${ZIG_SOURCES_MEM_PROFILE}"
) )

View File

@ -224,7 +224,7 @@ test "crypto.chacha20 test vector sunscreen" {
// Chacha20 is self-reversing. // Chacha20 is self-reversing.
var plaintext: [114]u8 = undefined; var plaintext: [114]u8 = undefined;
chaCha20IETF(plaintext[0..], result[0..], 1, key, nonce); chaCha20IETF(plaintext[0..], result[0..], 1, key, nonce);
testing.expect(mem.compare(u8, input, &plaintext) == mem.Compare.Equal); testing.expect(mem.order(u8, input, &plaintext) == .eq);
} }
// https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7 // https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7

View File

@ -70,12 +70,12 @@ const HeaderEntry = struct {
} }
// Sort lexicographically on header name // Sort lexicographically on header name
return mem.compare(u8, a.name, b.name) == mem.Compare.LessThan; return mem.order(u8, a.name, b.name) == .lt;
} }
// Sort lexicographically on header value // Sort lexicographically on header value
if (!mem.eql(u8, a.value, b.value)) { if (!mem.eql(u8, a.value, b.value)) {
return mem.compare(u8, a.value, b.value) == mem.Compare.LessThan; return mem.order(u8, a.value, b.value) == .lt;
} }
// Doesn't matter here; need to pick something for sort consistency // Doesn't matter here; need to pick something for sort consistency

View File

@ -926,9 +926,6 @@ test "minInt and maxInt" {
} }
test "max value type" { test "max value type" {
// If the type of maxInt(i32) was i32 then this implicit cast to
// u32 would not work. But since the value is a number literal,
// it works fine.
const x: u32 = maxInt(i32); const x: u32 = maxInt(i32);
testing.expect(x == 2147483647); testing.expect(x == 2147483647);
} }
@ -944,7 +941,32 @@ test "math.mulWide" {
testing.expect(mulWide(u8, 100, 100) == 10000); testing.expect(mulWide(u8, 100, 100) == 10000);
} }
/// Not to be confused with `std.mem.Compare`. /// See also `CompareOperator`.
pub const Order = enum {
/// Less than (`<`)
lt,
/// Equal (`==`)
eq,
/// Greater than (`>`)
gt,
};
/// Given two numbers, this function returns the order they are with respect to each other.
pub fn order(a: var, b: var) Order {
if (a == b) {
return .eq;
} else if (a < b) {
return .lt;
} else if (a > b) {
return .gt;
} else {
unreachable;
}
}
/// See also `Order`.
pub const CompareOperator = enum { pub const CompareOperator = enum {
/// Less than (`<`) /// Less than (`<`)
lt, lt,
@ -979,7 +1001,7 @@ pub fn compare(a: var, op: CompareOperator, b: var) bool {
}; };
} }
test "math.lt, et al < <= > >= between signed and unsigned" { test "compare between signed and unsigned" {
testing.expect(compare(@as(i8, -1), .lt, @as(u8, 255))); testing.expect(compare(@as(i8, -1), .lt, @as(u8, 255)));
testing.expect(compare(@as(i8, 2), .gt, @as(u8, 1))); testing.expect(compare(@as(i8, 2), .gt, @as(u8, 1)));
testing.expect(!compare(@as(i8, -1), .gte, @as(u8, 255))); testing.expect(!compare(@as(i8, -1), .gte, @as(u8, 255)));

View File

@ -239,12 +239,6 @@ pub const Allocator = struct {
} }
}; };
pub const Compare = enum {
LessThan,
Equal,
GreaterThan,
};
/// Copy all of source into dest at position 0. /// Copy all of source into dest at position 0.
/// dest.len must be >= source.len. /// dest.len must be >= source.len.
/// dest.ptr must be <= src.ptr. /// dest.ptr must be <= src.ptr.
@ -297,46 +291,30 @@ test "mem.secureZero" {
testing.expectEqualSlices(u8, a[0..], b[0..]); testing.expectEqualSlices(u8, a[0..], b[0..]);
} }
pub fn compare(comptime T: type, lhs: []const T, rhs: []const T) Compare { pub fn order(comptime T: type, lhs: []const T, rhs: []const T) math.Order {
const n = math.min(lhs.len, rhs.len); const n = math.min(lhs.len, rhs.len);
var i: usize = 0; var i: usize = 0;
while (i < n) : (i += 1) { while (i < n) : (i += 1) {
if (lhs[i] == rhs[i]) { switch (math.order(lhs[i], rhs[i])) {
continue; .eq => continue,
} else if (lhs[i] < rhs[i]) { .lt => return .lt,
return Compare.LessThan; .gt => return .gt,
} else if (lhs[i] > rhs[i]) {
return Compare.GreaterThan;
} else {
unreachable;
} }
} }
return math.order(lhs.len, rhs.len);
if (lhs.len == rhs.len) {
return Compare.Equal;
} else if (lhs.len < rhs.len) {
return Compare.LessThan;
} else if (lhs.len > rhs.len) {
return Compare.GreaterThan;
}
unreachable;
} }
test "mem.compare" { test "order" {
testing.expect(compare(u8, "abcd", "bee") == Compare.LessThan); testing.expect(order(u8, "abcd", "bee") == .lt);
testing.expect(compare(u8, "abc", "abc") == Compare.Equal); testing.expect(order(u8, "abc", "abc") == .eq);
testing.expect(compare(u8, "abc", "abc0") == Compare.LessThan); testing.expect(order(u8, "abc", "abc0") == .lt);
testing.expect(compare(u8, "", "") == Compare.Equal); testing.expect(order(u8, "", "") == .eq);
testing.expect(compare(u8, "", "a") == Compare.LessThan); testing.expect(order(u8, "", "a") == .lt);
} }
/// Returns true if lhs < rhs, false otherwise /// Returns true if lhs < rhs, false otherwise
pub fn lessThan(comptime T: type, lhs: []const T, rhs: []const T) bool { pub fn lessThan(comptime T: type, lhs: []const T, rhs: []const T) bool {
var result = compare(T, lhs, rhs); return order(T, lhs, rhs) == .lt;
if (result == Compare.LessThan) {
return true;
} else
return false;
} }
test "mem.lessThan" { test "mem.lessThan" {

View File

@ -1,7 +1,7 @@
const std = @import("std.zig"); const std = @import("std.zig");
const assert = std.debug.assert; const assert = std.debug.assert;
const testing = std.testing; const testing = std.testing;
const mem = std.mem; // For mem.Compare const Order = std.math.Order;
const Color = enum(u1) { const Color = enum(u1) {
Black, Black,
@ -132,7 +132,7 @@ pub const Node = struct {
pub const Tree = struct { pub const Tree = struct {
root: ?*Node, root: ?*Node,
compareFn: fn (*Node, *Node) mem.Compare, compareFn: fn (*Node, *Node) Order,
/// If you have a need for a version that caches this, please file a bug. /// If you have a need for a version that caches this, please file a bug.
pub fn first(tree: *Tree) ?*Node { pub fn first(tree: *Tree) ?*Node {
@ -389,7 +389,7 @@ pub const Tree = struct {
var new = newconst; var new = newconst;
// I assume this can get optimized out if the caller already knows. // I assume this can get optimized out if the caller already knows.
if (tree.compareFn(old, new) != mem.Compare.Equal) return ReplaceError.NotEqual; if (tree.compareFn(old, new) != .eq) return ReplaceError.NotEqual;
if (old.getParent()) |parent| { if (old.getParent()) |parent| {
parent.setChild(new, parent.left == old); parent.setChild(new, parent.left == old);
@ -404,7 +404,7 @@ pub const Tree = struct {
new.* = old.*; new.* = old.*;
} }
pub fn init(tree: *Tree, f: fn (*Node, *Node) mem.Compare) void { pub fn init(tree: *Tree, f: fn (*Node, *Node) Order) void {
tree.root = null; tree.root = null;
tree.compareFn = f; tree.compareFn = f;
} }
@ -469,19 +469,21 @@ fn doLookup(key: *Node, tree: *Tree, pparent: *?*Node, is_left: *bool) ?*Node {
is_left.* = false; is_left.* = false;
while (maybe_node) |node| { while (maybe_node) |node| {
var res: mem.Compare = tree.compareFn(node, key); const res = tree.compareFn(node, key);
if (res == mem.Compare.Equal) { if (res == .eq) {
return node; return node;
} }
pparent.* = node; pparent.* = node;
if (res == mem.Compare.GreaterThan) { switch (res) {
is_left.* = true; .gt => {
maybe_node = node.left; is_left.* = true;
} else if (res == mem.Compare.LessThan) { maybe_node = node.left;
is_left.* = false; },
maybe_node = node.right; .lt => {
} else { is_left.* = false;
unreachable; maybe_node = node.right;
},
.eq => unreachable, // handled above
} }
} }
return null; return null;
@ -496,16 +498,16 @@ fn testGetNumber(node: *Node) *testNumber {
return @fieldParentPtr(testNumber, "node", node); return @fieldParentPtr(testNumber, "node", node);
} }
fn testCompare(l: *Node, r: *Node) mem.Compare { fn testCompare(l: *Node, r: *Node) Order {
var left = testGetNumber(l); var left = testGetNumber(l);
var right = testGetNumber(r); var right = testGetNumber(r);
if (left.value < right.value) { if (left.value < right.value) {
return mem.Compare.LessThan; return .lt;
} else if (left.value == right.value) { } else if (left.value == right.value) {
return mem.Compare.Equal; return .eq;
} else if (left.value > right.value) { } else if (left.value > right.value) {
return mem.Compare.GreaterThan; return .gt;
} }
unreachable; unreachable;
} }

View File

@ -13,6 +13,7 @@ pub const Tree = struct {
root_node: *Node.Root, root_node: *Node.Root,
arena_allocator: std.heap.ArenaAllocator, arena_allocator: std.heap.ArenaAllocator,
errors: ErrorList, errors: ErrorList,
generated: bool = false,
pub const TokenList = SegmentedList(Token, 64); pub const TokenList = SegmentedList(Token, 64);
pub const ErrorList = SegmentedList(Error, 0); pub const ErrorList = SegmentedList(Error, 0);
@ -58,6 +59,8 @@ pub const Tree = struct {
.line_start = start_index, .line_start = start_index,
.line_end = self.source.len, .line_end = self.source.len,
}; };
if (self.generated)
return loc;
const token_start = token.start; const token_start = token.start;
for (self.source[start_index..]) |c, i| { for (self.source[start_index..]) |c, i| {
if (i + start_index == token_start) { if (i + start_index == token_start) {
@ -581,7 +584,7 @@ pub const Node = struct {
} }
pub const Root = struct { pub const Root = struct {
base: Node = Node {.id = .Root}, base: Node = Node{ .id = .Root },
decls: DeclList, decls: DeclList,
eof_token: TokenIndex, eof_token: TokenIndex,
@ -604,7 +607,7 @@ pub const Node = struct {
}; };
pub const VarDecl = struct { pub const VarDecl = struct {
base: Node = Node {.id = .VarDecl}, base: Node = Node{ .id = .VarDecl },
doc_comments: ?*DocComment, doc_comments: ?*DocComment,
visib_token: ?TokenIndex, visib_token: ?TokenIndex,
thread_local_token: ?TokenIndex, thread_local_token: ?TokenIndex,
@ -661,7 +664,7 @@ pub const Node = struct {
}; };
pub const Use = struct { pub const Use = struct {
base: Node = Node {.id = .Use}, base: Node = Node{ .id = .Use },
doc_comments: ?*DocComment, doc_comments: ?*DocComment,
visib_token: ?TokenIndex, visib_token: ?TokenIndex,
use_token: TokenIndex, use_token: TokenIndex,
@ -688,7 +691,7 @@ pub const Node = struct {
}; };
pub const ErrorSetDecl = struct { pub const ErrorSetDecl = struct {
base: Node = Node {.id = .ErrorSetDecl}, base: Node = Node{ .id = .ErrorSetDecl },
error_token: TokenIndex, error_token: TokenIndex,
decls: DeclList, decls: DeclList,
rbrace_token: TokenIndex, rbrace_token: TokenIndex,
@ -714,7 +717,7 @@ pub const Node = struct {
}; };
pub const ContainerDecl = struct { pub const ContainerDecl = struct {
base: Node = Node {.id = .ContainerDecl}, base: Node = Node{ .id = .ContainerDecl },
layout_token: ?TokenIndex, layout_token: ?TokenIndex,
kind_token: TokenIndex, kind_token: TokenIndex,
init_arg_expr: InitArg, init_arg_expr: InitArg,
@ -801,7 +804,7 @@ pub const Node = struct {
}; };
pub const ErrorTag = struct { pub const ErrorTag = struct {
base: Node = Node {.id = .ErrorTag}, base: Node = Node{ .id = .ErrorTag },
doc_comments: ?*DocComment, doc_comments: ?*DocComment,
name_token: TokenIndex, name_token: TokenIndex,
@ -826,7 +829,7 @@ pub const Node = struct {
}; };
pub const Identifier = struct { pub const Identifier = struct {
base: Node = Node {.id = .Identifier}, base: Node = Node{ .id = .Identifier },
token: TokenIndex, token: TokenIndex,
pub fn iterate(self: *Identifier, index: usize) ?*Node { pub fn iterate(self: *Identifier, index: usize) ?*Node {
@ -843,7 +846,7 @@ pub const Node = struct {
}; };
pub const FnProto = struct { pub const FnProto = struct {
base: Node = Node {.id = .FnProto}, base: Node = Node{ .id = .FnProto },
doc_comments: ?*DocComment, doc_comments: ?*DocComment,
visib_token: ?TokenIndex, visib_token: ?TokenIndex,
fn_token: TokenIndex, fn_token: TokenIndex,
@ -925,7 +928,7 @@ pub const Node = struct {
}; };
pub const AnyFrameType = struct { pub const AnyFrameType = struct {
base: Node = Node {.id = .AnyFrameType}, base: Node = Node{ .id = .AnyFrameType },
anyframe_token: TokenIndex, anyframe_token: TokenIndex,
result: ?Result, result: ?Result,
@ -956,7 +959,7 @@ pub const Node = struct {
}; };
pub const ParamDecl = struct { pub const ParamDecl = struct {
base: Node = Node {.id = .ParamDecl}, base: Node = Node{ .id = .ParamDecl },
doc_comments: ?*DocComment, doc_comments: ?*DocComment,
comptime_token: ?TokenIndex, comptime_token: ?TokenIndex,
noalias_token: ?TokenIndex, noalias_token: ?TokenIndex,
@ -989,7 +992,7 @@ pub const Node = struct {
}; };
pub const Block = struct { pub const Block = struct {
base: Node = Node {.id = .Block}, base: Node = Node{ .id = .Block },
label: ?TokenIndex, label: ?TokenIndex,
lbrace: TokenIndex, lbrace: TokenIndex,
statements: StatementList, statements: StatementList,
@ -1020,7 +1023,7 @@ pub const Node = struct {
}; };
pub const Defer = struct { pub const Defer = struct {
base: Node = Node {.id = .Defer}, base: Node = Node{ .id = .Defer },
defer_token: TokenIndex, defer_token: TokenIndex,
expr: *Node, expr: *Node,
@ -1043,7 +1046,7 @@ pub const Node = struct {
}; };
pub const Comptime = struct { pub const Comptime = struct {
base: Node = Node {.id = .Comptime}, base: Node = Node{ .id = .Comptime },
doc_comments: ?*DocComment, doc_comments: ?*DocComment,
comptime_token: TokenIndex, comptime_token: TokenIndex,
expr: *Node, expr: *Node,
@ -1067,7 +1070,7 @@ pub const Node = struct {
}; };
pub const Payload = struct { pub const Payload = struct {
base: Node = Node {.id = .Payload}, base: Node = Node{ .id = .Payload },
lpipe: TokenIndex, lpipe: TokenIndex,
error_symbol: *Node, error_symbol: *Node,
rpipe: TokenIndex, rpipe: TokenIndex,
@ -1091,7 +1094,7 @@ pub const Node = struct {
}; };
pub const PointerPayload = struct { pub const PointerPayload = struct {
base: Node = Node {.id = .PointerPayload}, base: Node = Node{ .id = .PointerPayload },
lpipe: TokenIndex, lpipe: TokenIndex,
ptr_token: ?TokenIndex, ptr_token: ?TokenIndex,
value_symbol: *Node, value_symbol: *Node,
@ -1116,7 +1119,7 @@ pub const Node = struct {
}; };
pub const PointerIndexPayload = struct { pub const PointerIndexPayload = struct {
base: Node = Node {.id = .PointerIndexPayload}, base: Node = Node{ .id = .PointerIndexPayload },
lpipe: TokenIndex, lpipe: TokenIndex,
ptr_token: ?TokenIndex, ptr_token: ?TokenIndex,
value_symbol: *Node, value_symbol: *Node,
@ -1147,7 +1150,7 @@ pub const Node = struct {
}; };
pub const Else = struct { pub const Else = struct {
base: Node = Node {.id = .Else}, base: Node = Node{ .id = .Else },
else_token: TokenIndex, else_token: TokenIndex,
payload: ?*Node, payload: ?*Node,
body: *Node, body: *Node,
@ -1176,7 +1179,7 @@ pub const Node = struct {
}; };
pub const Switch = struct { pub const Switch = struct {
base: Node = Node {.id = .Switch}, base: Node = Node{ .id = .Switch },
switch_token: TokenIndex, switch_token: TokenIndex,
expr: *Node, expr: *Node,
@ -1208,7 +1211,7 @@ pub const Node = struct {
}; };
pub const SwitchCase = struct { pub const SwitchCase = struct {
base: Node = Node {.id = .SwitchCase}, base: Node = Node{ .id = .SwitchCase },
items: ItemList, items: ItemList,
arrow_token: TokenIndex, arrow_token: TokenIndex,
payload: ?*Node, payload: ?*Node,
@ -1243,7 +1246,7 @@ pub const Node = struct {
}; };
pub const SwitchElse = struct { pub const SwitchElse = struct {
base: Node = Node {.id = .SwitchElse}, base: Node = Node{ .id = .SwitchElse },
token: TokenIndex, token: TokenIndex,
pub fn iterate(self: *SwitchElse, index: usize) ?*Node { pub fn iterate(self: *SwitchElse, index: usize) ?*Node {
@ -1260,7 +1263,7 @@ pub const Node = struct {
}; };
pub const While = struct { pub const While = struct {
base: Node = Node {.id = .While}, base: Node = Node{ .id = .While },
label: ?TokenIndex, label: ?TokenIndex,
inline_token: ?TokenIndex, inline_token: ?TokenIndex,
while_token: TokenIndex, while_token: TokenIndex,
@ -1319,7 +1322,7 @@ pub const Node = struct {
}; };
pub const For = struct { pub const For = struct {
base: Node = Node {.id = .For}, base: Node = Node{ .id = .For },
label: ?TokenIndex, label: ?TokenIndex,
inline_token: ?TokenIndex, inline_token: ?TokenIndex,
for_token: TokenIndex, for_token: TokenIndex,
@ -1370,7 +1373,7 @@ pub const Node = struct {
}; };
pub const If = struct { pub const If = struct {
base: Node = Node {.id = .If}, base: Node = Node{ .id = .If },
if_token: TokenIndex, if_token: TokenIndex,
condition: *Node, condition: *Node,
payload: ?*Node, payload: ?*Node,
@ -1413,7 +1416,7 @@ pub const Node = struct {
}; };
pub const InfixOp = struct { pub const InfixOp = struct {
base: Node = Node {.id = .InfixOp}, base: Node = Node{ .id = .InfixOp },
op_token: TokenIndex, op_token: TokenIndex,
lhs: *Node, lhs: *Node,
op: Op, op: Op,
@ -1646,7 +1649,7 @@ pub const Node = struct {
}; };
pub const FieldInitializer = struct { pub const FieldInitializer = struct {
base: Node = Node {.id = .FieldInitializer}, base: Node = Node{ .id = .FieldInitializer },
period_token: TokenIndex, period_token: TokenIndex,
name_token: TokenIndex, name_token: TokenIndex,
expr: *Node, expr: *Node,
@ -1670,7 +1673,7 @@ pub const Node = struct {
}; };
pub const SuffixOp = struct { pub const SuffixOp = struct {
base: Node = Node {.id = .SuffixOp}, base: Node = Node{ .id = .SuffixOp },
lhs: Lhs, lhs: Lhs,
op: Op, op: Op,
rtoken: TokenIndex, rtoken: TokenIndex,
@ -1771,7 +1774,7 @@ pub const Node = struct {
}; };
pub const GroupedExpression = struct { pub const GroupedExpression = struct {
base: Node = Node {.id = .GroupedExpression}, base: Node = Node{ .id = .GroupedExpression },
lparen: TokenIndex, lparen: TokenIndex,
expr: *Node, expr: *Node,
rparen: TokenIndex, rparen: TokenIndex,
@ -1795,7 +1798,7 @@ pub const Node = struct {
}; };
pub const ControlFlowExpression = struct { pub const ControlFlowExpression = struct {
base: Node = Node {.id = .ControlFlowExpression}, base: Node = Node{ .id = .ControlFlowExpression },
ltoken: TokenIndex, ltoken: TokenIndex,
kind: Kind, kind: Kind,
rhs: ?*Node, rhs: ?*Node,
@ -1861,7 +1864,7 @@ pub const Node = struct {
}; };
pub const Suspend = struct { pub const Suspend = struct {
base: Node = Node {.id = .Suspend}, base: Node = Node{ .id = .Suspend },
suspend_token: TokenIndex, suspend_token: TokenIndex,
body: ?*Node, body: ?*Node,
@ -1890,7 +1893,7 @@ pub const Node = struct {
}; };
pub const IntegerLiteral = struct { pub const IntegerLiteral = struct {
base: Node = Node {.id = .IntegerLiteral}, base: Node = Node{ .id = .IntegerLiteral },
token: TokenIndex, token: TokenIndex,
pub fn iterate(self: *IntegerLiteral, index: usize) ?*Node { pub fn iterate(self: *IntegerLiteral, index: usize) ?*Node {
@ -1907,7 +1910,7 @@ pub const Node = struct {
}; };
pub const EnumLiteral = struct { pub const EnumLiteral = struct {
base: Node = Node {.id = .EnumLiteral}, base: Node = Node{ .id = .EnumLiteral },
dot: TokenIndex, dot: TokenIndex,
name: TokenIndex, name: TokenIndex,
@ -1925,7 +1928,7 @@ pub const Node = struct {
}; };
pub const FloatLiteral = struct { pub const FloatLiteral = struct {
base: Node = Node {.id = .FloatLiteral}, base: Node = Node{ .id = .FloatLiteral },
token: TokenIndex, token: TokenIndex,
pub fn iterate(self: *FloatLiteral, index: usize) ?*Node { pub fn iterate(self: *FloatLiteral, index: usize) ?*Node {
@ -1942,7 +1945,7 @@ pub const Node = struct {
}; };
pub const BuiltinCall = struct { pub const BuiltinCall = struct {
base: Node = Node {.id = .BuiltinCall}, base: Node = Node{ .id = .BuiltinCall },
builtin_token: TokenIndex, builtin_token: TokenIndex,
params: ParamList, params: ParamList,
rparen_token: TokenIndex, rparen_token: TokenIndex,
@ -1968,7 +1971,7 @@ pub const Node = struct {
}; };
pub const StringLiteral = struct { pub const StringLiteral = struct {
base: Node = Node {.id = .StringLiteral}, base: Node = Node{ .id = .StringLiteral },
token: TokenIndex, token: TokenIndex,
pub fn iterate(self: *StringLiteral, index: usize) ?*Node { pub fn iterate(self: *StringLiteral, index: usize) ?*Node {
@ -1985,7 +1988,7 @@ pub const Node = struct {
}; };
pub const MultilineStringLiteral = struct { pub const MultilineStringLiteral = struct {
base: Node = Node {.id = .MultilineStringLiteral}, base: Node = Node{ .id = .MultilineStringLiteral },
lines: LineList, lines: LineList,
pub const LineList = SegmentedList(TokenIndex, 4); pub const LineList = SegmentedList(TokenIndex, 4);
@ -2004,7 +2007,7 @@ pub const Node = struct {
}; };
pub const CharLiteral = struct { pub const CharLiteral = struct {
base: Node = Node {.id = .CharLiteral}, base: Node = Node{ .id = .CharLiteral },
token: TokenIndex, token: TokenIndex,
pub fn iterate(self: *CharLiteral, index: usize) ?*Node { pub fn iterate(self: *CharLiteral, index: usize) ?*Node {
@ -2021,7 +2024,7 @@ pub const Node = struct {
}; };
pub const BoolLiteral = struct { pub const BoolLiteral = struct {
base: Node = Node {.id = .BoolLiteral}, base: Node = Node{ .id = .BoolLiteral },
token: TokenIndex, token: TokenIndex,
pub fn iterate(self: *BoolLiteral, index: usize) ?*Node { pub fn iterate(self: *BoolLiteral, index: usize) ?*Node {
@ -2038,7 +2041,7 @@ pub const Node = struct {
}; };
pub const NullLiteral = struct { pub const NullLiteral = struct {
base: Node = Node {.id = .NullLiteral}, base: Node = Node{ .id = .NullLiteral },
token: TokenIndex, token: TokenIndex,
pub fn iterate(self: *NullLiteral, index: usize) ?*Node { pub fn iterate(self: *NullLiteral, index: usize) ?*Node {
@ -2055,7 +2058,7 @@ pub const Node = struct {
}; };
pub const UndefinedLiteral = struct { pub const UndefinedLiteral = struct {
base: Node = Node {.id = .UndefinedLiteral}, base: Node = Node{ .id = .UndefinedLiteral },
token: TokenIndex, token: TokenIndex,
pub fn iterate(self: *UndefinedLiteral, index: usize) ?*Node { pub fn iterate(self: *UndefinedLiteral, index: usize) ?*Node {
@ -2072,7 +2075,7 @@ pub const Node = struct {
}; };
pub const AsmOutput = struct { pub const AsmOutput = struct {
base: Node = Node {.id = .AsmOutput}, base: Node = Node{ .id = .AsmOutput },
lbracket: TokenIndex, lbracket: TokenIndex,
symbolic_name: *Node, symbolic_name: *Node,
constraint: *Node, constraint: *Node,
@ -2117,7 +2120,7 @@ pub const Node = struct {
}; };
pub const AsmInput = struct { pub const AsmInput = struct {
base: Node = Node {.id = .AsmInput}, base: Node = Node{ .id = .AsmInput },
lbracket: TokenIndex, lbracket: TokenIndex,
symbolic_name: *Node, symbolic_name: *Node,
constraint: *Node, constraint: *Node,
@ -2149,7 +2152,7 @@ pub const Node = struct {
}; };
pub const Asm = struct { pub const Asm = struct {
base: Node = Node {.id = .Asm}, base: Node = Node{ .id = .Asm },
asm_token: TokenIndex, asm_token: TokenIndex,
volatile_token: ?TokenIndex, volatile_token: ?TokenIndex,
template: *Node, template: *Node,
@ -2184,7 +2187,7 @@ pub const Node = struct {
}; };
pub const Unreachable = struct { pub const Unreachable = struct {
base: Node = Node {.id = .Unreachable}, base: Node = Node{ .id = .Unreachable },
token: TokenIndex, token: TokenIndex,
pub fn iterate(self: *Unreachable, index: usize) ?*Node { pub fn iterate(self: *Unreachable, index: usize) ?*Node {
@ -2201,7 +2204,7 @@ pub const Node = struct {
}; };
pub const ErrorType = struct { pub const ErrorType = struct {
base: Node = Node {.id = .ErrorType}, base: Node = Node{ .id = .ErrorType },
token: TokenIndex, token: TokenIndex,
pub fn iterate(self: *ErrorType, index: usize) ?*Node { pub fn iterate(self: *ErrorType, index: usize) ?*Node {
@ -2235,7 +2238,7 @@ pub const Node = struct {
}; };
pub const DocComment = struct { pub const DocComment = struct {
base: Node = Node {.id = .DocComment}, base: Node = Node{ .id = .DocComment },
lines: LineList, lines: LineList,
pub const LineList = SegmentedList(TokenIndex, 4); pub const LineList = SegmentedList(TokenIndex, 4);
@ -2254,7 +2257,7 @@ pub const Node = struct {
}; };
pub const TestDecl = struct { pub const TestDecl = struct {
base: Node = Node {.id = .TestDecl}, base: Node = Node{ .id = .TestDecl },
doc_comments: ?*DocComment, doc_comments: ?*DocComment,
test_token: TokenIndex, test_token: TokenIndex,
name: *Node, name: *Node,

View File

@ -643,7 +643,7 @@ fn renderExpression(
}, },
.ArrayAccess => |index_expr| { .ArrayAccess => |index_expr| {
const lbracket = tree.prevToken(index_expr.firstToken()); const lbracket = tree.nextToken(suffix_op.lhs.node.lastToken());
const rbracket = tree.nextToken(index_expr.lastToken()); const rbracket = tree.nextToken(index_expr.lastToken());
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None); try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);

View File

@ -8,7 +8,7 @@ pub const TokenList = std.SegmentedList(CToken, 32);
pub const CToken = struct { pub const CToken = struct {
id: Id, id: Id,
bytes: []const u8, bytes: []const u8 = "",
num_lit_suffix: NumLitSuffix = .None, num_lit_suffix: NumLitSuffix = .None,
pub const Id = enum { pub const Id = enum {
@ -17,20 +17,33 @@ pub const CToken = struct {
NumLitInt, NumLitInt,
NumLitFloat, NumLitFloat,
Identifier, Identifier,
Plus,
Minus, Minus,
Slash, Slash,
LParen, LParen,
RParen, RParen,
Eof, Eof,
Dot, Dot,
Asterisk, Asterisk, // *
Bang, Ampersand, // &
Tilde, And, // &&
Shl, Assign, // =
Lt, Or, // ||
Bang, // !
Tilde, // ~
Shl, // <<
Shr, // >>
Lt, // <
Lte, // <=
Gt, // >
Gte, // >=
Eq, // ==
Ne, // !=
Increment, // ++
Decrement, // --
Comma, Comma,
Fn, Fn,
Arrow, Arrow, // ->
LBrace, LBrace,
RBrace, RBrace,
Pipe, Pipe,
@ -225,7 +238,14 @@ fn zigifyEscapeSequences(ctx: *Context, loc: ZigClangSourceLocation, name: []con
fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:0]const u8, i: *usize) !CToken { fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:0]const u8, i: *usize) !CToken {
var state: enum { var state: enum {
Start, Start,
GotLt, SawLt,
SawGt,
SawPlus,
SawMinus,
SawAmpersand,
SawPipe,
SawBang,
SawEq,
CharLit, CharLit,
OpenComment, OpenComment,
Comment, Comment,
@ -235,7 +255,7 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
Identifier, Identifier,
Decimal, Decimal,
Octal, Octal,
GotZero, SawZero,
Hex, Hex,
Bin, Bin,
Float, Float,
@ -246,7 +266,6 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
NumLitIntSuffixL, NumLitIntSuffixL,
NumLitIntSuffixLL, NumLitIntSuffixLL,
NumLitIntSuffixUL, NumLitIntSuffixUL,
Minus,
Done, Done,
} = .Start; } = .Start;
@ -267,7 +286,7 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
.Hex, .Hex,
.Bin, .Bin,
.Octal, .Octal,
.GotZero, .SawZero,
.Float, .Float,
.FloatExp, .FloatExp,
=> { => {
@ -275,13 +294,19 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
return result; return result;
}, },
.Start, .Start,
.Minus, .SawMinus,
.Done, .Done,
.NumLitIntSuffixU, .NumLitIntSuffixU,
.NumLitIntSuffixL, .NumLitIntSuffixL,
.NumLitIntSuffixUL, .NumLitIntSuffixUL,
.NumLitIntSuffixLL, .NumLitIntSuffixLL,
.GotLt, .SawLt,
.SawGt,
.SawPlus,
.SawAmpersand,
.SawPipe,
.SawBang,
.SawEq,
=> { => {
return result; return result;
}, },
@ -333,7 +358,7 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
begin_index = i.*; begin_index = i.*;
}, },
'0' => { '0' => {
state = .GotZero; state = .SawZero;
result.id = .NumLitInt; result.id = .NumLitInt;
begin_index = i.*; begin_index = i.*;
}, },
@ -343,7 +368,11 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
}, },
'<' => { '<' => {
result.id = .Lt; result.id = .Lt;
state = .GotLt; state = .SawLt;
},
'>' => {
result.id = .Gt;
state = .SawGt;
}, },
'(' => { '(' => {
result.id = .LParen; result.id = .LParen;
@ -357,18 +386,26 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
result.id = .Asterisk; result.id = .Asterisk;
state = .Done; state = .Done;
}, },
'+' => {
result.id = .Plus;
state = .SawPlus;
},
'-' => { '-' => {
state = .Minus;
result.id = .Minus; result.id = .Minus;
state = .SawMinus;
}, },
'!' => { '!' => {
result.id = .Bang; result.id = .Bang;
state = .Done; state = .SawBang;
}, },
'~' => { '~' => {
result.id = .Tilde; result.id = .Tilde;
state = .Done; state = .Done;
}, },
'=' => {
result.id = .Assign;
state = .SawEq;
},
',' => { ',' => {
result.id = .Comma; result.id = .Comma;
state = .Done; state = .Done;
@ -383,7 +420,11 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
}, },
'|' => { '|' => {
result.id = .Pipe; result.id = .Pipe;
state = .Done; state = .SawPipe;
},
'&' => {
result.id = .Ampersand;
state = .SawAmpersand;
}, },
'?' => { '?' => {
result.id = .QuestionMark; result.id = .QuestionMark;
@ -400,26 +441,88 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
} }
}, },
.Done => return result, .Done => return result,
.Minus => { .SawMinus => {
switch (c) { switch (c) {
'>' => { '>' => {
result.id = .Arrow; result.id = .Arrow;
state = .Done; state = .Done;
}, },
else => { '-' => {
return result; result.id = .Decrement;
state = .Done;
}, },
else => return result,
} }
}, },
.GotLt => { .SawPlus => {
switch (c) {
'+' => {
result.id = .Increment;
state = .Done;
},
else => return result,
}
},
.SawLt => {
switch (c) { switch (c) {
'<' => { '<' => {
result.id = .Shl; result.id = .Shl;
state = .Done; state = .Done;
}, },
else => { '=' => {
return result; result.id = .Lte;
state = .Done;
}, },
else => return result,
}
},
.SawGt => {
switch (c) {
'>' => {
result.id = .Shr;
state = .Done;
},
'=' => {
result.id = .Gte;
state = .Done;
},
else => return result,
}
},
.SawPipe => {
switch (c) {
'|' => {
result.id = .Or;
state = .Done;
},
else => return result,
}
},
.SawAmpersand => {
switch (c) {
'&' => {
result.id = .And;
state = .Done;
},
else => return result,
}
},
.SawBang => {
switch (c) {
'=' => {
result.id = .Ne;
state = .Done;
},
else => return result,
}
},
.SawEq => {
switch (c) {
'=' => {
result.id = .Eq;
state = .Done;
},
else => return result,
} }
}, },
.Float => { .Float => {
@ -454,7 +557,7 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
'0'...'9' => { '0'...'9' => {
state = .FloatExp; state = .FloatExp;
}, },
else => { else => {
try failDecl(ctx, loc, name, "macro tokenizing failed: expected a digit or '+' or '-'", .{}); try failDecl(ctx, loc, name, "macro tokenizing failed: expected a digit or '+' or '-'", .{});
return error.TokenizingFailed; return error.TokenizingFailed;
}, },
@ -514,7 +617,7 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
}, },
} }
}, },
.GotZero => { .SawZero => {
switch (c) { switch (c) {
'x', 'X' => { 'x', 'X' => {
state = .Hex; state = .Hex;
@ -726,76 +829,114 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
unreachable; unreachable;
} }
fn expectTokens(tl: *TokenList, src: [*:0]const u8, expected: []CToken) void {
// these can be undefined since they are only used for error reporting
tokenizeCMacro(undefined, undefined, undefined, tl, src) catch unreachable;
var it = tl.iterator(0);
for (expected) |t| {
var tok = it.next().?;
std.testing.expectEqual(t.id, tok.id);
if (t.bytes.len > 0) {
//std.debug.warn(" {} = {}\n", .{tok.bytes, t.bytes});
std.testing.expectEqualSlices(u8, tok.bytes, t.bytes);
}
if (t.num_lit_suffix != .None) {
std.testing.expectEqual(t.num_lit_suffix, tok.num_lit_suffix);
}
}
std.testing.expect(it.next() == null);
tl.shrink(0);
}
test "tokenize macro" { test "tokenize macro" {
var tl = TokenList.init(std.heap.page_allocator); var tl = TokenList.init(std.heap.page_allocator);
defer tl.deinit(); defer tl.deinit();
const src = "TEST(0\n"; expectTokens(&tl, "TEST(0\n", &[_]CToken{
try tokenizeCMacro(&tl, src); .{ .id = .Identifier, .bytes = "TEST" },
var it = tl.iterator(0); .{ .id = .Fn },
expect(it.next().?.id == .Identifier); .{ .id = .LParen },
expect(it.next().?.id == .Fn); .{ .id = .NumLitInt, .bytes = "0" },
expect(it.next().?.id == .LParen); .{ .id = .Eof },
expect(std.mem.eql(u8, it.next().?.bytes, "0")); });
expect(it.next().?.id == .Eof);
expect(it.next() == null);
tl.shrink(0);
const src2 = "__FLT_MIN_10_EXP__ -37\n"; expectTokens(&tl, "__FLT_MIN_10_EXP__ -37\n", &[_]CToken{
try tokenizeCMacro(&tl, src2); .{ .id = .Identifier, .bytes = "__FLT_MIN_10_EXP__" },
it = tl.iterator(0); .{ .id = .Minus },
expect(std.mem.eql(u8, it.next().?.bytes, "__FLT_MIN_10_EXP__")); .{ .id = .NumLitInt, .bytes = "37" },
expect(it.next().?.id == .Minus); .{ .id = .Eof },
expect(std.mem.eql(u8, it.next().?.bytes, "37")); });
expect(it.next().?.id == .Eof);
expect(it.next() == null);
tl.shrink(0);
const src3 = "__llvm__ 1\n#define"; expectTokens(&tl, "__llvm__ 1\n#define", &[_]CToken{
try tokenizeCMacro(&tl, src3); .{ .id = .Identifier, .bytes = "__llvm__" },
it = tl.iterator(0); .{ .id = .NumLitInt, .bytes = "1" },
expect(std.mem.eql(u8, it.next().?.bytes, "__llvm__")); .{ .id = .Eof },
expect(std.mem.eql(u8, it.next().?.bytes, "1")); });
expect(it.next().?.id == .Eof);
expect(it.next() == null);
tl.shrink(0);
const src4 = "TEST 2"; expectTokens(&tl, "TEST 2", &[_]CToken{
try tokenizeCMacro(&tl, src4); .{ .id = .Identifier, .bytes = "TEST" },
it = tl.iterator(0); .{ .id = .NumLitInt, .bytes = "2" },
expect(it.next().?.id == .Identifier); .{ .id = .Eof },
expect(std.mem.eql(u8, it.next().?.bytes, "2")); });
expect(it.next().?.id == .Eof);
expect(it.next() == null);
tl.shrink(0);
const src5 = "FOO 0ull"; expectTokens(&tl, "FOO 0ull", &[_]CToken{
try tokenizeCMacro(&tl, src5); .{ .id = .Identifier, .bytes = "FOO" },
it = tl.iterator(0); .{ .id = .NumLitInt, .bytes = "0", .num_lit_suffix = .LLU },
expect(it.next().?.id == .Identifier); .{ .id = .Eof },
expect(std.mem.eql(u8, it.next().?.bytes, "0")); });
expect(it.next().?.id == .Eof); }
expect(it.next() == null);
tl.shrink(0); test "tokenize macro ops" {
var tl = TokenList.init(std.heap.page_allocator);
defer tl.deinit();
expectTokens(&tl, "ADD A + B", &[_]CToken{
.{ .id = .Identifier, .bytes = "ADD" },
.{ .id = .Identifier, .bytes = "A" },
.{ .id = .Plus },
.{ .id = .Identifier, .bytes = "B" },
.{ .id = .Eof },
});
expectTokens(&tl, "ADD (A) + B", &[_]CToken{
.{ .id = .Identifier, .bytes = "ADD" },
.{ .id = .LParen },
.{ .id = .Identifier, .bytes = "A" },
.{ .id = .RParen },
.{ .id = .Plus },
.{ .id = .Identifier, .bytes = "B" },
.{ .id = .Eof },
});
expectTokens(&tl, "ADD (A) + B", &[_]CToken{
.{ .id = .Identifier, .bytes = "ADD" },
.{ .id = .LParen },
.{ .id = .Identifier, .bytes = "A" },
.{ .id = .RParen },
.{ .id = .Plus },
.{ .id = .Identifier, .bytes = "B" },
.{ .id = .Eof },
});
} }
test "escape sequences" { test "escape sequences" {
var buf: [1024]u8 = undefined; var buf: [1024]u8 = undefined;
var alloc = std.heap.FixedBufferAllocator.init(buf[0..]); var alloc = std.heap.FixedBufferAllocator.init(buf[0..]);
const a = &alloc.allocator; const a = &alloc.allocator;
expect(std.mem.eql(u8, (try zigifyEscapeSequences(a, .{ // these can be undefined since they are only used for error reporting
expect(std.mem.eql(u8, (try zigifyEscapeSequences(undefined, undefined, undefined, a, .{
.id = .StrLit, .id = .StrLit,
.bytes = "\\x0077", .bytes = "\\x0077",
})).bytes, "\\x77")); })).bytes, "\\x77"));
expect(std.mem.eql(u8, (try zigifyEscapeSequences(a, .{ expect(std.mem.eql(u8, (try zigifyEscapeSequences(undefined, undefined, undefined, a, .{
.id = .StrLit, .id = .StrLit,
.bytes = "\\24500", .bytes = "\\24500",
})).bytes, "\\xa500")); })).bytes, "\\xa500"));
expect(std.mem.eql(u8, (try zigifyEscapeSequences(a, .{ expect(std.mem.eql(u8, (try zigifyEscapeSequences(undefined, undefined, undefined, a, .{
.id = .StrLit, .id = .StrLit,
.bytes = "\\x0077 abc", .bytes = "\\x0077 abc",
})).bytes, "\\x77 abc")); })).bytes, "\\x77 abc"));
expect(std.mem.eql(u8, (try zigifyEscapeSequences(a, .{ expect(std.mem.eql(u8, (try zigifyEscapeSequences(undefined, undefined, undefined, a, .{
.id = .StrLit, .id = .StrLit,
.bytes = "\\045abc", .bytes = "\\045abc",
})).bytes, "\\x25abc")); })).bytes, "\\x25abc"));

View File

@ -43,6 +43,7 @@ pub const struct_ZigClangImplicitCastExpr = @OpaqueType();
pub const struct_ZigClangIncompleteArrayType = @OpaqueType(); pub const struct_ZigClangIncompleteArrayType = @OpaqueType();
pub const struct_ZigClangIntegerLiteral = @OpaqueType(); pub const struct_ZigClangIntegerLiteral = @OpaqueType();
pub const struct_ZigClangMacroDefinitionRecord = @OpaqueType(); pub const struct_ZigClangMacroDefinitionRecord = @OpaqueType();
pub const struct_ZigClangMacroExpansion = @OpaqueType();
pub const struct_ZigClangMacroQualifiedType = @OpaqueType(); pub const struct_ZigClangMacroQualifiedType = @OpaqueType();
pub const struct_ZigClangMemberExpr = @OpaqueType(); pub const struct_ZigClangMemberExpr = @OpaqueType();
pub const struct_ZigClangNamedDecl = @OpaqueType(); pub const struct_ZigClangNamedDecl = @OpaqueType();
@ -803,8 +804,8 @@ pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *cons
pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation; 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_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;
pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool; pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;
pub extern fn ZigClangExpr_getStmtClass(self: ?*const struct_ZigClangExpr) ZigClangStmtClass; 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_getType(self: *const struct_ZigClangExpr) struct_ZigClangQualType;
pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation; pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;
pub extern fn ZigClangInitListExpr_getInit(self: ?*const struct_ZigClangInitListExpr, i: c_uint) *const ZigClangExpr; pub extern fn ZigClangInitListExpr_getInit(self: ?*const struct_ZigClangInitListExpr, i: c_uint) *const ZigClangExpr;
pub extern fn ZigClangInitListExpr_getArrayFiller(self: ?*const struct_ZigClangInitListExpr) *const ZigClangExpr; pub extern fn ZigClangInitListExpr_getArrayFiller(self: ?*const struct_ZigClangInitListExpr) *const ZigClangExpr;
@ -831,6 +832,8 @@ pub extern fn ZigClangFunctionDecl_hasBody(self: *const ZigClangFunctionDecl) bo
pub extern fn ZigClangFunctionDecl_getStorageClass(self: *const ZigClangFunctionDecl) ZigClangStorageClass; 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_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 struct_ZigClangStmt;
pub extern fn ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(self: *const ZigClangFunctionDecl) bool;
pub extern fn ZigClangFunctionDecl_isInlineSpecified(self: *const ZigClangFunctionDecl) bool;
pub extern fn ZigClangBuiltinType_getKind(self: *const struct_ZigClangBuiltinType) ZigClangBuiltinTypeKind; pub extern fn ZigClangBuiltinType_getKind(self: *const struct_ZigClangBuiltinType) ZigClangBuiltinTypeKind;
@ -889,6 +892,7 @@ pub const ZigClangImplicitCastExpr = struct_ZigClangImplicitCastExpr;
pub const ZigClangIncompleteArrayType = struct_ZigClangIncompleteArrayType; pub const ZigClangIncompleteArrayType = struct_ZigClangIncompleteArrayType;
pub const ZigClangIntegerLiteral = struct_ZigClangIntegerLiteral; pub const ZigClangIntegerLiteral = struct_ZigClangIntegerLiteral;
pub const ZigClangMacroDefinitionRecord = struct_ZigClangMacroDefinitionRecord; pub const ZigClangMacroDefinitionRecord = struct_ZigClangMacroDefinitionRecord;
pub const ZigClangMacroExpansion = struct_ZigClangMacroExpansion;
pub const ZigClangMacroQualifiedType = struct_ZigClangMacroQualifiedType; pub const ZigClangMacroQualifiedType = struct_ZigClangMacroQualifiedType;
pub const ZigClangMemberExpr = struct_ZigClangMemberExpr; pub const ZigClangMemberExpr = struct_ZigClangMemberExpr;
pub const ZigClangNamedDecl = struct_ZigClangNamedDecl; pub const ZigClangNamedDecl = struct_ZigClangNamedDecl;
@ -1058,6 +1062,8 @@ pub extern fn ZigClangMacroDefinitionRecord_getName_getNameStart(*const ZigClang
pub extern fn ZigClangMacroDefinitionRecord_getSourceRange_getBegin(*const ZigClangMacroDefinitionRecord) ZigClangSourceLocation; pub extern fn ZigClangMacroDefinitionRecord_getSourceRange_getBegin(*const ZigClangMacroDefinitionRecord) ZigClangSourceLocation;
pub extern fn ZigClangMacroDefinitionRecord_getSourceRange_getEnd(*const ZigClangMacroDefinitionRecord) ZigClangSourceLocation; pub extern fn ZigClangMacroDefinitionRecord_getSourceRange_getEnd(*const ZigClangMacroDefinitionRecord) ZigClangSourceLocation;
pub extern fn ZigClangMacroExpansion_getDefinition(*const ZigClangMacroExpansion) *const ZigClangMacroDefinitionRecord;
pub extern fn ZigClangIfStmt_getThen(*const ZigClangIfStmt) *const ZigClangStmt; pub extern fn ZigClangIfStmt_getThen(*const ZigClangIfStmt) *const ZigClangStmt;
pub extern fn ZigClangIfStmt_getElse(*const ZigClangIfStmt) ?*const ZigClangStmt; pub extern fn ZigClangIfStmt_getElse(*const ZigClangIfStmt) ?*const ZigClangStmt;
pub extern fn ZigClangIfStmt_getCond(*const ZigClangIfStmt) *const ZigClangStmt; pub extern fn ZigClangIfStmt_getCond(*const ZigClangIfStmt) *const ZigClangStmt;

View File

@ -119,11 +119,11 @@ fn linkDiagCallbackErrorable(ctx: *Context, msg: []const u8) !void {
fn toExternObjectFormatType(ofmt: ObjectFormat) c.ZigLLVM_ObjectFormatType { fn toExternObjectFormatType(ofmt: ObjectFormat) c.ZigLLVM_ObjectFormatType {
return switch (ofmt) { return switch (ofmt) {
.unknown => c.ZigLLVM_UnknownObjectFormat, .unknown => .ZigLLVM_UnknownObjectFormat,
.coff => c.ZigLLVM_COFF, .coff => .ZigLLVM_COFF,
.elf => c.ZigLLVM_ELF, .elf => .ZigLLVM_ELF,
.macho => c.ZigLLVM_MachO, .macho => .ZigLLVM_MachO,
.wasm => c.ZigLLVM_Wasm, .wasm => .ZigLLVM_Wasm,
}; };
} }

View File

@ -226,24 +226,24 @@ pub const PrintMessageAction = VerifierFailureAction.LLVMPrintMessageAction;
pub const ReturnStatusAction = VerifierFailureAction.LLVMReturnStatusAction; pub const ReturnStatusAction = VerifierFailureAction.LLVMReturnStatusAction;
pub const VerifierFailureAction = c.LLVMVerifierFailureAction; pub const VerifierFailureAction = c.LLVMVerifierFailureAction;
pub const CodeGenLevelNone = c.LLVMCodeGenOptLevel.LLVMCodeGenLevelNone; pub const CodeGenLevelNone = CodeGenOptLevel.LLVMCodeGenLevelNone;
pub const CodeGenLevelLess = c.LLVMCodeGenOptLevel.LLVMCodeGenLevelLess; pub const CodeGenLevelLess = CodeGenOptLevel.LLVMCodeGenLevelLess;
pub const CodeGenLevelDefault = c.LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault; pub const CodeGenLevelDefault = CodeGenOptLevel.LLVMCodeGenLevelDefault;
pub const CodeGenLevelAggressive = c.LLVMCodeGenOptLevel.LLVMCodeGenLevelAggressive; pub const CodeGenLevelAggressive = CodeGenOptLevel.LLVMCodeGenLevelAggressive;
pub const CodeGenOptLevel = c.LLVMCodeGenOptLevel; pub const CodeGenOptLevel = c.LLVMCodeGenOptLevel;
pub const RelocDefault = c.LLVMRelocMode.LLVMRelocDefault; pub const RelocDefault = RelocMode.LLVMRelocDefault;
pub const RelocStatic = c.LLVMRelocMode.LLVMRelocStatic; pub const RelocStatic = RelocMode.LLVMRelocStatic;
pub const RelocPIC = c.LLVMRelocMode.LLVMRelocPIC; pub const RelocPIC = RelocMode.LLVMRelocPIC;
pub const RelocDynamicNoPic = c.LLVMRelocMode.LLVMRelocDynamicNoPic; pub const RelocDynamicNoPic = RelocMode.LLVMRelocDynamicNoPic;
pub const RelocMode = c.LLVMRelocMode; pub const RelocMode = c.LLVMRelocMode;
pub const CodeModelDefault = c.LLVMCodeModel.LLVMCodeModelDefault; pub const CodeModelDefault = CodeModel.LLVMCodeModelDefault;
pub const CodeModelJITDefault = c.LLVMCodeModel.LLVMCodeModelJITDefault; pub const CodeModelJITDefault = CodeModel.LLVMCodeModelJITDefault;
pub const CodeModelSmall = c.LLVMCodeModel.LLVMCodeModelSmall; pub const CodeModelSmall = CodeModel.LLVMCodeModelSmall;
pub const CodeModelKernel = c.LLVMCodeModel.LLVMCodeModelKernel; pub const CodeModelKernel = CodeModel.LLVMCodeModelKernel;
pub const CodeModelMedium = c.LLVMCodeModel.LLVMCodeModelMedium; pub const CodeModelMedium = CodeModel.LLVMCodeModelMedium;
pub const CodeModelLarge = c.LLVMCodeModel.LLVMCodeModelLarge; pub const CodeModelLarge = CodeModel.LLVMCodeModelLarge;
pub const CodeModel = c.LLVMCodeModel; pub const CodeModel = c.LLVMCodeModel;
pub const EmitAssembly = EmitOutputType.ZigLLVM_EmitAssembly; pub const EmitAssembly = EmitOutputType.ZigLLVM_EmitAssembly;
@ -251,13 +251,13 @@ pub const EmitBinary = EmitOutputType.ZigLLVM_EmitBinary;
pub const EmitLLVMIr = EmitOutputType.ZigLLVM_EmitLLVMIr; pub const EmitLLVMIr = EmitOutputType.ZigLLVM_EmitLLVMIr;
pub const EmitOutputType = c.ZigLLVM_EmitOutputType; pub const EmitOutputType = c.ZigLLVM_EmitOutputType;
pub const CCallConv = c.LLVMCCallConv; pub const CCallConv = CallConv.LLVMCCallConv;
pub const FastCallConv = c.LLVMFastCallConv; pub const FastCallConv = CallConv.LLVMFastCallConv;
pub const ColdCallConv = c.LLVMColdCallConv; pub const ColdCallConv = CallConv.LLVMColdCallConv;
pub const WebKitJSCallConv = c.LLVMWebKitJSCallConv; pub const WebKitJSCallConv = CallConv.LLVMWebKitJSCallConv;
pub const AnyRegCallConv = c.LLVMAnyRegCallConv; pub const AnyRegCallConv = CallConv.LLVMAnyRegCallConv;
pub const X86StdcallCallConv = c.LLVMX86StdcallCallConv; pub const X86StdcallCallConv = CallConv.LLVMX86StdcallCallConv;
pub const X86FastcallCallConv = c.LLVMX86FastcallCallConv; pub const X86FastcallCallConv = CallConv.LLVMX86FastcallCallConv;
pub const CallConv = c.LLVMCallConv; pub const CallConv = c.LLVMCallConv;
pub const CallAttr = extern enum { pub const CallAttr = extern enum {
@ -288,6 +288,6 @@ extern fn ZigLLVMTargetMachineEmitToFile(
) bool; ) bool;
pub const BuildCall = ZigLLVMBuildCall; pub const BuildCall = ZigLLVMBuildCall;
extern fn ZigLLVMBuildCall(B: *Builder, Fn: *Value, Args: [*]*Value, NumArgs: c_uint, CC: c_uint, fn_inline: CallAttr, Name: [*:0]const u8) ?*Value; extern fn ZigLLVMBuildCall(B: *Builder, Fn: *Value, Args: [*]*Value, NumArgs: c_uint, CC: CallConv, fn_inline: CallAttr, Name: [*:0]const u8) ?*Value;
pub const PrivateLinkage = c.LLVMLinkage.LLVMPrivateLinkage; pub const PrivateLinkage = c.LLVMLinkage.LLVMPrivateLinkage;

View File

@ -95,7 +95,7 @@ export fn stage2_translate_c(
args_end: [*]?[*]const u8, args_end: [*]?[*]const u8,
resources_path: [*:0]const u8, resources_path: [*:0]const u8,
) Error { ) Error {
var errors: []translate_c.ClangErrMsg = undefined; var errors = @as([*]translate_c.ClangErrMsg, undefined)[0..0];
out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) { out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) {
error.SemanticAnalyzeFail => { error.SemanticAnalyzeFail => {
out_errors_ptr.* = errors.ptr; out_errors_ptr.* = errors.ptr;

File diff suppressed because it is too large Load Diff

View File

@ -1,840 +0,0 @@
/*
* Copyright (c) 2016 Andrew Kelley
*
* This file is part of zig, which is MIT licensed.
* See http://opensource.org/licenses/MIT
*/
#include "c_tokenizer.hpp"
#include <inttypes.h>
#define WHITESPACE_EXCEPT_N \
' ': \
case '\t': \
case '\v': \
case '\f'
#define DIGIT_NON_ZERO \
'1': \
case '2': \
case '3': \
case '4': \
case '5': \
case '6': \
case '7': \
case '8': \
case '9'
#define DIGIT \
'0': \
case DIGIT_NON_ZERO
#define ALPHA \
'a': \
case 'b': \
case 'c': \
case 'd': \
case 'e': \
case 'f': \
case 'g': \
case 'h': \
case 'i': \
case 'j': \
case 'k': \
case 'l': \
case 'm': \
case 'n': \
case 'o': \
case 'p': \
case 'q': \
case 'r': \
case 's': \
case 't': \
case 'u': \
case 'v': \
case 'w': \
case 'x': \
case 'y': \
case 'z': \
case 'A': \
case 'B': \
case 'C': \
case 'D': \
case 'E': \
case 'F': \
case 'G': \
case 'H': \
case 'I': \
case 'J': \
case 'K': \
case 'L': \
case 'M': \
case 'N': \
case 'O': \
case 'P': \
case 'Q': \
case 'R': \
case 'S': \
case 'T': \
case 'U': \
case 'V': \
case 'W': \
case 'X': \
case 'Y': \
case 'Z'
#define IDENT_START \
ALPHA: \
case '_'
#define IDENT \
IDENT_START: \
case DIGIT
#define LINE_ENDING \
'\r': \
case '\n'
static void begin_token(CTokenize *ctok, CTokId id) {
assert(ctok->cur_tok == nullptr);
ctok->tokens.add_one();
ctok->cur_tok = &ctok->tokens.last();
ctok->cur_tok->id = id;
switch (id) {
case CTokIdStrLit:
memset(&ctok->cur_tok->data.str_lit, 0, sizeof(Buf));
buf_resize(&ctok->cur_tok->data.str_lit, 0);
break;
case CTokIdSymbol:
memset(&ctok->cur_tok->data.symbol, 0, sizeof(Buf));
buf_resize(&ctok->cur_tok->data.symbol, 0);
break;
case CTokIdNumLitInt:
ctok->cur_tok->data.num_lit_int.x = 0;
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixNone;
break;
case CTokIdCharLit:
case CTokIdNumLitFloat:
case CTokIdMinus:
case CTokIdLParen:
case CTokIdRParen:
case CTokIdEOF:
case CTokIdDot:
case CTokIdAsterisk:
case CTokIdBang:
case CTokIdTilde:
case CTokIdShl:
case CTokIdLt:
break;
}
}
static void end_token(CTokenize *ctok) {
ctok->cur_tok = nullptr;
}
static void mark_error(CTokenize *ctok) {
ctok->error = true;
}
static void add_char(CTokenize *ctok, uint8_t c) {
assert(ctok->cur_tok);
if (ctok->cur_tok->id == CTokIdCharLit) {
ctok->cur_tok->data.char_lit = c;
ctok->state = CTokStateExpectEndQuot;
} else if (ctok->cur_tok->id == CTokIdStrLit) {
buf_append_char(&ctok->cur_tok->data.str_lit, c);
ctok->state = CTokStateString;
} else {
zig_unreachable();
}
}
static void hex_digit(CTokenize *ctok, uint8_t value) {
// TODO @mul_with_overflow
ctok->cur_tok->data.num_lit_int.x *= 16;
// TODO @add_with_overflow
ctok->cur_tok->data.num_lit_int.x += value;
static const uint8_t hex_digit[] = "0123456789abcdef";
buf_append_char(&ctok->buf, hex_digit[value]);
}
static void end_float(CTokenize *ctok) {
// TODO detect errors, overflow, and underflow
double value = strtod(buf_ptr(&ctok->buf), nullptr);
ctok->cur_tok->data.num_lit_float = value;
end_token(ctok);
ctok->state = CTokStateStart;
}
void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
ctok->tokens.resize(0);
ctok->state = CTokStateStart;
ctok->error = false;
ctok->cur_tok = nullptr;
buf_resize(&ctok->buf, 0);
for (; *c; c += 1) {
switch (ctok->state) {
case CTokStateStart:
switch (*c) {
case WHITESPACE_EXCEPT_N:
break;
case '\'':
ctok->state = CTokStateExpectChar;
begin_token(ctok, CTokIdCharLit);
break;
case '\"':
ctok->state = CTokStateString;
begin_token(ctok, CTokIdStrLit);
break;
case '/':
ctok->state = CTokStateOpenComment;
break;
case '\\':
ctok->state = CTokStateBackslash;
break;
case LINE_ENDING:
goto found_end_of_macro;
case IDENT_START:
ctok->state = CTokStateIdentifier;
begin_token(ctok, CTokIdSymbol);
buf_append_char(&ctok->cur_tok->data.symbol, *c);
break;
case DIGIT_NON_ZERO:
ctok->state = CTokStateDecimal;
begin_token(ctok, CTokIdNumLitInt);
ctok->cur_tok->data.num_lit_int.x = *c - '0';
buf_resize(&ctok->buf, 0);
buf_append_char(&ctok->buf, *c);
break;
case '0':
ctok->state = CTokStateGotZero;
begin_token(ctok, CTokIdNumLitInt);
ctok->cur_tok->data.num_lit_int.x = 0;
buf_resize(&ctok->buf, 0);
buf_append_char(&ctok->buf, '0');
break;
case '.':
begin_token(ctok, CTokIdDot);
end_token(ctok);
break;
case '<':
begin_token(ctok, CTokIdLt);
ctok->state = CTokStateGotLt;
break;
case '(':
begin_token(ctok, CTokIdLParen);
end_token(ctok);
break;
case ')':
begin_token(ctok, CTokIdRParen);
end_token(ctok);
break;
case '*':
begin_token(ctok, CTokIdAsterisk);
end_token(ctok);
break;
case '-':
begin_token(ctok, CTokIdMinus);
end_token(ctok);
break;
case '!':
begin_token(ctok, CTokIdBang);
end_token(ctok);
break;
case '~':
begin_token(ctok, CTokIdTilde);
end_token(ctok);
break;
default:
return mark_error(ctok);
}
break;
case CTokStateGotLt:
switch (*c) {
case '<':
ctok->cur_tok->id = CTokIdShl;
end_token(ctok);
ctok->state = CTokStateStart;
break;
default:
end_token(ctok);
ctok->state = CTokStateStart;
continue;
}
break;
case CTokStateFloat:
switch (*c) {
case '.':
break;
case 'e':
case 'E':
buf_append_char(&ctok->buf, 'e');
ctok->state = CTokStateExpSign;
break;
case 'f':
case 'F':
case 'l':
case 'L':
end_float(ctok);
break;
case DIGIT:
buf_append_char(&ctok->buf, *c);
break;
default:
c -= 1;
end_float(ctok);
continue;
}
break;
case CTokStateExpSign:
switch (*c) {
case '+':
case '-':
ctok->state = CTokStateFloatExpFirst;
buf_append_char(&ctok->buf, *c);
break;
case DIGIT:
ctok->state = CTokStateFloatExp;
buf_append_char(&ctok->buf, *c);
break;
default:
return mark_error(ctok);
}
break;
case CTokStateFloatExpFirst:
switch (*c) {
case DIGIT:
buf_append_char(&ctok->buf, *c);
ctok->state = CTokStateFloatExp;
break;
default:
return mark_error(ctok);
}
break;
case CTokStateFloatExp:
switch (*c) {
case DIGIT:
buf_append_char(&ctok->buf, *c);
break;
case 'f':
case 'F':
case 'l':
case 'L':
end_float(ctok);
break;
default:
c -= 1;
end_float(ctok);
continue;
}
break;
case CTokStateDecimal:
switch (*c) {
case DIGIT:
buf_append_char(&ctok->buf, *c);
// TODO @mul_with_overflow
ctok->cur_tok->data.num_lit_int.x *= 10;
// TODO @add_with_overflow
ctok->cur_tok->data.num_lit_int.x += *c - '0';
break;
case '\'':
break;
case 'u':
case 'U':
ctok->state = CTokStateNumLitIntSuffixU;
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixU;
break;
case 'l':
case 'L':
ctok->state = CTokStateNumLitIntSuffixL;
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixL;
break;
case '.':
buf_append_char(&ctok->buf, '.');
ctok->cur_tok->id = CTokIdNumLitFloat;
ctok->state = CTokStateFloat;
break;
default:
c -= 1;
end_token(ctok);
ctok->state = CTokStateStart;
continue;
}
break;
case CTokStateGotZero:
switch (*c) {
case 'x':
case 'X':
ctok->state = CTokStateHex;
break;
case '.':
ctok->state = CTokStateFloat;
ctok->cur_tok->id = CTokIdNumLitFloat;
buf_append_char(&ctok->buf, '.');
break;
case 'l':
case 'L':
case 'u':
case 'U':
c -= 1;
ctok->state = CTokStateDecimal;
continue;
default:
c -= 1;
ctok->state = CTokStateOctal;
continue;
}
break;
case CTokStateOctal:
switch (*c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
// TODO @mul_with_overflow
ctok->cur_tok->data.num_lit_int.x *= 8;
// TODO @add_with_overflow
ctok->cur_tok->data.num_lit_int.x += *c - '0';
break;
case '8':
case '9':
return mark_error(ctok);
case '\'':
break;
default:
c -= 1;
end_token(ctok);
ctok->state = CTokStateStart;
continue;
}
break;
case CTokStateHex:
switch (*c) {
case '0':
hex_digit(ctok, 0);
break;
case '1':
hex_digit(ctok, 1);
break;
case '2':
hex_digit(ctok, 2);
break;
case '3':
hex_digit(ctok, 3);
break;
case '4':
hex_digit(ctok, 4);
break;
case '5':
hex_digit(ctok, 5);
break;
case '6':
hex_digit(ctok, 6);
break;
case '7':
hex_digit(ctok, 7);
break;
case '8':
hex_digit(ctok, 8);
break;
case '9':
hex_digit(ctok, 9);
break;
case 'a':
case 'A':
hex_digit(ctok, 10);
break;
case 'b':
case 'B':
hex_digit(ctok, 11);
break;
case 'c':
case 'C':
hex_digit(ctok, 12);
break;
case 'd':
case 'D':
hex_digit(ctok, 13);
break;
case 'e':
case 'E':
hex_digit(ctok, 14);
break;
case 'f':
case 'F':
hex_digit(ctok, 15);
break;
case 'p':
case 'P':
ctok->cur_tok->id = CTokIdNumLitFloat;
ctok->state = CTokStateExpSign;
break;
case 'u':
case 'U':
// marks the number literal as unsigned
ctok->state = CTokStateNumLitIntSuffixU;
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixU;
break;
case 'l':
case 'L':
// marks the number literal as long
ctok->state = CTokStateNumLitIntSuffixL;
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixL;
break;
default:
c -= 1;
end_token(ctok);
ctok->state = CTokStateStart;
continue;
}
break;
case CTokStateNumLitIntSuffixU:
switch (*c) {
case 'l':
case 'L':
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLU;
ctok->state = CTokStateNumLitIntSuffixUL;
break;
default:
c -= 1;
end_token(ctok);
ctok->state = CTokStateStart;
continue;
}
break;
case CTokStateNumLitIntSuffixL:
switch (*c) {
case 'l':
case 'L':
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLL;
ctok->state = CTokStateNumLitIntSuffixLL;
break;
case 'u':
case 'U':
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLU;
end_token(ctok);
ctok->state = CTokStateStart;
break;
default:
c -= 1;
end_token(ctok);
ctok->state = CTokStateStart;
continue;
}
break;
case CTokStateNumLitIntSuffixLL:
switch (*c) {
case 'u':
case 'U':
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLLU;
end_token(ctok);
ctok->state = CTokStateStart;
break;
default:
c -= 1;
end_token(ctok);
ctok->state = CTokStateStart;
continue;
}
break;
case CTokStateNumLitIntSuffixUL:
switch (*c) {
case 'l':
case 'L':
ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLLU;
end_token(ctok);
ctok->state = CTokStateStart;
break;
default:
c -= 1;
end_token(ctok);
ctok->state = CTokStateStart;
continue;
}
break;
case CTokStateIdentifier:
switch (*c) {
case IDENT:
buf_append_char(&ctok->cur_tok->data.symbol, *c);
break;
default:
c -= 1;
end_token(ctok);
ctok->state = CTokStateStart;
continue;
}
break;
case CTokStateString:
switch (*c) {
case '\\':
ctok->state = CTokStateCharEscape;
break;
case '\"':
end_token(ctok);
ctok->state = CTokStateStart;
break;
default:
buf_append_char(&ctok->cur_tok->data.str_lit, *c);
}
break;
case CTokStateExpectChar:
switch (*c) {
case '\\':
ctok->state = CTokStateCharEscape;
break;
case '\'':
return mark_error(ctok);
default:
ctok->cur_tok->data.char_lit = *c;
ctok->state = CTokStateExpectEndQuot;
}
break;
case CTokStateCharEscape:
switch (*c) {
case '\'':
case '"':
case '?':
case '\\':
add_char(ctok, *c);
break;
case 'a':
add_char(ctok, '\a');
break;
case 'b':
add_char(ctok, '\b');
break;
case 'f':
add_char(ctok, '\f');
break;
case 'n':
add_char(ctok, '\n');
break;
case 'r':
add_char(ctok, '\r');
break;
case 't':
add_char(ctok, '\t');
break;
case 'v':
add_char(ctok, '\v');
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
ctok->state = CTokStateStrOctal;
ctok->cur_char = (uint8_t)(*c - '0');
ctok->octal_index = 1;
break;
case 'x':
ctok->state = CTokStateStrHex;
ctok->cur_char = 0;
break;
case 'u':
zig_panic("TODO unicode");
break;
case 'U':
zig_panic("TODO Unicode");
break;
default:
return mark_error(ctok);
}
break;
case CTokStateStrHex: {
uint8_t value = 0;
switch (*c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
value = *c - '0';
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
value = (*c - 'a') + 10;
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
value = (*c - 'A') + 10;
break;
default:
c -= 1;
add_char(ctok, ctok->cur_char);
continue;
}
// TODO @mul_with_overflow
if (((long)ctok->cur_char) * 16 >= 256) {
zig_panic("TODO str hex mul overflow");
}
ctok->cur_char = (uint8_t)(ctok->cur_char * (uint8_t)16);
// TODO @add_with_overflow
if (((long)ctok->cur_char) + (long)(value) >= 256) {
zig_panic("TODO str hex add overflow");
}
ctok->cur_char = (uint8_t)(ctok->cur_char + value);
break;
}
case CTokStateStrOctal:
switch (*c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
// TODO @mul_with_overflow
if (((long)ctok->cur_char) * 8 >= 256) {
zig_panic("TODO");
}
ctok->cur_char = (uint8_t)(ctok->cur_char * (uint8_t)8);
// TODO @add_with_overflow
if (((long)ctok->cur_char) + (long)(*c - '0') >= 256) {
zig_panic("TODO");
}
ctok->cur_char = (uint8_t)(ctok->cur_char + (uint8_t)(*c - '0'));
ctok->octal_index += 1;
if (ctok->octal_index == 3) {
add_char(ctok, ctok->cur_char);
}
break;
default:
c -= 1;
add_char(ctok, ctok->cur_char);
continue;
}
break;
case CTokStateExpectEndQuot:
switch (*c) {
case '\'':
end_token(ctok);
ctok->state = CTokStateStart;
break;
default:
return mark_error(ctok);
}
break;
case CTokStateOpenComment:
switch (*c) {
case '/':
ctok->state = CTokStateLineComment;
break;
case '*':
ctok->state = CTokStateComment;
break;
default:
return mark_error(ctok);
}
break;
case CTokStateLineComment:
if (*c == '\n') {
ctok->state = CTokStateStart;
goto found_end_of_macro;
}
break;
case CTokStateComment:
switch (*c) {
case '*':
ctok->state = CTokStateCommentStar;
break;
default:
break;
}
break;
case CTokStateCommentStar:
switch (*c) {
case '/':
ctok->state = CTokStateStart;
break;
case '*':
break;
default:
ctok->state = CTokStateComment;
break;
}
break;
case CTokStateBackslash:
switch (*c) {
case '\n':
ctok->state = CTokStateStart;
break;
default:
return mark_error(ctok);
}
break;
}
}
found_end_of_macro:
switch (ctok->state) {
case CTokStateStart:
break;
case CTokStateIdentifier:
case CTokStateDecimal:
case CTokStateHex:
case CTokStateOctal:
case CTokStateGotZero:
case CTokStateNumLitIntSuffixU:
case CTokStateNumLitIntSuffixL:
case CTokStateNumLitIntSuffixUL:
case CTokStateNumLitIntSuffixLL:
case CTokStateGotLt:
end_token(ctok);
break;
case CTokStateFloat:
case CTokStateFloatExp:
end_float(ctok);
break;
case CTokStateExpectChar:
case CTokStateExpectEndQuot:
case CTokStateOpenComment:
case CTokStateLineComment:
case CTokStateComment:
case CTokStateCommentStar:
case CTokStateCharEscape:
case CTokStateBackslash:
case CTokStateString:
case CTokStateExpSign:
case CTokStateFloatExpFirst:
case CTokStateStrHex:
case CTokStateStrOctal:
return mark_error(ctok);
}
assert(ctok->cur_tok == nullptr);
begin_token(ctok, CTokIdEOF);
end_token(ctok);
}

View File

@ -1,98 +0,0 @@
/*
* Copyright (c) 2016 Andrew Kelley
*
* This file is part of zig, which is MIT licensed.
* See http://opensource.org/licenses/MIT
*/
#ifndef ZIG_C_TOKENIZER_HPP
#define ZIG_C_TOKENIZER_HPP
#include "buffer.hpp"
enum CTokId {
CTokIdCharLit,
CTokIdStrLit,
CTokIdNumLitInt,
CTokIdNumLitFloat,
CTokIdSymbol,
CTokIdMinus,
CTokIdLParen,
CTokIdRParen,
CTokIdEOF,
CTokIdDot,
CTokIdAsterisk,
CTokIdBang,
CTokIdTilde,
CTokIdShl,
CTokIdLt,
};
enum CNumLitSuffix {
CNumLitSuffixNone,
CNumLitSuffixL,
CNumLitSuffixU,
CNumLitSuffixLU,
CNumLitSuffixLL,
CNumLitSuffixLLU,
};
struct CNumLitInt {
uint64_t x;
CNumLitSuffix suffix;
};
struct CTok {
enum CTokId id;
union {
uint8_t char_lit;
Buf str_lit;
CNumLitInt num_lit_int;
double num_lit_float;
Buf symbol;
} data;
};
enum CTokState {
CTokStateStart,
CTokStateExpectChar,
CTokStateCharEscape,
CTokStateExpectEndQuot,
CTokStateOpenComment,
CTokStateLineComment,
CTokStateComment,
CTokStateCommentStar,
CTokStateBackslash,
CTokStateString,
CTokStateIdentifier,
CTokStateDecimal,
CTokStateOctal,
CTokStateGotZero,
CTokStateHex,
CTokStateFloat,
CTokStateExpSign,
CTokStateFloatExp,
CTokStateFloatExpFirst,
CTokStateStrHex,
CTokStateStrOctal,
CTokStateNumLitIntSuffixU,
CTokStateNumLitIntSuffixL,
CTokStateNumLitIntSuffixLL,
CTokStateNumLitIntSuffixUL,
CTokStateGotLt,
};
struct CTokenize {
ZigList<CTok> tokens;
CTokState state;
bool error;
CTok *cur_tok;
Buf buf;
uint8_t cur_char;
int octal_index;
};
void tokenize_c_macro(CTokenize *ctok, const uint8_t *c);
#endif

View File

@ -15,7 +15,6 @@
#include "hash_map.hpp" #include "hash_map.hpp"
#include "ir.hpp" #include "ir.hpp"
#include "os.hpp" #include "os.hpp"
#include "translate_c.hpp"
#include "target.hpp" #include "target.hpp"
#include "util.hpp" #include "util.hpp"
#include "zig_llvm.h" #include "zig_llvm.h"
@ -9104,7 +9103,7 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
} }
void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_userland_implementation) { void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file) {
Error err; Error err;
Buf *src_basename = buf_alloc(); Buf *src_basename = buf_alloc();
Buf *src_dirname = buf_alloc(); Buf *src_dirname = buf_alloc();
@ -9117,10 +9116,6 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
init(g); init(g);
TranslateMode trans_mode = buf_ends_with_str(full_path, ".h") ?
TranslateModeImport : TranslateModeTranslate;
ZigList<const char *> clang_argv = {0}; ZigList<const char *> clang_argv = {0};
add_cc_args(g, clang_argv, nullptr, true); add_cc_args(g, clang_argv, nullptr, true);
@ -9140,15 +9135,9 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
Stage2ErrorMsg *errors_ptr; Stage2ErrorMsg *errors_ptr;
size_t errors_len; size_t errors_len;
Stage2Ast *ast; Stage2Ast *ast;
AstNode *root_node;
if (use_userland_implementation) { err = stage2_translate_c(&ast, &errors_ptr, &errors_len,
err = stage2_translate_c(&ast, &errors_ptr, &errors_len, &clang_argv.at(0), &clang_argv.last(), resources_path);
&clang_argv.at(0), &clang_argv.last(), resources_path);
} else {
err = parse_h_file(g, &root_node, &errors_ptr, &errors_len, &clang_argv.at(0), &clang_argv.last(),
trans_mode, resources_path);
}
if (err == ErrorCCompileErrors && errors_len > 0) { if (err == ErrorCCompileErrors && errors_len > 0) {
for (size_t i = 0; i < errors_len; i += 1) { for (size_t i = 0; i < errors_len; i += 1) {
@ -9172,12 +9161,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
exit(1); exit(1);
} }
stage2_render_ast(ast, out_file);
if (use_userland_implementation) {
stage2_render_ast(ast, out_file);
} else {
ast_render(out_file, root_node, 4);
}
} }
static void update_test_functions_builtin_decl(CodeGen *g) { static void update_test_functions_builtin_decl(CodeGen *g) {

View File

@ -54,7 +54,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
void codegen_add_assembly(CodeGen *g, Buf *path); void codegen_add_assembly(CodeGen *g, Buf *path);
void codegen_add_object(CodeGen *g, Buf *object_path); void codegen_add_object(CodeGen *g, Buf *object_path);
void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_userland_implementation); void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file);
Buf *codegen_generate_builtin_source(CodeGen *g); Buf *codegen_generate_builtin_source(CodeGen *g);

View File

@ -13,7 +13,6 @@
#include "os.hpp" #include "os.hpp"
#include "range_set.hpp" #include "range_set.hpp"
#include "softfloat.hpp" #include "softfloat.hpp"
#include "translate_c.hpp"
#include "util.hpp" #include "util.hpp"
#include <errno.h> #include <errno.h>
@ -23762,14 +23761,14 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
clang_argv.append(nullptr); // to make the [start...end] argument work clang_argv.append(nullptr); // to make the [start...end] argument work
AstNode *root_node;
Stage2ErrorMsg *errors_ptr; Stage2ErrorMsg *errors_ptr;
size_t errors_len; size_t errors_len;
Stage2Ast *ast;
const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir); const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir);
if ((err = parse_h_file(ira->codegen, &root_node, &errors_ptr, &errors_len, if ((err = stage2_translate_c(&ast, &errors_ptr, &errors_len,
&clang_argv.at(0), &clang_argv.last(), TranslateModeImport, resources_path))) &clang_argv.at(0), &clang_argv.last(), resources_path)))
{ {
if (err != ErrorCCompileErrors) { if (err != ErrorCCompileErrors) {
ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err))); ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err)));
@ -23820,7 +23819,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
buf_sprintf("C import failed: unable to open output file: %s", strerror(errno))); buf_sprintf("C import failed: unable to open output file: %s", strerror(errno)));
return ira->codegen->invalid_instruction; return ira->codegen->invalid_instruction;
} }
ast_render(out_file, root_node, 4); stage2_render_ast(ast, out_file);
if (fclose(out_file) != 0) { if (fclose(out_file) != 0) {
ir_add_error_node(ira, node, ir_add_error_node(ira, node,
buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno))); buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno)));

View File

@ -243,7 +243,6 @@ enum Cmd {
CmdTargets, CmdTargets,
CmdTest, CmdTest,
CmdTranslateC, CmdTranslateC,
CmdTranslateCUserland,
CmdVersion, CmdVersion,
CmdZen, CmdZen,
CmdLibC, CmdLibC,
@ -960,8 +959,6 @@ int main(int argc, char **argv) {
cmd = CmdLibC; cmd = CmdLibC;
} else if (strcmp(arg, "translate-c") == 0) { } else if (strcmp(arg, "translate-c") == 0) {
cmd = CmdTranslateC; cmd = CmdTranslateC;
} else if (strcmp(arg, "translate-c-2") == 0) {
cmd = CmdTranslateCUserland;
} else if (strcmp(arg, "test") == 0) { } else if (strcmp(arg, "test") == 0) {
cmd = CmdTest; cmd = CmdTest;
out_type = OutTypeExe; out_type = OutTypeExe;
@ -978,7 +975,6 @@ int main(int argc, char **argv) {
case CmdBuild: case CmdBuild:
case CmdRun: case CmdRun:
case CmdTranslateC: case CmdTranslateC:
case CmdTranslateCUserland:
case CmdTest: case CmdTest:
case CmdLibC: case CmdLibC:
if (!in_file) { if (!in_file) {
@ -1112,7 +1108,6 @@ int main(int argc, char **argv) {
case CmdRun: case CmdRun:
case CmdBuild: case CmdBuild:
case CmdTranslateC: case CmdTranslateC:
case CmdTranslateCUserland:
case CmdTest: case CmdTest:
{ {
if (cmd == CmdBuild && !in_file && objects.length == 0 && if (cmd == CmdBuild && !in_file && objects.length == 0 &&
@ -1124,7 +1119,7 @@ int main(int argc, char **argv) {
" * --object argument\n" " * --object argument\n"
" * --c-source argument\n"); " * --c-source argument\n");
return print_error_usage(arg0); return print_error_usage(arg0);
} else if ((cmd == CmdTranslateC || cmd == CmdTranslateCUserland || } else if ((cmd == CmdTranslateC ||
cmd == CmdTest || cmd == CmdRun) && !in_file) cmd == CmdTest || cmd == CmdRun) && !in_file)
{ {
fprintf(stderr, "Expected source file argument.\n"); fprintf(stderr, "Expected source file argument.\n");
@ -1136,7 +1131,7 @@ int main(int argc, char **argv) {
assert(cmd != CmdBuild || out_type != OutTypeUnknown); assert(cmd != CmdBuild || out_type != OutTypeUnknown);
bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC || cmd == CmdTranslateCUserland); bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC);
if (cmd == CmdRun) { if (cmd == CmdRun) {
out_name = "run"; out_name = "run";
@ -1170,8 +1165,7 @@ int main(int argc, char **argv) {
return print_error_usage(arg0); return print_error_usage(arg0);
} }
Buf *zig_root_source_file = (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) ? Buf *zig_root_source_file = cmd == CmdTranslateC ? nullptr : in_file_buf;
nullptr : in_file_buf;
if (cmd == CmdRun && buf_out_name == nullptr) { if (cmd == CmdRun && buf_out_name == nullptr) {
buf_out_name = buf_create_from_str("run"); buf_out_name = buf_create_from_str("run");
@ -1336,8 +1330,8 @@ int main(int argc, char **argv) {
} else { } else {
zig_unreachable(); zig_unreachable();
} }
} else if (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) { } else if (cmd == CmdTranslateC) {
codegen_translate_c(g, in_file_buf, stdout, cmd == CmdTranslateCUserland); codegen_translate_c(g, in_file_buf, stdout);
if (timing_info) if (timing_info)
codegen_print_timing_report(g, stderr); codegen_print_timing_report(g, stderr);
return main_exit(root_progress_node, EXIT_SUCCESS); return main_exit(root_progress_node, EXIT_SUCCESS);

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +0,0 @@
/*
* Copyright (c) 2015 Andrew Kelley
*
* This file is part of zig, which is MIT licensed.
* See http://opensource.org/licenses/MIT
*/
#ifndef ZIG_PARSEC_HPP
#define ZIG_PARSEC_HPP
#include "all_types.hpp"
enum TranslateMode {
TranslateModeImport,
TranslateModeTranslate,
};
Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
Stage2ErrorMsg **errors_ptr, size_t *errors_len,
const char **args_begin, const char **args_end,
TranslateMode mode, const char *resources_path);
#endif

View File

@ -1686,6 +1686,16 @@ const struct ZigClangStmt *ZigClangFunctionDecl_getBody(const struct ZigClangFun
return reinterpret_cast<const ZigClangStmt *>(stmt); return reinterpret_cast<const ZigClangStmt *>(stmt);
} }
bool ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(const struct ZigClangFunctionDecl *self) {
auto casted = reinterpret_cast<const clang::FunctionDecl *>(self);
return casted->doesDeclarationForceExternallyVisibleDefinition();
}
bool ZigClangFunctionDecl_isInlineSpecified(const struct ZigClangFunctionDecl *self) {
auto casted = reinterpret_cast<const clang::FunctionDecl *>(self);
return casted->isInlineSpecified();
}
const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *self) { const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *self) {
auto casted = reinterpret_cast<const clang::TypedefType *>(self); auto casted = reinterpret_cast<const clang::TypedefType *>(self);
const clang::TypedefNameDecl *name_decl = casted->getDecl(); const clang::TypedefNameDecl *name_decl = casted->getDecl();

View File

@ -873,6 +873,8 @@ ZIG_EXTERN_C bool ZigClangFunctionDecl_hasBody(const struct ZigClangFunctionDecl
ZIG_EXTERN_C enum ZigClangStorageClass ZigClangFunctionDecl_getStorageClass(const struct ZigClangFunctionDecl *); ZIG_EXTERN_C enum ZigClangStorageClass ZigClangFunctionDecl_getStorageClass(const struct ZigClangFunctionDecl *);
ZIG_EXTERN_C const struct ZigClangParmVarDecl *ZigClangFunctionDecl_getParamDecl(const struct ZigClangFunctionDecl *, unsigned i); ZIG_EXTERN_C const struct ZigClangParmVarDecl *ZigClangFunctionDecl_getParamDecl(const struct ZigClangFunctionDecl *, unsigned i);
ZIG_EXTERN_C const struct ZigClangStmt *ZigClangFunctionDecl_getBody(const struct ZigClangFunctionDecl *); ZIG_EXTERN_C const struct ZigClangStmt *ZigClangFunctionDecl_getBody(const struct ZigClangFunctionDecl *);
ZIG_EXTERN_C bool ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(const struct ZigClangFunctionDecl *);
ZIG_EXTERN_C bool ZigClangFunctionDecl_isInlineSpecified(const struct ZigClangFunctionDecl *);
ZIG_EXTERN_C bool ZigClangRecordDecl_isUnion(const struct ZigClangRecordDecl *record_decl); ZIG_EXTERN_C bool ZigClangRecordDecl_isUnion(const struct ZigClangRecordDecl *record_decl);
ZIG_EXTERN_C bool ZigClangRecordDecl_isStruct(const struct ZigClangRecordDecl *record_decl); ZIG_EXTERN_C bool ZigClangRecordDecl_isStruct(const struct ZigClangRecordDecl *record_decl);

View File

@ -5,7 +5,11 @@ const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompareOutputContext) void { pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addC("hello world with libc", cases.addC("hello world with libc",
\\const c = @cImport(@cInclude("stdio.h")); \\const c = @cImport({
\\ // See https://github.com/ziglang/zig/issues/515
\\ @cDefine("_NO_CRT_STDIO_INLINE", "1");
\\ @cInclude("stdio.h");
\\});
\\pub export fn main(argc: c_int, argv: [*][*]u8) c_int { \\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
\\ _ = c.puts("Hello, world!"); \\ _ = c.puts("Hello, world!");
\\ return 0; \\ return 0;

View File

@ -1422,7 +1422,6 @@ pub const TranslateCContext = struct {
sources: ArrayList(SourceFile), sources: ArrayList(SourceFile),
expected_lines: ArrayList([]const u8), expected_lines: ArrayList([]const u8),
allow_warnings: bool, allow_warnings: bool,
stage2: bool,
const SourceFile = struct { const SourceFile = struct {
filename: []const u8, filename: []const u8,
@ -1475,7 +1474,7 @@ pub const TranslateCContext = struct {
var zig_args = ArrayList([]const u8).init(b.allocator); var zig_args = ArrayList([]const u8).init(b.allocator);
zig_args.append(b.zig_exe) catch unreachable; zig_args.append(b.zig_exe) catch unreachable;
const translate_c_cmd = if (self.case.stage2) "translate-c-2" else "translate-c"; const translate_c_cmd = "translate-c";
zig_args.append(translate_c_cmd) catch unreachable; zig_args.append(translate_c_cmd) catch unreachable;
zig_args.append(b.pathFromRoot(root_src)) catch unreachable; zig_args.append(b.pathFromRoot(root_src)) catch unreachable;
@ -1583,7 +1582,6 @@ pub const TranslateCContext = struct {
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator), .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_lines = ArrayList([]const u8).init(self.b.allocator), .expected_lines = ArrayList([]const u8).init(self.b.allocator),
.allow_warnings = allow_warnings, .allow_warnings = allow_warnings,
.stage2 = false,
}; };
tc.addSourceFile(filename, source); tc.addSourceFile(filename, source);
@ -1604,53 +1602,6 @@ pub const TranslateCContext = struct {
self.addCase(tc); self.addCase(tc);
} }
pub fn addC(
self: *TranslateCContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
const tc = self.create(false, "source.c", name, source, expected_lines);
self.addCase(tc);
}
pub fn add_both(
self: *TranslateCContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
for ([_]bool{ false, true }) |stage2| {
const tc = self.create(false, "source.h", name, source, expected_lines);
tc.stage2 = stage2;
self.addCase(tc);
}
}
pub fn addC_both(
self: *TranslateCContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
for ([_]bool{ false, true }) |stage2| {
const tc = self.create(false, "source.c", name, source, expected_lines);
tc.stage2 = stage2;
self.addCase(tc);
}
}
pub fn add_2(
self: *TranslateCContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
const tc = self.create(false, "source.h", name, source, expected_lines);
tc.stage2 = true;
self.addCase(tc);
}
pub fn addAllowWarnings( pub fn addAllowWarnings(
self: *TranslateCContext, self: *TranslateCContext,
name: []const u8, name: []const u8,
@ -1664,7 +1615,7 @@ pub const TranslateCContext = struct {
pub fn addCase(self: *TranslateCContext, case: *const TestCase) void { pub fn addCase(self: *TranslateCContext, case: *const TestCase) void {
const b = self.b; const b = self.b;
const translate_c_cmd = if (case.stage2) "translate-c-2" else "translate-c"; const translate_c_cmd = "translate-c";
const annotated_case_name = fmt.allocPrint(self.b.allocator, "{} {}", .{ translate_c_cmd, case.name }) catch unreachable; const annotated_case_name = fmt.allocPrint(self.b.allocator, "{} {}", .{ translate_c_cmd, case.name }) catch unreachable;
if (self.test_filter) |filter| { if (self.test_filter) |filter| {
if (mem.indexOf(u8, annotated_case_name, filter) == null) return; if (mem.indexOf(u8, annotated_case_name, filter) == null) return;

File diff suppressed because it is too large Load Diff