authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-13 15:48:10-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-12-13 15:48:10-05:00
log21a85d4fb643cf14cf4afbcfc7ecfd359b910097
tree34121806cdb748b441e2904f688fb90b78b0b5e1
parente54c49be9b4b1a97805a3ffaab3f21bac48b8851
parent45abfa9e7189e5d87d4d49763399531973c2f899
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #3896 from Vexu/translate-c-2

Translate-c self-hosted var decl and remove translate mode

13 files changed, 493 insertions(+), 214 deletions(-)

src-self-hosted/clang.zig+17-3
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
22
3pub const struct_ZigClangAPInt = @OpaqueType();
3pub const struct_ZigClangAPSInt = @OpaqueType();4pub const struct_ZigClangAPSInt = @OpaqueType();
4pub const struct_ZigClangAPFloat = @OpaqueType();5pub const struct_ZigClangAPFloat = @OpaqueType();
5pub const struct_ZigClangASTContext = @OpaqueType();6pub const struct_ZigClangASTContext = @OpaqueType();
...@@ -73,6 +74,7 @@ pub const struct_ZigClangVarDecl = @OpaqueType();...@@ -73,6 +74,7 @@ pub const struct_ZigClangVarDecl = @OpaqueType();
73pub const struct_ZigClangWhileStmt = @OpaqueType();74pub const struct_ZigClangWhileStmt = @OpaqueType();
74pub const struct_ZigClangFunctionType = @OpaqueType();75pub const struct_ZigClangFunctionType = @OpaqueType();
75pub const struct_ZigClangPredefinedExpr = @OpaqueType();76pub const struct_ZigClangPredefinedExpr = @OpaqueType();
77pub const struct_ZigClangInitListExpr = @OpaqueType();
7678
77pub const ZigClangBO = extern enum {79pub const ZigClangBO = extern enum {
78 PtrMemD,80 PtrMemD,
...@@ -733,7 +735,7 @@ pub extern fn ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl: ?*const s...@@ -733,7 +735,7 @@ pub extern fn ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl: ?*const s
733pub extern fn ZigClangEnumDecl_getIntegerType(self: ?*const struct_ZigClangEnumDecl) struct_ZigClangQualType;735pub extern fn ZigClangEnumDecl_getIntegerType(self: ?*const struct_ZigClangEnumDecl) struct_ZigClangQualType;
734pub extern fn ZigClangDecl_getName_bytes_begin(decl: ?*const struct_ZigClangDecl) [*c]const u8;736pub extern fn ZigClangDecl_getName_bytes_begin(decl: ?*const struct_ZigClangDecl) [*c]const u8;
735pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: struct_ZigClangSourceLocation) bool;737pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: struct_ZigClangSourceLocation) bool;
736pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) ?*const struct_ZigClangTypedefNameDecl;738pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) *const struct_ZigClangTypedefNameDecl;
737pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(self: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType;739pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(self: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType;
738pub extern fn ZigClangQualType_getCanonicalType(self: struct_ZigClangQualType) struct_ZigClangQualType;740pub extern fn ZigClangQualType_getCanonicalType(self: struct_ZigClangQualType) struct_ZigClangQualType;
739pub extern fn ZigClangQualType_getTypeClass(self: struct_ZigClangQualType) ZigClangTypeClass;741pub extern fn ZigClangQualType_getTypeClass(self: struct_ZigClangQualType) ZigClangTypeClass;
...@@ -747,17 +749,19 @@ pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigCl...@@ -747,17 +749,19 @@ pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigCl
747pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) struct_ZigClangQualType;749pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) struct_ZigClangQualType;
748pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;750pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
749pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8;751pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8;
752pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType;
750pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;753pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;
751pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;754pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;
752pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;755pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;
753pub extern fn ZigClangExpr_getStmtClass(self: ?*const struct_ZigClangExpr) ZigClangStmtClass;756pub extern fn ZigClangExpr_getStmtClass(self: ?*const struct_ZigClangExpr) ZigClangStmtClass;
754pub extern fn ZigClangExpr_getType(self: ?*const struct_ZigClangExpr) struct_ZigClangQualType;757pub extern fn ZigClangExpr_getType(self: ?*const struct_ZigClangExpr) struct_ZigClangQualType;
755pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;758pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;
759pub extern fn ZigClangInitListExpr_getInit(self: ?*const struct_ZigClangInitListExpr, i: c_uint) *const ZigClangExpr;
760pub extern fn ZigClangInitListExpr_getArrayFiller(self: ?*const struct_ZigClangInitListExpr) *const ZigClangExpr;
761pub extern fn ZigClangInitListExpr_getNumInits(self: ?*const struct_ZigClangInitListExpr) c_uint;
756pub extern fn ZigClangAPValue_getKind(self: ?*const struct_ZigClangAPValue) ZigClangAPValueKind;762pub extern fn ZigClangAPValue_getKind(self: ?*const struct_ZigClangAPValue) ZigClangAPValueKind;
757pub extern fn ZigClangAPValue_getInt(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPSInt;763pub extern fn ZigClangAPValue_getInt(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPSInt;
758pub extern fn ZigClangAPValue_getArrayInitializedElts(self: ?*const struct_ZigClangAPValue) c_uint;764pub extern fn ZigClangAPValue_getArrayInitializedElts(self: ?*const struct_ZigClangAPValue) c_uint;
759pub extern fn ZigClangAPValue_getArrayInitializedElt(self: ?*const struct_ZigClangAPValue, i: c_uint) ?*const struct_ZigClangAPValue;
760pub extern fn ZigClangAPValue_getArrayFiller(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPValue;
761pub extern fn ZigClangAPValue_getArraySize(self: ?*const struct_ZigClangAPValue) c_uint;765pub extern fn ZigClangAPValue_getArraySize(self: ?*const struct_ZigClangAPValue) c_uint;
762pub extern fn ZigClangAPValue_getLValueBase(self: ?*const struct_ZigClangAPValue) struct_ZigClangAPValueLValueBase;766pub extern fn ZigClangAPValue_getLValueBase(self: ?*const struct_ZigClangAPValue) struct_ZigClangAPValueLValueBase;
763pub extern fn ZigClangAPSInt_isSigned(self: ?*const struct_ZigClangAPSInt) bool;767pub extern fn ZigClangAPSInt_isSigned(self: ?*const struct_ZigClangAPSInt) bool;
...@@ -766,6 +770,8 @@ pub extern fn ZigClangAPSInt_negate(self: ?*const struct_ZigClangAPSInt) ?*const...@@ -766,6 +770,8 @@ pub extern fn ZigClangAPSInt_negate(self: ?*const struct_ZigClangAPSInt) ?*const
766pub extern fn ZigClangAPSInt_free(self: ?*const struct_ZigClangAPSInt) void;770pub extern fn ZigClangAPSInt_free(self: ?*const struct_ZigClangAPSInt) void;
767pub extern fn ZigClangAPSInt_getRawData(self: ?*const struct_ZigClangAPSInt) [*c]const u64;771pub extern fn ZigClangAPSInt_getRawData(self: ?*const struct_ZigClangAPSInt) [*c]const u64;
768pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_uint;772pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_uint;
773
774pub extern fn ZigClangAPInt_getLimitedValue(self: *const struct_ZigClangAPInt, limit: u64) u64;
769pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr;775pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr;
770pub extern fn ZigClangASTUnit_delete(self: ?*struct_ZigClangASTUnit) void;776pub extern fn ZigClangASTUnit_delete(self: ?*struct_ZigClangASTUnit) void;
771777
...@@ -863,6 +869,7 @@ pub const ZigClangVarDecl = struct_ZigClangVarDecl;...@@ -863,6 +869,7 @@ pub const ZigClangVarDecl = struct_ZigClangVarDecl;
863pub const ZigClangWhileStmt = struct_ZigClangWhileStmt;869pub const ZigClangWhileStmt = struct_ZigClangWhileStmt;
864pub const ZigClangFunctionType = struct_ZigClangFunctionType;870pub const ZigClangFunctionType = struct_ZigClangFunctionType;
865pub const ZigClangPredefinedExpr = struct_ZigClangPredefinedExpr;871pub const ZigClangPredefinedExpr = struct_ZigClangPredefinedExpr;
872pub const ZigClangInitListExpr = struct_ZigClangInitListExpr;
866873
867pub const struct_ZigClangSourceLocation = extern struct {874pub const struct_ZigClangSourceLocation = extern struct {
868 ID: c_uint,875 ID: c_uint,
...@@ -916,6 +923,9 @@ pub const ZigClangDeclStmt_const_decl_iterator = [*c]const *struct_ZigClangDecl;...@@ -916,6 +923,9 @@ pub const ZigClangDeclStmt_const_decl_iterator = [*c]const *struct_ZigClangDecl;
916pub extern fn ZigClangDeclStmt_decl_begin(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator;923pub extern fn ZigClangDeclStmt_decl_begin(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator;
917pub extern fn ZigClangDeclStmt_decl_end(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator;924pub extern fn ZigClangDeclStmt_decl_end(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator;
918925
926pub extern fn ZigClangVarDecl_getLocation(self: *const struct_ZigClangVarDecl) ZigClangSourceLocation;
927pub extern fn ZigClangVarDecl_hasInit(self: *const struct_ZigClangVarDecl) bool;
928pub extern fn ZigClangVarDecl_getStorageClass(self: *const ZigClangVarDecl) ZigClangStorageClass;
919pub extern fn ZigClangVarDecl_getType(self: ?*const struct_ZigClangVarDecl) struct_ZigClangQualType;929pub extern fn ZigClangVarDecl_getType(self: ?*const struct_ZigClangVarDecl) struct_ZigClangQualType;
920pub extern fn ZigClangVarDecl_getInit(*const ZigClangVarDecl) ?*const ZigClangExpr;930pub extern fn ZigClangVarDecl_getInit(*const ZigClangVarDecl) ?*const ZigClangExpr;
921pub extern fn ZigClangVarDecl_getTLSKind(self: ?*const struct_ZigClangVarDecl) ZigClangVarDecl_TLSKind;931pub extern fn ZigClangVarDecl_getTLSKind(self: ?*const struct_ZigClangVarDecl) ZigClangVarDecl_TLSKind;
...@@ -930,7 +940,10 @@ pub extern fn ZigClangImplicitCastExpr_getCastKind(*const ZigClangImplicitCastEx...@@ -930,7 +940,10 @@ pub extern fn ZigClangImplicitCastExpr_getCastKind(*const ZigClangImplicitCastEx
930pub extern fn ZigClangImplicitCastExpr_getSubExpr(*const ZigClangImplicitCastExpr) *const ZigClangExpr;940pub extern fn ZigClangImplicitCastExpr_getSubExpr(*const ZigClangImplicitCastExpr) *const ZigClangExpr;
931941
932pub extern fn ZigClangArrayType_getElementType(*const ZigClangArrayType) ZigClangQualType;942pub extern fn ZigClangArrayType_getElementType(*const ZigClangArrayType) ZigClangQualType;
943pub extern fn ZigClangIncompleteArrayType_getElementType(*const ZigClangIncompleteArrayType) ZigClangQualType;
933944
945pub extern fn ZigClangConstantArrayType_getElementType(self: *const struct_ZigClangConstantArrayType) ZigClangQualType;
946pub extern fn ZigClangConstantArrayType_getSize(self: *const struct_ZigClangConstantArrayType) *const struct_ZigClangAPInt;
934pub extern fn ZigClangDeclRefExpr_getDecl(*const ZigClangDeclRefExpr) *const ZigClangValueDecl;947pub extern fn ZigClangDeclRefExpr_getDecl(*const ZigClangDeclRefExpr) *const ZigClangValueDecl;
935948
936pub extern fn ZigClangParenType_getInnerType(*const ZigClangParenType) ZigClangQualType;949pub extern fn ZigClangParenType_getInnerType(*const ZigClangParenType) ZigClangQualType;
...@@ -957,6 +970,7 @@ pub const struct_ZigClangAPValue = extern struct {...@@ -957,6 +970,7 @@ pub const struct_ZigClangAPValue = extern struct {
957 Kind: ZigClangAPValueKind,970 Kind: ZigClangAPValueKind,
958 Data: if (builtin.os == .windows and builtin.abi == .msvc) [52]u8 else [68]u8,971 Data: if (builtin.os == .windows and builtin.abi == .msvc) [52]u8 else [68]u8,
959};972};
973pub extern fn ZigClangVarDecl_getTypeSourceInfo_getType(self: *const struct_ZigClangVarDecl) struct_ZigClangQualType;
960974
961pub extern fn ZigClangIntegerLiteral_EvaluateAsInt(*const ZigClangIntegerLiteral, *ZigClangExprEvalResult, *const ZigClangASTContext) bool;975pub extern fn ZigClangIntegerLiteral_EvaluateAsInt(*const ZigClangIntegerLiteral, *ZigClangExprEvalResult, *const ZigClangASTContext) bool;
962pub extern fn ZigClangIntegerLiteral_getBeginLoc(*const ZigClangIntegerLiteral) ZigClangSourceLocation;976pub extern fn ZigClangIntegerLiteral_getBeginLoc(*const ZigClangIntegerLiteral) ZigClangSourceLocation;
src-self-hosted/stage1.zig+1-11
...@@ -33,12 +33,6 @@ export fn stage2_panic(ptr: [*]const u8, len: usize) void {...@@ -33,12 +33,6 @@ export fn stage2_panic(ptr: [*]const u8, len: usize) void {
33 @panic(ptr[0..len]);33 @panic(ptr[0..len]);
34}34}
3535
36// ABI warning
37const TranslateMode = extern enum {
38 import,
39 translate,
40};
41
42// ABI warning36// ABI warning
43const Error = extern enum {37const Error = extern enum {
44 None,38 None,
...@@ -99,14 +93,10 @@ export fn stage2_translate_c(...@@ -99,14 +93,10 @@ export fn stage2_translate_c(
99 out_errors_len: *usize,93 out_errors_len: *usize,
100 args_begin: [*]?[*]const u8,94 args_begin: [*]?[*]const u8,
101 args_end: [*]?[*]const u8,95 args_end: [*]?[*]const u8,
102 mode: TranslateMode,
103 resources_path: [*]const u8,96 resources_path: [*]const u8,
104) Error {97) Error {
105 var errors: []translate_c.ClangErrMsg = undefined;98 var errors: []translate_c.ClangErrMsg = undefined;
106 out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, switch (mode) {99 out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) {
107 .import => translate_c.Mode.import,
108 .translate => translate_c.Mode.translate,
109 }, &errors, resources_path) catch |err| switch (err) {
110 error.SemanticAnalyzeFail => {100 error.SemanticAnalyzeFail => {
111 out_errors_ptr.* = errors.ptr;101 out_errors_ptr.* = errors.ptr;
112 out_errors_len.* = errors.len;102 out_errors_len.* = errors.len;
src-self-hosted/translate_c.zig+301-24
...@@ -7,11 +7,6 @@ const ast = std.zig.ast;...@@ -7,11 +7,6 @@ const ast = std.zig.ast;
7const Token = std.zig.Token;7const Token = std.zig.Token;
8usingnamespace @import("clang.zig");8usingnamespace @import("clang.zig");
99
10pub const Mode = enum {
11 import,
12 translate,
13};
14
15const CallingConvention = std.builtin.TypeInfo.CallingConvention;10const CallingConvention = std.builtin.TypeInfo.CallingConvention;
1611
17pub const ClangErrMsg = Stage2ErrorMsg;12pub const ClangErrMsg = Stage2ErrorMsg;
...@@ -104,7 +99,6 @@ const Context = struct {...@@ -104,7 +99,6 @@ const Context = struct {
104 source_manager: *ZigClangSourceManager,99 source_manager: *ZigClangSourceManager,
105 decl_table: DeclTable,100 decl_table: DeclTable,
106 global_scope: *Scope.Root,101 global_scope: *Scope.Root,
107 mode: Mode,
108 ptr_params: std.BufSet,102 ptr_params: std.BufSet,
109 clang_context: *ZigClangASTContext,103 clang_context: *ZigClangASTContext,
110104
...@@ -133,7 +127,6 @@ pub fn translate(...@@ -133,7 +127,6 @@ pub fn translate(
133 backing_allocator: *std.mem.Allocator,127 backing_allocator: *std.mem.Allocator,
134 args_begin: [*]?[*]const u8,128 args_begin: [*]?[*]const u8,
135 args_end: [*]?[*]const u8,129 args_end: [*]?[*]const u8,
136 mode: Mode,
137 errors: *[]ClangErrMsg,130 errors: *[]ClangErrMsg,
138 resources_path: [*]const u8,131 resources_path: [*]const u8,
139) !*ast.Tree {132) !*ast.Tree {
...@@ -185,7 +178,6 @@ pub fn translate(...@@ -185,7 +178,6 @@ pub fn translate(
185 .err = undefined,178 .err = undefined,
186 .decl_table = DeclTable.init(arena),179 .decl_table = DeclTable.init(arena),
187 .global_scope = try arena.create(Scope.Root),180 .global_scope = try arena.create(Scope.Root),
188 .mode = mode,
189 .ptr_params = std.BufSet.init(arena),181 .ptr_params = std.BufSet.init(arena),
190 .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,182 .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
191 };183 };
...@@ -228,7 +220,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {...@@ -228,7 +220,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
228 return visitFnDecl(c, @ptrCast(*const ZigClangFunctionDecl, decl));220 return visitFnDecl(c, @ptrCast(*const ZigClangFunctionDecl, decl));
229 },221 },
230 .Typedef => {222 .Typedef => {
231 try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for typedefs", .{});223 try resolveTypeDef(c, @ptrCast(*const ZigClangTypedefNameDecl, decl));
232 },224 },
233 .Enum => {225 .Enum => {
234 try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for enums", .{});226 try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for enums", .{});
...@@ -237,7 +229,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {...@@ -237,7 +229,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
237 try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for structs", .{});229 try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for structs", .{});
238 },230 },
239 .Var => {231 .Var => {
240 try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for variables", .{});232 return visitVarDecl(c, @ptrCast(*const ZigClangVarDecl, decl));
241 },233 },
242 else => {234 else => {
243 const decl_name = try c.str(ZigClangDecl_getDeclKindName(decl));235 const decl_name = try c.str(ZigClangDecl_getDeclKindName(decl));
...@@ -262,7 +254,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {...@@ -262,7 +254,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
262 .storage_class = storage_class,254 .storage_class = storage_class,
263 .scope = &scope,255 .scope = &scope,
264 .is_export = switch (storage_class) {256 .is_export = switch (storage_class) {
265 .None => has_body and c.mode != .import,257 .None => has_body,
266 .Extern, .Static => false,258 .Extern, .Static => false,
267 .PrivateExtern => return failDecl(c, fn_decl_loc, fn_name, "unsupported storage class: private extern", .{}),259 .PrivateExtern => return failDecl(c, fn_decl_loc, fn_name, "unsupported storage class: private extern", .{}),
268 .Auto => unreachable, // Not legal on functions260 .Auto => unreachable, // Not legal on functions
...@@ -310,6 +302,130 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {...@@ -310,6 +302,130 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
310 return addTopLevelDecl(c, fn_name, &proto_node.base);302 return addTopLevelDecl(c, fn_name, &proto_node.base);
311}303}
312304
305fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
306 if (try c.decl_table.put(@ptrToInt(var_decl), {})) |_| return; // Avoid processing this decl twice
307 const rp = makeRestorePoint(c);
308 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
309
310 const thread_local_token = if (ZigClangVarDecl_getTLSKind(var_decl) == .None)
311 null
312 else
313 try appendToken(c, .Keyword_threadlocal, "threadlocal");
314
315 var scope = &c.global_scope.base;
316 const var_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, var_decl)));
317 const var_decl_loc = ZigClangVarDecl_getLocation(var_decl);
318
319 const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);
320 const storage_class = ZigClangVarDecl_getStorageClass(var_decl);
321 const is_const = ZigClangQualType_isConstQualified(qual_type);
322
323 const extern_tok = if (storage_class == .Extern)
324 try appendToken(c, .Keyword_extern, "extern")
325 else if (storage_class != .Static)
326 try appendToken(c, .Keyword_export, "export")
327 else
328 null;
329
330 const mut_tok = if (is_const)
331 try appendToken(c, .Keyword_const, "const")
332 else
333 try appendToken(c, .Keyword_var, "var");
334
335 const name_tok = try appendToken(c, .Identifier, var_name);
336
337 _ = try appendToken(c, .Colon, ":");
338 const type_node = transQualType(rp, qual_type, var_decl_loc) catch |err| switch (err) {
339 error.UnsupportedType => {
340 return failDecl(c, var_decl_loc, var_name, "unable to resolve variable type", .{});
341 },
342 error.OutOfMemory => |e| return e,
343 };
344
345 var eq_tok: ast.TokenIndex = undefined;
346 var init_node: ?*ast.Node = null;
347
348 if (ZigClangVarDecl_hasInit(var_decl)) {
349 eq_tok = try appendToken(c, .Equal, "=");
350 init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr| blk: {
351 var res = transExpr(rp, &c.global_scope.base, expr, .used, .r_value) catch |err| switch (err) {
352 error.UnsupportedTranslation,
353 error.UnsupportedType,
354 => {
355 return failDecl(c, var_decl_loc, var_name, "unable to translate initializer", .{});
356 },
357 error.OutOfMemory => |e| return e,
358 };
359 break :blk res.node;
360 } else
361 try transCreateNodeUndefinedLiteral(c);
362 } else if (storage_class != .Extern) {
363 return failDecl(c, var_decl_loc, var_name, "non-extern variable has no initializer", .{});
364 }
365
366 const node = try c.a().create(ast.Node.VarDecl);
367 node.* = ast.Node.VarDecl{
368 .base = ast.Node{ .id = .VarDecl },
369 .doc_comments = null,
370 .visib_token = visib_tok,
371 .thread_local_token = thread_local_token,
372 .name_token = name_tok,
373 .eq_token = eq_tok,
374 .mut_token = mut_tok,
375 .comptime_token = null,
376 .extern_export_token = extern_tok,
377 .lib_name = null,
378 .type_node = type_node,
379 .align_node = null,
380 .section_node = null,
381 .init_node = init_node,
382 .semicolon_token = try appendToken(c, .Semicolon, ";"),
383 };
384 return addTopLevelDecl(c, var_name, &node.base);
385}
386
387fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error!void {
388 if (try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), {})) |_| return; // Avoid processing this decl twice
389 const rp = makeRestorePoint(c);
390 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
391 const const_tok = try appendToken(c, .Keyword_const, "const");
392
393 const typedef_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));
394 const name_tok = try appendToken(c, .Identifier, typedef_name);
395 const eq_tok = try appendToken(c, .Equal, "=");
396
397 const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
398 const typedef_loc = ZigClangTypedefNameDecl_getLocation(typedef_decl);
399 const type_node = transQualType(rp, child_qt, typedef_loc) catch |err| switch (err) {
400 error.UnsupportedType => {
401 const node = try failDecl(c, typedef_loc, typedef_name, "unable to resolve typedef child type", .{});
402 _ = try c.decl_table.put(@ptrToInt(typedef_decl), node);
403 return node;
404 },
405 error.OutOfMemory => |e| return e,
406 };
407
408 const node = try c.a().create(ast.Node.VarDecl);
409 node.* = ast.Node.VarDecl{
410 .base = ast.Node{ .id = .VarDecl },
411 .doc_comments = null,
412 .visib_token = visib_tok,
413 .thread_local_token = null,
414 .name_token = name_tok,
415 .eq_token = eq_tok,
416 .mut_token = const_tok,
417 .comptime_token = null,
418 .extern_export_token = null,
419 .lib_name = null,
420 .type_node = null,
421 .align_node = null,
422 .section_node = null,
423 .init_node = type_node,
424 .semicolon_token = try appendToken(c, .Semicolon, ";"),
425 };
426 try addTopLevelDecl(c, typedef_name, &node.base);
427}
428
313const ResultUsed = enum {429const ResultUsed = enum {
314 used,430 used,
315 unused,431 unused,
...@@ -339,6 +455,7 @@ fn transStmt(...@@ -339,6 +455,7 @@ fn transStmt(
339 .ReturnStmtClass => return transReturnStmt(rp, scope, @ptrCast(*const ZigClangReturnStmt, stmt)),455 .ReturnStmtClass => return transReturnStmt(rp, scope, @ptrCast(*const ZigClangReturnStmt, stmt)),
340 .StringLiteralClass => return transStringLiteral(rp, scope, @ptrCast(*const ZigClangStringLiteral, stmt), result_used),456 .StringLiteralClass => return transStringLiteral(rp, scope, @ptrCast(*const ZigClangStringLiteral, stmt), result_used),
341 .ParenExprClass => return transExpr(rp, scope, ZigClangParenExpr_getSubExpr(@ptrCast(*const ZigClangParenExpr, stmt)), result_used, lrvalue),457 .ParenExprClass => return transExpr(rp, scope, ZigClangParenExpr_getSubExpr(@ptrCast(*const ZigClangParenExpr, stmt)), result_used, lrvalue),
458 .InitListExprClass => return transInitListExpr(rp, scope, @ptrCast(*const ZigClangInitListExpr, stmt), result_used),
342 else => {459 else => {
343 return revertAndWarn(460 return revertAndWarn(
344 rp,461 rp,
...@@ -564,7 +681,7 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe...@@ -564,7 +681,7 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe
564 null681 null
565 else682 else
566 try appendToken(c, .Keyword_threadlocal, "threadlocal");683 try appendToken(c, .Keyword_threadlocal, "threadlocal");
567 const qual_type = ZigClangVarDecl_getType(var_decl);684 const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);
568 const mut_token = if (ZigClangQualType_isConstQualified(qual_type))685 const mut_token = if (ZigClangQualType_isConstQualified(qual_type))
569 try appendToken(c, .Keyword_const, "const")686 try appendToken(c, .Keyword_const, "const")
570 else687 else
...@@ -589,15 +706,8 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe...@@ -589,15 +706,8 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe
589 const eq_token = try appendToken(c, .Equal, "=");706 const eq_token = try appendToken(c, .Equal, "=");
590 const init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr|707 const init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr|
591 (try transExpr(rp, scope, expr, .used, .r_value)).node708 (try transExpr(rp, scope, expr, .used, .r_value)).node
592 else blk: {709 else
593 const undefined_token = try appendToken(c, .Keyword_undefined, "undefined");710 try transCreateNodeUndefinedLiteral(c);
594 const undefined_node = try rp.c.a().create(ast.Node.UndefinedLiteral);
595 undefined_node.* = ast.Node.UndefinedLiteral{
596 .base = ast.Node{ .id = .UndefinedLiteral },
597 .token = undefined_token,
598 };
599 break :blk &undefined_node.base;
600 };
601 const semicolon_token = try appendToken(c, .Semicolon, ";");711 const semicolon_token = try appendToken(c, .Semicolon, ";");
602712
603 const node = try c.a().create(ast.Node.VarDecl);713 const node = try c.a().create(ast.Node.VarDecl);
...@@ -687,7 +797,7 @@ fn transImplicitCastExpr(...@@ -687,7 +797,7 @@ fn transImplicitCastExpr(
687 .FunctionToPointerDecay, .ArrayToPointerDecay => {797 .FunctionToPointerDecay, .ArrayToPointerDecay => {
688 return maybeSuppressResult(rp, scope, result_used, sub_expr_node);798 return maybeSuppressResult(rp, scope, result_used, sub_expr_node);
689 },799 },
690 .LValueToRValue => {800 .LValueToRValue, .NoOp => {
691 return transExpr(rp, scope, sub_expr, .used, .r_value);801 return transExpr(rp, scope, sub_expr, .used, .r_value);
692 },802 },
693 else => |kind| return revertAndWarn(803 else => |kind| return revertAndWarn(
...@@ -868,6 +978,88 @@ fn transExpr(...@@ -868,6 +978,88 @@ fn transExpr(
868 return transStmt(rp, scope, @ptrCast(*const ZigClangStmt, expr), used, lrvalue);978 return transStmt(rp, scope, @ptrCast(*const ZigClangStmt, expr), used, lrvalue);
869}979}
870980
981fn transInitListExpr(
982 rp: RestorePoint,
983 scope: *Scope,
984 expr: *const ZigClangInitListExpr,
985 used: ResultUsed,
986) TransError!TransResult {
987 // TODO use anon literals once they work properly
988 const qt = getExprQualType(rp.c, @ptrCast(*const ZigClangExpr, expr));
989 const qual_type = ZigClangQualType_getTypePtr(qt);
990 const source_loc = ZigClangExpr_getBeginLoc(@ptrCast(*const ZigClangExpr, expr));
991 const arr_type = ZigClangType_getAsArrayTypeUnsafe(qual_type);
992 const child_qt = ZigClangArrayType_getElementType(arr_type);
993 const init_count = ZigClangInitListExpr_getNumInits(expr);
994 const all_count = 200; //ZigClangArrayType_getSize(arr_type);
995 const leftover_count = all_count - init_count;
996
997 var init_node: *ast.Node.SuffixOp = undefined;
998 var cat_tok: ast.TokenIndex = undefined;
999 if (init_count != 0) {
1000 var type_node = try transQualType(rp, qt, source_loc);
1001 init_node = try transCreateNodeArrayInitializer(rp.c, type_node);
1002 var i: c_uint = 0;
1003 while (i < init_count) : (i += 1) {
1004 const elem_expr = ZigClangInitListExpr_getInit(expr, i);
1005 try init_node.op.ArrayInitializer.push((try transExpr(rp, scope, elem_expr, .used, .r_value)).node);
1006 _ = try appendToken(rp.c, .Comma, ",");
1007 }
1008 init_node.rtoken = try appendToken(rp.c, .RBrace, "}");
1009 if (leftover_count == 0) {
1010 return TransResult{
1011 .node = &init_node.base,
1012 .child_scope = scope,
1013 .node_scope = scope,
1014 };
1015 }
1016 cat_tok = try appendToken(rp.c, .PlusPlus, "++");
1017 }
1018
1019 var filler_type_node = try transQualType(rp, qt, source_loc);
1020 var filler_init_node = try transCreateNodeArrayInitializer(rp.c, filler_type_node);
1021 const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr);
1022 try filler_init_node.op.ArrayInitializer.push((try transExpr(rp, scope, filler_val_expr, .used, .r_value)).node);
1023 filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}");
1024
1025 const rhs_node = if (leftover_count == 1)
1026 &filler_init_node.base
1027 else blk: {
1028 const mul_tok = try appendToken(rp.c, .AsteriskAsterisk, "**");
1029 const mul_node = try rp.c.a().create(ast.Node.InfixOp);
1030 mul_node.* = .{
1031 .base = .{ .id = .InfixOp },
1032 .op_token = mul_tok,
1033 .lhs = &filler_init_node.base,
1034 .op = .ArrayMult,
1035 .rhs = try transCreateNodeInt(rp.c, leftover_count),
1036 };
1037 break :blk &mul_node.base;
1038 };
1039
1040 if (init_count == 0) {
1041 return TransResult{
1042 .node = rhs_node,
1043 .child_scope = scope,
1044 .node_scope = scope,
1045 };
1046 }
1047
1048 const cat_node = try rp.c.a().create(ast.Node.InfixOp);
1049 cat_node.* = .{
1050 .base = .{ .id = .InfixOp },
1051 .op_token = cat_tok,
1052 .lhs = &init_node.base,
1053 .op = .ArrayCat,
1054 .rhs = rhs_node,
1055 };
1056 return TransResult{
1057 .node = &cat_node.base,
1058 .child_scope = scope,
1059 .node_scope = scope,
1060 };
1061}
1062
871fn findBlockScope(inner: *Scope) *Scope.Block {1063fn findBlockScope(inner: *Scope) *Scope.Block {
872 var scope = inner;1064 var scope = inner;
873 while (true) : (scope = scope.parent orelse unreachable) {1065 while (true) : (scope = scope.parent orelse unreachable) {
...@@ -1233,6 +1425,40 @@ fn transCreateNodeReturnExpr(c: *Context) !*ast.Node {...@@ -1233,6 +1425,40 @@ fn transCreateNodeReturnExpr(c: *Context) !*ast.Node {
1233 return &node.base;1425 return &node.base;
1234}1426}
12351427
1428fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node {
1429 const token = try appendToken(c, .Keyword_undefined, "undefined");
1430 const node = try c.a().create(ast.Node.UndefinedLiteral);
1431 node.* = ast.Node.UndefinedLiteral{
1432 .base = ast.Node{ .id = .UndefinedLiteral },
1433 .token = token,
1434 };
1435 return &node.base;
1436}
1437
1438fn transCreateNodeArrayInitializer(c: *Context, type_node: *ast.Node) !*ast.Node.SuffixOp {
1439 _ = try appendToken(c, .LBrace, "{");
1440 const node = try c.a().create(ast.Node.SuffixOp);
1441 node.* = ast.Node.SuffixOp{
1442 .base = ast.Node{ .id = .SuffixOp },
1443 .lhs = .{ .node = type_node },
1444 .op = .{
1445 .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
1446 },
1447 .rtoken = undefined, // set after appending values
1448 };
1449 return node;
1450}
1451
1452fn transCreateNodeInt(c: *Context, int: var) !*ast.Node {
1453 const token = try appendToken(c, .IntegerLiteral, try std.fmt.allocPrint(c.a(), "{}", .{int}));
1454 const node = try c.a().create(ast.Node.IntegerLiteral);
1455 node.* = ast.Node.IntegerLiteral{
1456 .base = ast.Node{ .id = .IntegerLiteral },
1457 .token = token,
1458 };
1459 return &node.base;
1460}
1461
1236const RestorePoint = struct {1462const RestorePoint = struct {
1237 c: *Context,1463 c: *Context,
1238 token_index: ast.TokenIndex,1464 token_index: ast.TokenIndex,
...@@ -1316,6 +1542,47 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour...@@ -1316,6 +1542,47 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
1316 pointer_node.rhs = try transQualType(rp, child_qt, source_loc);1542 pointer_node.rhs = try transQualType(rp, child_qt, source_loc);
1317 return &pointer_node.base;1543 return &pointer_node.base;
1318 },1544 },
1545 .ConstantArray => {
1546 const const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, ty);
1547
1548 const size_ap_int = ZigClangConstantArrayType_getSize(const_arr_ty);
1549 const size = ZigClangAPInt_getLimitedValue(size_ap_int, std.math.maxInt(usize));
1550 var node = try transCreateNodePrefixOp(
1551 rp.c,
1552 .{
1553 .ArrayType = .{
1554 .len_expr = undefined,
1555 .sentinel = null,
1556 },
1557 },
1558 .LBracket,
1559 "[",
1560 );
1561 node.op.ArrayType.len_expr = try transCreateNodeInt(rp.c, size);
1562 _ = try appendToken(rp.c, .RBracket, "]");
1563 node.rhs = try transQualType(rp, ZigClangConstantArrayType_getElementType(const_arr_ty), source_loc);
1564 return &node.base;
1565 },
1566 .IncompleteArray => {
1567 const incomplete_array_ty = @ptrCast(*const ZigClangIncompleteArrayType, ty);
1568
1569 const child_qt = ZigClangIncompleteArrayType_getElementType(incomplete_array_ty);
1570 var node = try transCreateNodePtrType(
1571 rp.c,
1572 ZigClangQualType_isConstQualified(child_qt),
1573 ZigClangQualType_isVolatileQualified(child_qt),
1574 .Identifier,
1575 );
1576 node.rhs = try transQualType(rp, child_qt, source_loc);
1577 return &node.base;
1578 },
1579 .Typedef => {
1580 const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);
1581
1582 const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
1583 const typedef_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));
1584 return appendIdentifier(rp.c, typedef_name);
1585 },
1319 else => {1586 else => {
1320 const type_name = rp.c.str(ZigClangType_getTypeClassName(ty));1587 const type_name = rp.c.str(ZigClangType_getTypeClassName(ty));
1321 return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported type: '{}'", .{type_name});1588 return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported type: '{}'", .{type_name});
...@@ -1323,6 +1590,15 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour...@@ -1323,6 +1590,15 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
1323 }1590 }
1324}1591}
13251592
1593fn isCVoid(qt: ZigClangQualType) bool {
1594 const ty = ZigClangQualType_getTypePtr(qt);
1595 if (ZigClangType_getTypeClass(ty) == .Builtin) {
1596 const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
1597 return ZigClangBuiltinType_getKind(builtin_ty) == .Void;
1598 }
1599 return false;
1600}
1601
1326const FnDeclContext = struct {1602const FnDeclContext = struct {
1327 fn_name: []const u8,1603 fn_name: []const u8,
1328 has_body: bool,1604 has_body: bool,
...@@ -1473,7 +1749,8 @@ fn finishTransFnProto(...@@ -1473,7 +1749,8 @@ fn finishTransFnProto(
1473 break :blk try appendIdentifier(rp.c, "noreturn");1749 break :blk try appendIdentifier(rp.c, "noreturn");
1474 } else {1750 } else {
1475 const return_qt = ZigClangFunctionType_getReturnType(fn_ty);1751 const return_qt = ZigClangFunctionType_getReturnType(fn_ty);
1476 if (ZigClangType_isVoidType(qualTypeCanon(return_qt))) {1752 if (isCVoid(return_qt)) {
1753 // convert primitive c_void to actual void (only for return type)
1477 break :blk try appendIdentifier(rp.c, "void");1754 break :blk try appendIdentifier(rp.c, "void");
1478 } else {1755 } else {
1479 break :blk transQualType(rp, return_qt, source_loc) catch |err| switch (err) {1756 break :blk transQualType(rp, return_qt, source_loc) catch |err| switch (err) {
...@@ -1568,7 +1845,7 @@ fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comptime...@@ -1568,7 +1845,7 @@ fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comptime
1568 .init_node = &call_node.base,1845 .init_node = &call_node.base,
1569 .semicolon_token = semi_tok,1846 .semicolon_token = semi_tok,
1570 };1847 };
1571 try c.tree.root_node.decls.push(&var_decl_node.base);1848 try addTopLevelDecl(c, name, &var_decl_node.base);
1572}1849}
15731850
1574fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenIndex {1851fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenIndex {
src/codegen.cpp+3-3
...@@ -9016,8 +9016,8 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us...@@ -9016,8 +9016,8 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
90169016
9017 init(g);9017 init(g);
90189018
9019 Stage2TranslateMode trans_mode = buf_ends_with_str(full_path, ".h") ?9019 TranslateMode trans_mode = buf_ends_with_str(full_path, ".h") ?
9020 Stage2TranslateModeImport : Stage2TranslateModeTranslate;9020 TranslateModeImport : TranslateModeTranslate;
90219021
90229022
9023 ZigList<const char *> clang_argv = {0};9023 ZigList<const char *> clang_argv = {0};
...@@ -9043,7 +9043,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us...@@ -9043,7 +9043,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
90439043
9044 if (use_userland_implementation) {9044 if (use_userland_implementation) {
9045 err = stage2_translate_c(&ast, &errors_ptr, &errors_len,9045 err = stage2_translate_c(&ast, &errors_ptr, &errors_len,
9046 &clang_argv.at(0), &clang_argv.last(), trans_mode, resources_path);9046 &clang_argv.at(0), &clang_argv.last(), resources_path);
9047 } else {9047 } else {
9048 err = parse_h_file(g, &root_node, &errors_ptr, &errors_len, &clang_argv.at(0), &clang_argv.last(),9048 err = parse_h_file(g, &root_node, &errors_ptr, &errors_len, &clang_argv.at(0), &clang_argv.last(),
9049 trans_mode, resources_path);9049 trans_mode, resources_path);
src/ir.cpp+1-1
...@@ -23303,7 +23303,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct...@@ -23303,7 +23303,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
23303 const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir);23303 const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir);
2330423304
23305 if ((err = parse_h_file(ira->codegen, &root_node, &errors_ptr, &errors_len,23305 if ((err = parse_h_file(ira->codegen, &root_node, &errors_ptr, &errors_len,
23306 &clang_argv.at(0), &clang_argv.last(), Stage2TranslateModeImport, resources_path)))23306 &clang_argv.at(0), &clang_argv.last(), TranslateModeImport, resources_path)))
23307 {23307 {
23308 if (err != ErrorCCompileErrors) {23308 if (err != ErrorCCompileErrors) {
23309 ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err)));23309 ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err)));
src/translate_c.cpp+6-9
...@@ -64,7 +64,6 @@ struct TransScopeWhile {...@@ -64,7 +64,6 @@ struct TransScopeWhile {
6464
65struct Context {65struct Context {
66 AstNode *root;66 AstNode *root;
67 VisibMod visib_mod;
68 bool want_export;67 bool want_export;
69 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;68 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
70 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;69 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
...@@ -367,7 +366,7 @@ static AstNode *trans_create_node_var_decl(Context *c, VisibMod visib_mod, bool...@@ -367,7 +366,7 @@ static AstNode *trans_create_node_var_decl(Context *c, VisibMod visib_mod, bool
367static AstNode *trans_create_node_var_decl_global(Context *c, bool is_const, Buf *var_name, AstNode *type_node,366static AstNode *trans_create_node_var_decl_global(Context *c, bool is_const, Buf *var_name, AstNode *type_node,
368 AstNode *init_node)367 AstNode *init_node)
369{368{
370 return trans_create_node_var_decl(c, c->visib_mod, is_const, var_name, type_node, init_node);369 return trans_create_node_var_decl(c, VisibModPub, is_const, var_name, type_node, init_node);
371}370}
372371
373static AstNode *trans_create_node_var_decl_local(Context *c, bool is_const, Buf *var_name, AstNode *type_node,372static AstNode *trans_create_node_var_decl_local(Context *c, bool is_const, Buf *var_name, AstNode *type_node,
...@@ -379,7 +378,7 @@ static AstNode *trans_create_node_var_decl_local(Context *c, bool is_const, Buf...@@ -379,7 +378,7 @@ static AstNode *trans_create_node_var_decl_local(Context *c, bool is_const, Buf
379static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, AstNode *ref_node, AstNode *src_proto_node) {378static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, AstNode *ref_node, AstNode *src_proto_node) {
380 AstNode *fn_def = trans_create_node(c, NodeTypeFnDef);379 AstNode *fn_def = trans_create_node(c, NodeTypeFnDef);
381 AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto);380 AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto);
382 fn_proto->data.fn_proto.visib_mod = c->visib_mod;381 fn_proto->data.fn_proto.visib_mod = VisibModPub;
383 fn_proto->data.fn_proto.name = fn_name;382 fn_proto->data.fn_proto.name = fn_name;
384 fn_proto->data.fn_proto.fn_inline = FnInlineAlways;383 fn_proto->data.fn_proto.fn_inline = FnInlineAlways;
385 fn_proto->data.fn_proto.return_type = src_proto_node->data.fn_proto.return_type; // TODO ok for these to alias?384 fn_proto->data.fn_proto.return_type = src_proto_node->data.fn_proto.return_type; // TODO ok for these to alias?
...@@ -4091,10 +4090,10 @@ static void visit_fn_decl(Context *c, const ZigClangFunctionDecl *fn_decl) {...@@ -4091,10 +4090,10 @@ static void visit_fn_decl(Context *c, const ZigClangFunctionDecl *fn_decl) {
40914090
4092 ZigClangStorageClass sc = ZigClangFunctionDecl_getStorageClass(fn_decl);4091 ZigClangStorageClass sc = ZigClangFunctionDecl_getStorageClass(fn_decl);
4093 if (sc == ZigClangStorageClass_None) {4092 if (sc == ZigClangStorageClass_None) {
4094 proto_node->data.fn_proto.visib_mod = c->visib_mod;4093 proto_node->data.fn_proto.visib_mod = VisibModPub;
4095 proto_node->data.fn_proto.is_export = ZigClangFunctionDecl_hasBody(fn_decl) ? c->want_export : false;4094 proto_node->data.fn_proto.is_export = ZigClangFunctionDecl_hasBody(fn_decl) ? c->want_export : false;
4096 } else if (sc == ZigClangStorageClass_Extern || sc == ZigClangStorageClass_Static) {4095 } else if (sc == ZigClangStorageClass_Extern || sc == ZigClangStorageClass_Static) {
4097 proto_node->data.fn_proto.visib_mod = c->visib_mod;4096 proto_node->data.fn_proto.visib_mod = VisibModPub;
4098 } else if (sc == ZigClangStorageClass_PrivateExtern) {4097 } else if (sc == ZigClangStorageClass_PrivateExtern) {
4099 emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl), "unsupported storage class: private extern");4098 emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl), "unsupported storage class: private extern");
4100 return;4099 return;
...@@ -5113,16 +5112,14 @@ static void process_preprocessor_entities(Context *c, ZigClangASTUnit *unit) {...@@ -5113,16 +5112,14 @@ static void process_preprocessor_entities(Context *c, ZigClangASTUnit *unit) {
5113Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,5112Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
5114 Stage2ErrorMsg **errors_ptr, size_t *errors_len,5113 Stage2ErrorMsg **errors_ptr, size_t *errors_len,
5115 const char **args_begin, const char **args_end,5114 const char **args_begin, const char **args_end,
5116 Stage2TranslateMode mode, const char *resources_path)5115 TranslateMode mode, const char *resources_path)
5117{5116{
5118 Context context = {0};5117 Context context = {0};
5119 Context *c = &context;5118 Context *c = &context;
5120 c->warnings_on = codegen->verbose_cimport;5119 c->warnings_on = codegen->verbose_cimport;
5121 if (mode == Stage2TranslateModeImport) {5120 if (mode == TranslateModeImport) {
5122 c->visib_mod = VisibModPub;
5123 c->want_export = false;5121 c->want_export = false;
5124 } else {5122 } else {
5125 c->visib_mod = VisibModPub;
5126 c->want_export = true;5123 c->want_export = true;
5127 }5124 }
5128 c->decl_table.init(8);5125 c->decl_table.init(8);
src/translate_c.hpp+6-1
...@@ -11,9 +11,14 @@...@@ -11,9 +11,14 @@
1111
12#include "all_types.hpp"12#include "all_types.hpp"
1313
14enum TranslateMode {
15 TranslateModeImport,
16 TranslateModeTranslate,
17};
18
14Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,19Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
15 Stage2ErrorMsg **errors_ptr, size_t *errors_len,20 Stage2ErrorMsg **errors_ptr, size_t *errors_len,
16 const char **args_begin, const char **args_end,21 const char **args_begin, const char **args_end,
17 Stage2TranslateMode mode, const char *resources_path);22 TranslateMode mode, const char *resources_path);
1823
19#endif24#endif
src/userland.cpp+1-2
...@@ -9,8 +9,7 @@...@@ -9,8 +9,7 @@
99
10Error stage2_translate_c(struct Stage2Ast **out_ast,10Error stage2_translate_c(struct Stage2Ast **out_ast,
11 struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,11 struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
12 const char **args_begin, const char **args_end, enum Stage2TranslateMode mode,12 const char **args_begin, const char **args_end, const char *resources_path)
13 const char *resources_path)
14{13{
15 const char *msg = "stage0 called stage2_translate_c";14 const char *msg = "stage0 called stage2_translate_c";
16 stage2_panic(msg, strlen(msg));15 stage2_panic(msg, strlen(msg));
src/userland.h+1-8
...@@ -80,12 +80,6 @@ enum Error {...@@ -80,12 +80,6 @@ enum Error {
80 ErrorImportOutsidePkgPath,80 ErrorImportOutsidePkgPath,
81};81};
8282
83// ABI warning
84enum Stage2TranslateMode {
85 Stage2TranslateModeImport,
86 Stage2TranslateModeTranslate,
87};
88
89// ABI warning83// ABI warning
90struct Stage2ErrorMsg {84struct Stage2ErrorMsg {
91 const char *filename_ptr; // can be null85 const char *filename_ptr; // can be null
...@@ -104,8 +98,7 @@ struct Stage2Ast;...@@ -104,8 +98,7 @@ struct Stage2Ast;
104// ABI warning98// ABI warning
105ZIG_EXTERN_C enum Error stage2_translate_c(struct Stage2Ast **out_ast,99ZIG_EXTERN_C enum Error stage2_translate_c(struct Stage2Ast **out_ast,
106 struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,100 struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
107 const char **args_begin, const char **args_end, enum Stage2TranslateMode mode,101 const char **args_begin, const char **args_end, const char *resources_path);
108 const char *resources_path);
109102
110// ABI warning103// ABI warning
111ZIG_EXTERN_C void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len);104ZIG_EXTERN_C void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len);
src/zig_clang.cpp+22
...@@ -1825,6 +1825,23 @@ bool ZigClangExpr_EvaluateAsConstantExpr(const ZigClangExpr *self, ZigClangExprE...@@ -1825,6 +1825,23 @@ bool ZigClangExpr_EvaluateAsConstantExpr(const ZigClangExpr *self, ZigClangExprE
1825 return true;1825 return true;
1826}1826}
18271827
1828const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *self, unsigned i) {
1829 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
1830 const clang::Expr *result = casted->getInit(i);
1831 return reinterpret_cast<const ZigClangExpr *>(result);
1832}
1833
1834const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *self) {
1835 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
1836 const clang::Expr *result = casted->getArrayFiller();
1837 return reinterpret_cast<const ZigClangExpr *>(result);
1838}
1839
1840unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *self) {
1841 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
1842 return casted->getNumInits();
1843}
1844
1828ZigClangAPValueKind ZigClangAPValue_getKind(const ZigClangAPValue *self) {1845ZigClangAPValueKind ZigClangAPValue_getKind(const ZigClangAPValue *self) {
1829 auto casted = reinterpret_cast<const clang::APValue *>(self);1846 auto casted = reinterpret_cast<const clang::APValue *>(self);
1830 return (ZigClangAPValueKind)casted->getKind();1847 return (ZigClangAPValueKind)casted->getKind();
...@@ -2065,6 +2082,11 @@ const ZigClangAPValue * ZigClangVarDecl_evaluateValue(const struct ZigClangVarDe...@@ -2065,6 +2082,11 @@ const ZigClangAPValue * ZigClangVarDecl_evaluateValue(const struct ZigClangVarDe
2065 return reinterpret_cast<const ZigClangAPValue *>(result);2082 return reinterpret_cast<const ZigClangAPValue *>(result);
2066}2083}
20672084
2085enum ZigClangStorageClass ZigClangVarDecl_getStorageClass(const struct ZigClangVarDecl *self) {
2086 auto casted = reinterpret_cast<const clang::VarDecl *>(self);
2087 return (ZigClangStorageClass)casted->getStorageClass();
2088}
2089
2068enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBuiltinType *self) {2090enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBuiltinType *self) {
2069 auto casted = reinterpret_cast<const clang::BuiltinType *>(self);2091 auto casted = reinterpret_cast<const clang::BuiltinType *>(self);
2070 return (ZigClangBuiltinTypeKind)casted->getKind();2092 return (ZigClangBuiltinTypeKind)casted->getKind();
src/zig_clang.h+6
...@@ -144,6 +144,7 @@ struct ZigClangUnaryOperator;...@@ -144,6 +144,7 @@ struct ZigClangUnaryOperator;
144struct ZigClangValueDecl;144struct ZigClangValueDecl;
145struct ZigClangVarDecl;145struct ZigClangVarDecl;
146struct ZigClangWhileStmt;146struct ZigClangWhileStmt;
147struct ZigClangInitListExpr;
147148
148typedef struct ZigClangStmt *const * ZigClangCompoundStmt_const_body_iterator;149typedef struct ZigClangStmt *const * ZigClangCompoundStmt_const_body_iterator;
149typedef struct ZigClangDecl *const * ZigClangDeclStmt_const_decl_iterator;150typedef struct ZigClangDecl *const * ZigClangDeclStmt_const_decl_iterator;
...@@ -904,6 +905,7 @@ ZIG_EXTERN_C bool ZigClangVarDecl_isFileVarDecl(const struct ZigClangVarDecl *);...@@ -904,6 +905,7 @@ ZIG_EXTERN_C bool ZigClangVarDecl_isFileVarDecl(const struct ZigClangVarDecl *);
904ZIG_EXTERN_C bool ZigClangVarDecl_hasInit(const struct ZigClangVarDecl *);905ZIG_EXTERN_C bool ZigClangVarDecl_hasInit(const struct ZigClangVarDecl *);
905ZIG_EXTERN_C const struct ZigClangAPValue *ZigClangVarDecl_evaluateValue(const struct ZigClangVarDecl *);906ZIG_EXTERN_C const struct ZigClangAPValue *ZigClangVarDecl_evaluateValue(const struct ZigClangVarDecl *);
906ZIG_EXTERN_C struct ZigClangQualType ZigClangVarDecl_getTypeSourceInfo_getType(const struct ZigClangVarDecl *);907ZIG_EXTERN_C struct ZigClangQualType ZigClangVarDecl_getTypeSourceInfo_getType(const struct ZigClangVarDecl *);
908ZIG_EXTERN_C enum ZigClangStorageClass ZigClangVarDecl_getStorageClass(const struct ZigClangVarDecl *self);
907909
908ZIG_EXTERN_C bool ZigClangSourceLocation_eq(struct ZigClangSourceLocation a, struct ZigClangSourceLocation b);910ZIG_EXTERN_C bool ZigClangSourceLocation_eq(struct ZigClangSourceLocation a, struct ZigClangSourceLocation b);
909911
...@@ -939,6 +941,10 @@ ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsFloat(const struct ZigClangExpr *self,...@@ -939,6 +941,10 @@ ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsFloat(const struct ZigClangExpr *self,
939ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *,941ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *,
940 struct ZigClangExprEvalResult *, ZigClangExpr_ConstExprUsage, const struct ZigClangASTContext *);942 struct ZigClangExprEvalResult *, ZigClangExpr_ConstExprUsage, const struct ZigClangASTContext *);
941943
944ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned);
945ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *);
946ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *);
947
942ZIG_EXTERN_C enum ZigClangAPValueKind ZigClangAPValue_getKind(const struct ZigClangAPValue *self);948ZIG_EXTERN_C enum ZigClangAPValueKind ZigClangAPValue_getKind(const struct ZigClangAPValue *self);
943ZIG_EXTERN_C const struct ZigClangAPSInt *ZigClangAPValue_getInt(const struct ZigClangAPValue *self);949ZIG_EXTERN_C const struct ZigClangAPSInt *ZigClangAPValue_getInt(const struct ZigClangAPValue *self);
944ZIG_EXTERN_C unsigned ZigClangAPValue_getArrayInitializedElts(const struct ZigClangAPValue *self);950ZIG_EXTERN_C unsigned ZigClangAPValue_getArrayInitializedElts(const struct ZigClangAPValue *self);
test/tests.zig-11
...@@ -1651,17 +1651,6 @@ pub const TranslateCContext = struct {...@@ -1651,17 +1651,6 @@ pub const TranslateCContext = struct {
1651 self.addCase(tc);1651 self.addCase(tc);
1652 }1652 }
16531653
1654 pub fn addC_2(
1655 self: *TranslateCContext,
1656 name: []const u8,
1657 source: []const u8,
1658 expected_lines: []const []const u8,
1659 ) void {
1660 const tc = self.create(false, "source.c", name, source, expected_lines);
1661 tc.stage2 = true;
1662 self.addCase(tc);
1663 }
1664
1665 pub fn addAllowWarnings(1654 pub fn addAllowWarnings(
1666 self: *TranslateCContext,1655 self: *TranslateCContext,
1667 name: []const u8,1656 name: []const u8,
test/translate_c.zig+128-141
...@@ -3,10 +3,9 @@ const builtin = @import("builtin");...@@ -3,10 +3,9 @@ const builtin = @import("builtin");
33
4// add_both - test for stage1 and stage2, in #include mode4// add_both - test for stage1 and stage2, in #include mode
5// add - test stage1 only, in #include mode5// add - test stage1 only, in #include mode
6// add_2 - test stage2 only, in #include mode6// add_2 - test stage2 only
7// addC_both - test for stage1 and stage2, in -c mode7// addC_both - test for stage1 and stage2, in -c mode
8// addC - test stage1 only, in -c mode8// addC - test stage1 only, in -c mode
9// addC_2 - test stage2 only, in -c mode
109
11pub fn addCases(cases: *tests.TranslateCContext) void {10pub fn addCases(cases: *tests.TranslateCContext) void {
12 /////////////// Cases that pass for both stage1/stage2 ////////////////11 /////////////// Cases that pass for both stage1/stage2 ////////////////
...@@ -18,7 +17,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -18,7 +17,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
18 \\pub extern fn bar() c_int;17 \\pub extern fn bar() c_int;
19 });18 });
2019
21 cases.add_both("simple var decls",20 cases.addC_both("simple var decls",
22 \\void foo(void) {21 \\void foo(void) {
23 \\ int a;22 \\ int a;
24 \\ char b = 123;23 \\ char b = 123;
...@@ -26,7 +25,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -26,7 +25,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
26 \\ const unsigned d = 440;25 \\ const unsigned d = 440;
27 \\}26 \\}
28 , &[_][]const u8{27 , &[_][]const u8{
29 \\pub fn foo() void {28 \\pub export fn foo() void {
30 \\ var a: c_int = undefined;29 \\ var a: c_int = undefined;
31 \\ var b: u8 = @as(u8, 123);30 \\ var b: u8 = @as(u8, 123);
32 \\ const c: c_int = undefined;31 \\ const c: c_int = undefined;
...@@ -34,7 +33,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -34,7 +33,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
34 \\}33 \\}
35 });34 });
3635
37 cases.add_both("ignore result, explicit function arguments",36 cases.addC_both("ignore result, explicit function arguments",
38 \\void foo(void) {37 \\void foo(void) {
39 \\ int a;38 \\ int a;
40 \\ 1;39 \\ 1;
...@@ -44,7 +43,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -44,7 +43,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
44 \\ a = 1;43 \\ a = 1;
45 \\}44 \\}
46 , &[_][]const u8{45 , &[_][]const u8{
47 \\pub fn foo() void {46 \\pub export fn foo() void {
48 \\ var a: c_int = undefined;47 \\ var a: c_int = undefined;
49 \\ _ = 1;48 \\ _ = 1;
50 \\ _ = "hey";49 \\ _ = "hey";
...@@ -54,42 +53,139 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -54,42 +53,139 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
54 \\}53 \\}
55 });54 });
5655
56 cases.addC_both("variables",
57 \\extern int extern_var;
58 \\static const int int_var = 13;
59 , &[_][]const u8{
60 \\pub extern var extern_var: c_int;
61 ,
62 \\pub const int_var: c_int = 13;
63 });
64
65 cases.add_both("const ptr initializer",
66 \\static const char *v0 = "0.0.0";
67 , &[_][]const u8{
68 \\pub var v0: [*c]const u8 = "0.0.0";
69 });
70
71 cases.addC_both("static incomplete array inside function",
72 \\void foo(void) {
73 \\ static const char v2[] = "2.2.2";
74 \\}
75 , &[_][]const u8{
76 \\pub export fn foo() void {
77 \\ const v2: [*c]const u8 = "2.2.2";
78 \\}
79 });
80
81 cases.addC_both("simple function definition",
82 \\void foo(void) {}
83 \\static void bar(void) {}
84 , &[_][]const u8{
85 \\pub export fn foo() void {}
86 \\pub fn bar() void {}
87 });
88
89 cases.add_both("typedef void",
90 \\typedef void Foo;
91 \\Foo fun(Foo *a);
92 , &[_][]const u8{
93 \\pub const Foo = c_void;
94 ,
95 \\pub extern fn fun(a: ?*Foo) Foo;
96 });
97
98 cases.add_both("duplicate typedef",
99 \\typedef long foo;
100 \\typedef int bar;
101 \\typedef long foo;
102 \\typedef int baz;
103 , &[_][]const u8{
104 \\pub const foo = c_long;
105 \\pub const bar = c_int;
106 \\pub const baz = c_int;
107 });
108
109 cases.addC_both("casting pointers to ints and ints to pointers",
110 \\void foo(void);
111 \\void bar(void) {
112 \\ void *func_ptr = foo;
113 \\ void (*typed_func_ptr)(void) = (void (*)(void)) (unsigned long) func_ptr;
114 \\}
115 , &[_][]const u8{
116 \\pub extern fn foo() void;
117 \\pub export fn bar() void {
118 \\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo);
119 \\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, @as(c_ulong, @ptrToInt(func_ptr)));
120 \\}
121 });
122
123 cases.add_both("noreturn attribute",
124 \\void foo(void) __attribute__((noreturn));
125 , &[_][]const u8{
126 \\pub extern fn foo() noreturn;
127 });
128
129 cases.addC_both("add, sub, mul, div, rem",
130 \\int s(int a, int b) {
131 \\ int c;
132 \\ c = a + b;
133 \\ c = a - b;
134 \\ c = a * b;
135 \\ c = a / b;
136 \\ c = a % b;
137 \\}
138 \\unsigned u(unsigned a, unsigned b) {
139 \\ unsigned c;
140 \\ c = a + b;
141 \\ c = a - b;
142 \\ c = a * b;
143 \\ c = a / b;
144 \\ c = a % b;
145 \\}
146 , &[_][]const u8{
147 \\pub export fn s(a: c_int, b: c_int) c_int {
148 \\ var c: c_int = undefined;
149 \\ c = (a + b);
150 \\ c = (a - b);
151 \\ c = (a * b);
152 \\ c = @divTrunc(a, b);
153 \\ c = @rem(a, b);
154 \\}
155 \\pub export fn u(a: c_uint, b: c_uint) c_uint {
156 \\ var c: c_uint = undefined;
157 \\ c = (a +% b);
158 \\ c = (a -% b);
159 \\ c = (a *% b);
160 \\ c = (a / b);
161 \\ c = (a % b);
162 \\}
163 });
164
57 /////////////// Cases that pass for only stage2 ////////////////165 /////////////// Cases that pass for only stage2 ////////////////
58 // TODO: restore these tests after removing "import mode" concept166
59 // https://github.com/ziglang/zig/issues/2780167 cases.add_2("Parameterless function prototypes",
60
61 // cases.add_2("Parameterless function prototypes",
62 // \\void a() {}
63 // \\void b(void) {}
64 // \\void c();
65 // \\void d(void);
66 // ,
67 // \\pub export fn a() void {}
68 // \\pub export fn b() void {}
69 // \\pub extern fn c(...) void;
70 // \\pub extern fn d() void;
71 // );
72
73 // cases.add_2("simple function definition",
74 // \\void foo(void) {}
75 // \\static void bar(void) {}
76 // ,
77 // \\pub export fn foo() void {}
78 // \\pub extern fn bar() void {}
79 // );
80
81 cases.add_2("parameterless function prototypes",
82 \\void a() {}168 \\void a() {}
83 \\void b(void) {}169 \\void b(void) {}
84 \\void c();170 \\void c();
85 \\void d(void);171 \\void d(void);
86 , &[_][]const u8{172 , &[_][]const u8{
87 \\pub fn a(...) void {}173 \\pub export fn a() void {}
88 \\pub fn b() void {}174 \\pub export fn b() void {}
89 \\pub extern fn c(...) void;175 \\pub extern fn c(...) void;
90 \\pub extern fn d() void;176 \\pub extern fn d() void;
91 });177 });
92178
179 cases.add_2("variable declarations",
180 \\extern char arr0[] = "hello";
181 \\static char arr1[] = "hello";
182 \\char arr2[] = "hello";
183 , &[_][]const u8{
184 \\pub extern var arr0: [*c]u8 = "hello";
185 \\pub var arr1: [*c]u8 = "hello";
186 \\pub export var arr2: [*c]u8 = "hello";
187 });
188
93 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////189 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
94190
95 cases.add("typedef of function in struct field",191 cases.add("typedef of function in struct field",
...@@ -120,34 +216,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -120,34 +216,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
120 \\};216 \\};
121 });217 });
122218
123 cases.add_both("simple function definition",
124 \\void foo(void) {}
125 \\static void bar(void) {}
126 , &[_][]const u8{
127 \\pub fn foo() void {}
128 \\pub fn bar() void {}
129 });
130
131 cases.add("macro with left shift",219 cases.add("macro with left shift",
132 \\#define REDISMODULE_READ (1<<0)220 \\#define REDISMODULE_READ (1<<0)
133 , &[_][]const u8{221 , &[_][]const u8{
134 \\pub const REDISMODULE_READ = 1 << 0;222 \\pub const REDISMODULE_READ = 1 << 0;
135 });223 });
136224
137 cases.add_both("casting pointers to ints and ints to pointers",
138 \\void foo(void);
139 \\void bar(void) {
140 \\ void *func_ptr = foo;
141 \\ void (*typed_func_ptr)(void) = (void (*)(void)) (unsigned long) func_ptr;
142 \\}
143 , &[_][]const u8{
144 \\pub extern fn foo() void;
145 \\pub fn bar() void {
146 \\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo);
147 \\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, @as(c_ulong, @ptrToInt(func_ptr)));
148 \\}
149 });
150
151 if (builtin.os != builtin.Os.windows) {225 if (builtin.os != builtin.Os.windows) {
152 // Windows treats this as an enum with type c_int226 // Windows treats this as an enum with type c_int
153 cases.add("big negative enum init values when C ABI supports long long enums",227 cases.add("big negative enum init values when C ABI supports long long enums",
...@@ -320,12 +394,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -320,12 +394,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
320 \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64) void;394 \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64) void;
321 });395 });
322396
323 cases.add_both("noreturn attribute",
324 \\void foo(void) __attribute__((noreturn));
325 , &[_][]const u8{
326 \\pub extern fn foo() noreturn;
327 });
328
329 cases.addC("simple function",397 cases.addC("simple function",
330 \\int abs(int a) {398 \\int abs(int a) {
331 \\ return a < 0 ? -a : a;399 \\ return a < 0 ? -a : a;
...@@ -482,15 +550,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -482,15 +550,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
482 \\pub const THING2 = THING1;550 \\pub const THING2 = THING1;
483 });551 });
484552
485 cases.add("variables",
486 \\extern int extern_var;
487 \\static const int int_var = 13;
488 , &[_][]const u8{
489 \\pub extern var extern_var: c_int;
490 ,
491 \\pub const int_var: c_int = 13;
492 });
493
494 cases.add("circular struct definitions",553 cases.add("circular struct definitions",
495 \\struct Bar;554 \\struct Bar;
496 \\555 \\
...@@ -511,15 +570,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -511,15 +570,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
511 \\};570 \\};
512 });571 });
513572
514 cases.add("typedef void",
515 \\typedef void Foo;
516 \\Foo fun(Foo *a);
517 , &[_][]const u8{
518 \\pub const Foo = c_void;
519 ,
520 \\pub extern fn fun(a: ?*Foo) Foo;
521 });
522
523 cases.add("generate inline func for #define global extern fn",573 cases.add("generate inline func for #define global extern fn",
524 \\extern void (*fn_ptr)(void);574 \\extern void (*fn_ptr)(void);
525 \\#define foo fn_ptr575 \\#define foo fn_ptr
...@@ -719,42 +769,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -719,42 +769,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
719 \\}769 \\}
720 });770 });
721771
722 cases.addC_both("add, sub, mul, div, rem",
723 \\int s(int a, int b) {
724 \\ int c;
725 \\ c = a + b;
726 \\ c = a - b;
727 \\ c = a * b;
728 \\ c = a / b;
729 \\ c = a % b;
730 \\}
731 \\unsigned u(unsigned a, unsigned b) {
732 \\ unsigned c;
733 \\ c = a + b;
734 \\ c = a - b;
735 \\ c = a * b;
736 \\ c = a / b;
737 \\ c = a % b;
738 \\}
739 , &[_][]const u8{
740 \\pub export fn s(a: c_int, b: c_int) c_int {
741 \\ var c: c_int = undefined;
742 \\ c = (a + b);
743 \\ c = (a - b);
744 \\ c = (a * b);
745 \\ c = @divTrunc(a, b);
746 \\ c = @rem(a, b);
747 \\}
748 \\pub export fn u(a: c_uint, b: c_uint) c_uint {
749 \\ var c: c_uint = undefined;
750 \\ c = (a +% b);
751 \\ c = (a -% b);
752 \\ c = (a *% b);
753 \\ c = (a / b);
754 \\ c = (a % b);
755 \\}
756 });
757
758 cases.addC("bitwise binary operators",772 cases.addC("bitwise binary operators",
759 \\int max(int a, int b) {773 \\int max(int a, int b) {
760 \\ return (a & b) ^ (a | b);774 \\ return (a & b) ^ (a | b);
...@@ -1147,17 +1161,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1147,17 +1161,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1147 \\}1161 \\}
1148 });1162 });
11491163
1150 cases.addC("duplicate typedef",
1151 \\typedef long foo;
1152 \\typedef int bar;
1153 \\typedef long foo;
1154 \\typedef int baz;
1155 , &[_][]const u8{
1156 \\pub const foo = c_long;
1157 \\pub const bar = c_int;
1158 \\pub const baz = c_int;
1159 });
1160
1161 cases.addC("post increment/decrement",1164 cases.addC("post increment/decrement",
1162 \\void foo(void) {1165 \\void foo(void) {
1163 \\ int i = 0;1166 \\ int i = 0;
...@@ -1520,22 +1523,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1520,22 +1523,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1520 \\}1523 \\}
1521 });1524 });
15221525
1523 cases.add("const ptr initializer",
1524 \\static const char *v0 = "0.0.0";
1525 , &[_][]const u8{
1526 \\pub var v0: [*c]const u8 = "0.0.0";
1527 });
1528
1529 cases.add("static incomplete array inside function",
1530 \\void foo(void) {
1531 \\ static const char v2[] = "2.2.2";
1532 \\}
1533 , &[_][]const u8{
1534 \\pub fn foo() void {
1535 \\ const v2: [*c]const u8 = "2.2.2";
1536 \\}
1537 });
1538
1539 cases.add("macro pointer cast",1526 cases.add("macro pointer cast",
1540 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)1527 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
1541 , &[_][]const u8{1528 , &[_][]const u8{