authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-16 00:01:31-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-16 00:01:31-04:00
log5345044edfe6ce5d8c13d3a0e86abaad999f853b
tree508ded38a4b9e70b21052eb0d0b83bbad3d04b9e
parent3f4abe97bdbe666dbb3532c14a97e414aae4caca
parent776423bbf72312e756eb661b616f0e1bb805f568
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'hryx-translate-c-userland'


7 files changed, 1224 insertions(+), 45 deletions(-)

src-self-hosted/clang.zig+78-1
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1pub const struct_ZigClangAPValue = @OpaqueType();1const builtin = @import("builtin");
2
2pub const struct_ZigClangAPSInt = @OpaqueType();3pub const struct_ZigClangAPSInt = @OpaqueType();
3pub const struct_ZigClangAPFloat = @OpaqueType();4pub const struct_ZigClangAPFloat = @OpaqueType();
4pub const struct_ZigClangASTContext = @OpaqueType();5pub const struct_ZigClangASTContext = @OpaqueType();
...@@ -723,6 +724,7 @@ pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: str...@@ -723,6 +724,7 @@ pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: str
723pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) ?*const struct_ZigClangTypedefNameDecl;724pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) ?*const struct_ZigClangTypedefNameDecl;
724pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(self: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType;725pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(self: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType;
725pub extern fn ZigClangQualType_getCanonicalType(self: struct_ZigClangQualType) struct_ZigClangQualType;726pub extern fn ZigClangQualType_getCanonicalType(self: struct_ZigClangQualType) struct_ZigClangQualType;
727pub extern fn ZigClangQualType_getTypeClass(self: struct_ZigClangQualType) ZigClangTypeClass;
726pub extern fn ZigClangQualType_getTypePtr(self: struct_ZigClangQualType) *const struct_ZigClangType;728pub extern fn ZigClangQualType_getTypePtr(self: struct_ZigClangQualType) *const struct_ZigClangType;
727pub extern fn ZigClangQualType_addConst(self: [*c]struct_ZigClangQualType) void;729pub extern fn ZigClangQualType_addConst(self: [*c]struct_ZigClangQualType) void;
728pub extern fn ZigClangQualType_eq(self: struct_ZigClangQualType, arg1: struct_ZigClangQualType) bool;730pub extern fn ZigClangQualType_eq(self: struct_ZigClangQualType, arg1: struct_ZigClangQualType) bool;
...@@ -730,6 +732,7 @@ pub extern fn ZigClangQualType_isConstQualified(self: struct_ZigClangQualType) b...@@ -730,6 +732,7 @@ pub extern fn ZigClangQualType_isConstQualified(self: struct_ZigClangQualType) b
730pub extern fn ZigClangQualType_isVolatileQualified(self: struct_ZigClangQualType) bool;732pub extern fn ZigClangQualType_isVolatileQualified(self: struct_ZigClangQualType) bool;
731pub extern fn ZigClangQualType_isRestrictQualified(self: struct_ZigClangQualType) bool;733pub extern fn ZigClangQualType_isRestrictQualified(self: struct_ZigClangQualType) bool;
732pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass;734pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass;
735pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) struct_ZigClangQualType;
733pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;736pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
734pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*]const u8;737pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*]const u8;
735pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;738pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;
...@@ -894,3 +897,77 @@ pub const ZigClangCompoundStmt_const_body_iterator = [*c]const *struct_ZigClangS...@@ -894,3 +897,77 @@ pub const ZigClangCompoundStmt_const_body_iterator = [*c]const *struct_ZigClangS
894897
895pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;898pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
896pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;899pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
900
901pub const ZigClangDeclStmt_const_decl_iterator = [*c]const *struct_ZigClangDecl;
902
903pub extern fn ZigClangDeclStmt_decl_begin(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator;
904pub extern fn ZigClangDeclStmt_decl_end(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator;
905
906pub extern fn ZigClangVarDecl_getType(self: ?*const struct_ZigClangVarDecl) struct_ZigClangQualType;
907pub extern fn ZigClangVarDecl_getInit(*const ZigClangVarDecl) ?*const ZigClangExpr;
908pub extern fn ZigClangVarDecl_getTLSKind(self: ?*const struct_ZigClangVarDecl) ZigClangVarDecl_TLSKind;
909pub const ZigClangVarDecl_TLSKind = extern enum {
910 None,
911 Static,
912 Dynamic,
913};
914
915pub extern fn ZigClangImplicitCastExpr_getBeginLoc(*const ZigClangImplicitCastExpr) ZigClangSourceLocation;
916pub extern fn ZigClangImplicitCastExpr_getCastKind(*const ZigClangImplicitCastExpr) ZigClangCK;
917pub extern fn ZigClangImplicitCastExpr_getSubExpr(*const ZigClangImplicitCastExpr) *const ZigClangExpr;
918
919pub extern fn ZigClangArrayType_getElementType(*const ZigClangArrayType) ZigClangQualType;
920
921pub extern fn ZigClangDeclRefExpr_getDecl(*const ZigClangDeclRefExpr) *const ZigClangValueDecl;
922
923pub extern fn ZigClangParenType_getInnerType(*const ZigClangParenType) ZigClangQualType;
924
925pub extern fn ZigClangElaboratedType_getNamedType(*const ZigClangElaboratedType) ZigClangQualType;
926
927pub extern fn ZigClangAttributedType_getEquivalentType(*const ZigClangAttributedType) ZigClangQualType;
928
929pub extern fn ZigClangCStyleCastExpr_getBeginLoc(*const ZigClangCStyleCastExpr) ZigClangSourceLocation;
930pub extern fn ZigClangCStyleCastExpr_getSubExpr(*const ZigClangCStyleCastExpr) *const ZigClangExpr;
931pub extern fn ZigClangCStyleCastExpr_getType(*const ZigClangCStyleCastExpr) ZigClangQualType;
932
933pub const ZigClangExprEvalResult = struct_ZigClangExprEvalResult;
934pub const struct_ZigClangExprEvalResult = extern struct {
935 HasSideEffects: bool,
936 HasUndefinedBehavior: bool,
937 SmallVectorImpl: ?*c_void,
938 Val: ZigClangAPValue,
939};
940
941pub const struct_ZigClangAPValue = extern struct {
942 Kind: ZigClangAPValue_ValueKind,
943 Data: if (builtin.os == .windows) [52]u8 else [68]u8,
944};
945
946pub const ZigClangAPValue_ValueKind = extern enum {
947 ZigClangAPValue_ValueKind_Uninitialized,
948 ZigClangAPValue_ValueKind_Int,
949 ZigClangAPValue_ValueKind_Float,
950 ZigClangAPValue_ValueKind_ComplexInt,
951 ZigClangAPValue_ValueKind_ComplexFloat,
952 ZigClangAPValue_ValueKind_LValue,
953 ZigClangAPValue_ValueKind_Vector,
954 ZigClangAPValue_ValueKind_Array,
955 ZigClangAPValue_ValueKind_Struct,
956 ZigClangAPValue_ValueKind_Union,
957 ZigClangAPValue_ValueKind_MemberPointer,
958 ZigClangAPValue_ValueKind_AddrLabelDiff,
959};
960
961pub extern fn ZigClangIntegerLiteral_EvaluateAsInt(*const ZigClangIntegerLiteral, *ZigClangExprEvalResult, *const ZigClangASTContext) bool;
962pub extern fn ZigClangIntegerLiteral_getBeginLoc(*const ZigClangIntegerLiteral) ZigClangSourceLocation;
963
964pub extern fn ZigClangReturnStmt_getRetValue(*const ZigClangReturnStmt) ?*const ZigClangExpr;
965
966pub extern fn ZigClangBinaryOperator_getOpcode(*const ZigClangBinaryOperator) ZigClangBO;
967pub extern fn ZigClangBinaryOperator_getBeginLoc(*const ZigClangBinaryOperator) ZigClangSourceLocation;
968pub extern fn ZigClangBinaryOperator_getLHS(*const ZigClangBinaryOperator) *const ZigClangExpr;
969pub extern fn ZigClangBinaryOperator_getRHS(*const ZigClangBinaryOperator) *const ZigClangExpr;
970pub extern fn ZigClangBinaryOperator_getType(*const ZigClangBinaryOperator) ZigClangQualType;
971
972pub extern fn ZigClangStringLiteral_getKind(*const ZigClangStringLiteral) ZigClangStringLiteral_StringKind;
973pub extern fn ZigClangStringLiteral_getString_bytes_begin_size(*const ZigClangStringLiteral, *usize) [*c]const u8;
src-self-hosted/translate_c.zig+821-14
...@@ -20,7 +20,7 @@ pub const ClangErrMsg = Stage2ErrorMsg;...@@ -20,7 +20,7 @@ pub const ClangErrMsg = Stage2ErrorMsg;
2020
21pub const Error = error{OutOfMemory};21pub const Error = error{OutOfMemory};
22const TypeError = Error || error{UnsupportedType};22const TypeError = Error || error{UnsupportedType};
23const TransError = Error || error{UnsupportedTranslation};23const TransError = TypeError || error{UnsupportedTranslation};
2424
25const DeclTable = std.HashMap(usize, void, addrHash, addrEql);25const DeclTable = std.HashMap(usize, void, addrHash, addrEql);
2626
...@@ -107,6 +107,8 @@ const Context = struct {...@@ -107,6 +107,8 @@ const Context = struct {
107 decl_table: DeclTable,107 decl_table: DeclTable,
108 global_scope: *Scope.Root,108 global_scope: *Scope.Root,
109 mode: Mode,109 mode: Mode,
110 ptr_params: std.BufSet,
111 clang_context: *ZigClangASTContext,
110112
111 fn a(c: *Context) *std.mem.Allocator {113 fn a(c: *Context) *std.mem.Allocator {
112 return &c.tree.arena_allocator.allocator;114 return &c.tree.arena_allocator.allocator;
...@@ -183,6 +185,8 @@ pub fn translate(...@@ -183,6 +185,8 @@ pub fn translate(
183 .decl_table = DeclTable.init(arena),185 .decl_table = DeclTable.init(arena),
184 .global_scope = try arena.create(Scope.Root),186 .global_scope = try arena.create(Scope.Root),
185 .mode = mode,187 .mode = mode,
188 .ptr_params = std.BufSet.init(arena),
189 .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
186 };190 };
187 context.global_scope.* = Scope.Root{191 context.global_scope.* = Scope.Root{
188 .base = Scope{192 .base = Scope{
...@@ -195,7 +199,7 @@ pub fn translate(...@@ -195,7 +199,7 @@ pub fn translate(
195 return context.err;199 return context.err;
196 }200 }
197201
198 _ = try appendToken(&context, .Eof, "");202 tree.root_node.eof_token = try appendToken(&context, .Eof, "");
199 tree.source = source_buffer.toOwnedSlice();203 tree.source = source_buffer.toOwnedSlice();
200 if (false) {204 if (false) {
201 std.debug.warn("debug source:\n{}\n==EOF==\ntokens:\n", tree.source);205 std.debug.warn("debug source:\n{}\n==EOF==\ntokens:\n", tree.source);
...@@ -257,7 +261,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {...@@ -257,7 +261,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
257 .storage_class = storage_class,261 .storage_class = storage_class,
258 .scope = &scope,262 .scope = &scope,
259 .is_export = switch (storage_class) {263 .is_export = switch (storage_class) {
260 .None => has_body,264 .None => has_body and c.mode != .import,
261 .Extern, .Static => false,265 .Extern, .Static => false,
262 .PrivateExtern => return failDecl(c, fn_decl_loc, fn_name, "unsupported storage class: private extern"),266 .PrivateExtern => return failDecl(c, fn_decl_loc, fn_name, "unsupported storage class: private extern"),
263 .Auto => unreachable, // Not legal on functions267 .Auto => unreachable, // Not legal on functions
...@@ -267,7 +271,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {...@@ -267,7 +271,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
267 const proto_node = switch (ZigClangType_getTypeClass(fn_type)) {271 const proto_node = switch (ZigClangType_getTypeClass(fn_type)) {
268 .FunctionProto => blk: {272 .FunctionProto => blk: {
269 const fn_proto_type = @ptrCast(*const ZigClangFunctionProtoType, fn_type);273 const fn_proto_type = @ptrCast(*const ZigClangFunctionProtoType, fn_type);
270 break :blk transFnProto(rp, fn_proto_type, fn_decl_loc, decl_ctx) catch |err| switch (err) {274 break :blk transFnProto(rp, fn_proto_type, fn_decl_loc, decl_ctx, true) catch |err| switch (err) {
271 error.UnsupportedType => {275 error.UnsupportedType => {
272 return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function");276 return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function");
273 },277 },
...@@ -276,7 +280,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {...@@ -276,7 +280,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
276 },280 },
277 .FunctionNoProto => blk: {281 .FunctionNoProto => blk: {
278 const fn_no_proto_type = @ptrCast(*const ZigClangFunctionType, fn_type);282 const fn_no_proto_type = @ptrCast(*const ZigClangFunctionType, fn_type);
279 break :blk transFnNoProto(rp, fn_no_proto_type, fn_decl_loc, decl_ctx) catch |err| switch (err) {283 break :blk transFnNoProto(rp, fn_no_proto_type, fn_decl_loc, decl_ctx, true) catch |err| switch (err) {
280 error.UnsupportedType => {284 error.UnsupportedType => {
281 return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function");285 return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function");
282 },286 },
...@@ -295,7 +299,9 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {...@@ -295,7 +299,9 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
295 const body_stmt = ZigClangFunctionDecl_getBody(fn_decl);299 const body_stmt = ZigClangFunctionDecl_getBody(fn_decl);
296 const result = transStmt(rp, scope, body_stmt, .unused, .r_value) catch |err| switch (err) {300 const result = transStmt(rp, scope, body_stmt, .unused, .r_value) catch |err| switch (err) {
297 error.OutOfMemory => |e| return e,301 error.OutOfMemory => |e| return e,
298 error.UnsupportedTranslation => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function"),302 error.UnsupportedTranslation,
303 error.UnsupportedType,
304 => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function"),
299 };305 };
300 assert(result.node.id == ast.Node.Id.Block);306 assert(result.node.id == ast.Node.Id.Block);
301 proto_node.body_node = result.node;307 proto_node.body_node = result.node;
...@@ -322,7 +328,15 @@ fn transStmt(...@@ -322,7 +328,15 @@ fn transStmt(
322) !TransResult {328) !TransResult {
323 const sc = ZigClangStmt_getStmtClass(stmt);329 const sc = ZigClangStmt_getStmtClass(stmt);
324 switch (sc) {330 switch (sc) {
331 .BinaryOperatorClass => return transBinaryOperator(rp, scope, @ptrCast(*const ZigClangBinaryOperator, stmt), result_used),
325 .CompoundStmtClass => return transCompoundStmt(rp, scope, @ptrCast(*const ZigClangCompoundStmt, stmt)),332 .CompoundStmtClass => return transCompoundStmt(rp, scope, @ptrCast(*const ZigClangCompoundStmt, stmt)),
333 .CStyleCastExprClass => return transCStyleCastExprClass(rp, scope, @ptrCast(*const ZigClangCStyleCastExpr, stmt), result_used, lrvalue),
334 .DeclStmtClass => return transDeclStmt(rp, scope, @ptrCast(*const ZigClangDeclStmt, stmt)),
335 .DeclRefExprClass => return transDeclRefExpr(rp, scope, @ptrCast(*const ZigClangDeclRefExpr, stmt), lrvalue),
336 .ImplicitCastExprClass => return transImplicitCastExpr(rp, scope, @ptrCast(*const ZigClangImplicitCastExpr, stmt), result_used),
337 .IntegerLiteralClass => return transIntegerLiteral(rp, scope, @ptrCast(*const ZigClangIntegerLiteral, stmt), result_used),
338 .ReturnStmtClass => return transReturnStmt(rp, scope, @ptrCast(*const ZigClangReturnStmt, stmt)),
339 .StringLiteralClass => return transStringLiteral(rp, scope, @ptrCast(*const ZigClangStringLiteral, stmt), result_used),
326 else => {340 else => {
327 return revertAndWarn(341 return revertAndWarn(
328 rp,342 rp,
...@@ -335,6 +349,87 @@ fn transStmt(...@@ -335,6 +349,87 @@ fn transStmt(
335 }349 }
336}350}
337351
352fn transBinaryOperator(
353 rp: RestorePoint,
354 scope: *Scope,
355 stmt: *const ZigClangBinaryOperator,
356 result_used: ResultUsed,
357) TransError!TransResult {
358 const op = ZigClangBinaryOperator_getOpcode(stmt);
359 const qt = ZigClangBinaryOperator_getType(stmt);
360 switch (op) {
361 .PtrMemD, .PtrMemI, .Cmp => return revertAndWarn(
362 rp,
363 error.UnsupportedTranslation,
364 ZigClangBinaryOperator_getBeginLoc(stmt),
365 "TODO: handle more C binary operators: {}",
366 op,
367 ),
368 .Assign => return TransResult{
369 .node = &(try transCreateNodeAssign(rp, scope, result_used, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt))).base,
370 .child_scope = scope,
371 .node_scope = scope,
372 },
373 .Add => {
374 const node = if (cIsUnsignedInteger(qt))
375 try transCreateNodeInfixOp(rp, scope, stmt, .AddWrap, .PlusPercent, "+%", true)
376 else
377 try transCreateNodeInfixOp(rp, scope, stmt, .Add, .Plus, "+", true);
378 return maybeSuppressResult(rp, scope, result_used, TransResult{
379 .node = node,
380 .child_scope = scope,
381 .node_scope = scope,
382 });
383 },
384 .Sub => {
385 const node = if (cIsUnsignedInteger(qt))
386 try transCreateNodeInfixOp(rp, scope, stmt, .SubWrap, .MinusPercent, "-%", true)
387 else
388 try transCreateNodeInfixOp(rp, scope, stmt, .Sub, .Minus, "-", true);
389 return maybeSuppressResult(rp, scope, result_used, TransResult{
390 .node = node,
391 .child_scope = scope,
392 .node_scope = scope,
393 });
394 },
395 .Mul,
396 .Div,
397 .Rem,
398 .Shl,
399 .Shr,
400 .LT,
401 .GT,
402 .LE,
403 .GE,
404 .EQ,
405 .NE,
406 .And,
407 .Xor,
408 .Or,
409 .LAnd,
410 .LOr,
411 .Comma,
412 => return revertAndWarn(
413 rp,
414 error.UnsupportedTranslation,
415 ZigClangBinaryOperator_getBeginLoc(stmt),
416 "TODO: handle more C binary operators: {}",
417 op,
418 ),
419 .MulAssign,
420 .DivAssign,
421 .RemAssign,
422 .AddAssign,
423 .SubAssign,
424 .ShlAssign,
425 .ShrAssign,
426 .AndAssign,
427 .XorAssign,
428 .OrAssign,
429 => unreachable,
430 }
431}
432
338fn transCompoundStmtInline(433fn transCompoundStmtInline(
339 rp: RestorePoint,434 rp: RestorePoint,
340 parent_scope: *Scope,435 parent_scope: *Scope,
...@@ -345,9 +440,10 @@ fn transCompoundStmtInline(...@@ -345,9 +440,10 @@ fn transCompoundStmtInline(
345 const end_it = ZigClangCompoundStmt_body_end(stmt);440 const end_it = ZigClangCompoundStmt_body_end(stmt);
346 var scope = parent_scope;441 var scope = parent_scope;
347 while (it != end_it) : (it += 1) {442 while (it != end_it) : (it += 1) {
348 const result = try transStmt(rp, scope, it.*, .unused, .r_value);443 const result = try transStmt(rp, parent_scope, it.*, .unused, .r_value);
349 scope = result.child_scope;444 scope = result.child_scope;
350 try block_node.statements.push(result.node);445 if (result.node != &block_node.base)
446 try block_node.statements.push(result.node);
351 }447 }
352 return TransResult{448 return TransResult{
353 .node = &block_node.base,449 .node = &block_node.base,
...@@ -368,6 +464,427 @@ fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompo...@@ -368,6 +464,427 @@ fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompo
368 };464 };
369}465}
370466
467fn transCStyleCastExprClass(
468 rp: RestorePoint,
469 scope: *Scope,
470 stmt: *const ZigClangCStyleCastExpr,
471 result_used: ResultUsed,
472 lrvalue: LRValue,
473) !TransResult {
474 const sub_expr = ZigClangCStyleCastExpr_getSubExpr(stmt);
475 const cast_node = (try transCCast(
476 rp,
477 scope,
478 ZigClangCStyleCastExpr_getBeginLoc(stmt),
479 ZigClangCStyleCastExpr_getType(stmt),
480 ZigClangExpr_getType(sub_expr),
481 (try transExpr(rp, scope, sub_expr, .used, lrvalue)).node,
482 ));
483 const cast_res = TransResult{
484 .node = cast_node,
485 .child_scope = scope,
486 .node_scope = scope,
487 };
488 return maybeSuppressResult(rp, scope, result_used, cast_res);
489}
490
491fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDeclStmt) !TransResult {
492 const c = rp.c;
493 const block_scope = findBlockScope(parent_scope);
494 var scope = parent_scope;
495
496 var it = ZigClangDeclStmt_decl_begin(stmt);
497 const end_it = ZigClangDeclStmt_decl_end(stmt);
498 while (it != end_it) : (it += 1) {
499 switch (ZigClangDecl_getKind(it.*)) {
500 .Var => {
501 const var_decl = @ptrCast(*const ZigClangVarDecl, it.*);
502
503 const thread_local_token = if (ZigClangVarDecl_getTLSKind(var_decl) == .None)
504 null
505 else
506 try appendToken(c, .Keyword_threadlocal, "threadlocal");
507 const qual_type = ZigClangVarDecl_getType(var_decl);
508 const mut_token = if (ZigClangQualType_isConstQualified(qual_type))
509 try appendToken(c, .Keyword_const, "const")
510 else
511 try appendToken(c, .Keyword_var, "var");
512 const c_name = try c.str(ZigClangDecl_getName_bytes_begin(
513 @ptrCast(*const ZigClangDecl, var_decl),
514 ));
515 const name_token = try appendToken(c, .Identifier, c_name);
516
517 const var_scope = try c.a().create(Scope.Var);
518 var_scope.* = Scope.Var{
519 .base = Scope{ .id = .Var, .parent = scope },
520 .c_name = c_name,
521 .zig_name = c_name, // TODO: getWantedName
522 };
523 scope = &var_scope.base;
524
525 const colon_token = try appendToken(c, .Colon, ":");
526 const loc = ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt));
527 const type_node = try transQualType(rp, qual_type, loc);
528
529 const eq_token = try appendToken(c, .Equal, "=");
530 const init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr|
531 (try transExpr(rp, scope, expr, .used, .r_value)).node
532 else blk: {
533 const undefined_token = try appendToken(c, .Keyword_undefined, "undefined");
534 const undefined_node = try rp.c.a().create(ast.Node.UndefinedLiteral);
535 undefined_node.* = ast.Node.UndefinedLiteral{
536 .base = ast.Node{ .id = .UndefinedLiteral },
537 .token = undefined_token,
538 };
539 break :blk &undefined_node.base;
540 };
541 const semicolon_token = try appendToken(c, .Semicolon, ";");
542
543 const node = try c.a().create(ast.Node.VarDecl);
544 node.* = ast.Node.VarDecl{
545 .base = ast.Node{ .id = .VarDecl },
546 .doc_comments = null,
547 .visib_token = null,
548 .thread_local_token = thread_local_token,
549 .name_token = name_token,
550 .eq_token = eq_token,
551 .mut_token = mut_token,
552 .comptime_token = null,
553 .extern_export_token = null,
554 .lib_name = null,
555 .type_node = type_node,
556 .align_node = null, // TODO ?*Node,
557 .section_node = null,
558 .init_node = init_node,
559 .semicolon_token = semicolon_token,
560 };
561 try block_scope.block_node.statements.push(&node.base);
562 },
563
564 else => |kind| return revertAndWarn(
565 rp,
566 error.UnsupportedTranslation,
567 ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt)),
568 "TODO implement translation of DeclStmt kind {}",
569 @tagName(kind),
570 ),
571 }
572 }
573
574 return TransResult{
575 .node = &block_scope.block_node.base,
576 .node_scope = scope,
577 .child_scope = scope,
578 };
579}
580
581fn transDeclRefExpr(
582 rp: RestorePoint,
583 scope: *Scope,
584 expr: *const ZigClangDeclRefExpr,
585 lrvalue: LRValue,
586) !TransResult {
587 const value_decl = ZigClangDeclRefExpr_getDecl(expr);
588 const c_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, value_decl)));
589 const zig_name = transLookupZigIdentifier(scope, c_name);
590 if (lrvalue == .l_value) try rp.c.ptr_params.put(zig_name);
591 const node = try appendIdentifier(rp.c, zig_name);
592 return TransResult{
593 .node = node,
594 .node_scope = scope,
595 .child_scope = scope,
596 };
597}
598
599fn transImplicitCastExpr(
600 rp: RestorePoint,
601 scope: *Scope,
602 expr: *const ZigClangImplicitCastExpr,
603 result_used: ResultUsed,
604) !TransResult {
605 const c = rp.c;
606 const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr);
607 const sub_expr_node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value);
608 switch (ZigClangImplicitCastExpr_getCastKind(expr)) {
609 .BitCast => {
610 const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr));
611 const src_type = getExprQualType(c, sub_expr);
612 return TransResult{
613 .node = try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node.node),
614 .node_scope = scope,
615 .child_scope = scope,
616 };
617 },
618 .IntegralCast => {
619 const dest_type = ZigClangExpr_getType(@ptrCast(*const ZigClangExpr, expr));
620 const src_type = ZigClangExpr_getType(sub_expr);
621 return TransResult{
622 .node = try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node.node),
623 .node_scope = scope,
624 .child_scope = scope,
625 };
626 },
627 .FunctionToPointerDecay, .ArrayToPointerDecay => {
628 return maybeSuppressResult(rp, scope, result_used, sub_expr_node);
629 },
630 .LValueToRValue => {
631 return transExpr(rp, scope, sub_expr, .used, .r_value);
632 },
633 else => |kind| return revertAndWarn(
634 rp,
635 error.UnsupportedTranslation,
636 ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, expr)),
637 "TODO implement translation of CastKind {}",
638 @tagName(kind),
639 ),
640 }
641}
642
643fn transIntegerLiteral(
644 rp: RestorePoint,
645 scope: *Scope,
646 expr: *const ZigClangIntegerLiteral,
647 result_used: ResultUsed,
648) !TransResult {
649 var eval_result: ZigClangExprEvalResult = undefined;
650 if (!ZigClangIntegerLiteral_EvaluateAsInt(expr, &eval_result, rp.c.clang_context)) {
651 const loc = ZigClangIntegerLiteral_getBeginLoc(expr);
652 return revertAndWarn(rp, error.UnsupportedTranslation, loc, "invalid integer literal");
653 }
654 const node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val));
655 const res = TransResult{
656 .node = node,
657 .child_scope = scope,
658 .node_scope = scope,
659 };
660 return maybeSuppressResult(rp, scope, result_used, res);
661}
662
663fn transReturnStmt(
664 rp: RestorePoint,
665 scope: *Scope,
666 expr: *const ZigClangReturnStmt,
667) !TransResult {
668 const node = try transCreateNodeReturnExpr(rp.c);
669 if (ZigClangReturnStmt_getRetValue(expr)) |val_expr| {
670 const ret_node = node.cast(ast.Node.ControlFlowExpression).?;
671 ret_node.rhs = (try transExpr(rp, scope, val_expr, .used, .r_value)).node;
672 }
673 _ = try appendToken(rp.c, .Semicolon, ";");
674 return TransResult{
675 .node = node,
676 .child_scope = scope,
677 .node_scope = scope,
678 };
679}
680
681fn transStringLiteral(
682 rp: RestorePoint,
683 scope: *Scope,
684 stmt: *const ZigClangStringLiteral,
685 result_used: ResultUsed,
686) !TransResult {
687 const kind = ZigClangStringLiteral_getKind(stmt);
688 switch (kind) {
689 .Ascii, .UTF8 => {
690 var len: usize = undefined;
691 const bytes_ptr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &len);
692 const str = bytes_ptr[0..len];
693
694 var char_buf: [4]u8 = undefined;
695 len = 0;
696 for (str) |c| len += escapeChar(c, &char_buf).len;
697
698 const buf = try rp.c.a().alloc(u8, len + "c\"\"".len);
699 buf[0] = 'c';
700 buf[1] = '"';
701 writeEscapedString(buf[2..], str);
702 buf[buf.len - 1] = '"';
703
704 const token = try appendToken(rp.c, .StringLiteral, buf);
705 const node = try rp.c.a().create(ast.Node.StringLiteral);
706 node.* = ast.Node.StringLiteral{
707 .base = ast.Node{ .id = .StringLiteral },
708 .token = token,
709 };
710 const res = TransResult{
711 .node = &node.base,
712 .child_scope = scope,
713 .node_scope = scope,
714 };
715 return maybeSuppressResult(rp, scope, result_used, res);
716 },
717 .UTF16, .UTF32, .Wide => return revertAndWarn(
718 rp,
719 error.UnsupportedTranslation,
720 ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt)),
721 "TODO: support string literal kind {}",
722 kind,
723 ),
724 }
725}
726
727fn escapedStringLen(s: []const u8) usize {
728 var len: usize = 0;
729 var char_buf: [4]u8 = undefined;
730 for (s) |c| len += escapeChar(c, &char_buf).len;
731 return len;
732}
733
734fn writeEscapedString(buf: []u8, s: []const u8) void {
735 var char_buf: [4]u8 = undefined;
736 var i: usize = 0;
737 for (s) |c| {
738 const escaped = escapeChar(c, &char_buf);
739 std.mem.copy(u8, buf[i..], escaped);
740 i += escaped.len;
741 }
742}
743
744// Returns either a string literal or a slice of `buf`.
745fn escapeChar(c: u8, char_buf: *[4]u8) []const u8 {
746 // TODO: https://github.com/ziglang/zig/issues/2749
747 const escaped = switch (c) {
748 // Printable ASCII except for ' " \
749 ' ', '!', '#'...'&', '('...'[', ']'...'~' => ([_]u8{c})[0..],
750 '\'', '\"', '\\' => ([_]u8{ '\\', c })[0..],
751 '\n' => return "\\n"[0..],
752 '\r' => return "\\r"[0..],
753 '\t' => return "\\t"[0..],
754 else => return std.fmt.bufPrint(char_buf[0..], "\\x{x:2}", c) catch unreachable,
755 };
756 std.mem.copy(u8, char_buf, escaped);
757 return char_buf[0..escaped.len];
758}
759
760fn transCCast(
761 rp: RestorePoint,
762 scope: *Scope,
763 loc: ZigClangSourceLocation,
764 dst_type: ZigClangQualType,
765 src_type: ZigClangQualType,
766 expr: *ast.Node,
767) !*ast.Node {
768 if (ZigClangType_isVoidType(qualTypeCanon(dst_type))) return expr;
769 if (ZigClangQualType_eq(dst_type, src_type)) return expr;
770 if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type))
771 return transCPtrCast(rp, loc, dst_type, src_type, expr);
772 if (cIsUnsignedInteger(dst_type) and qualTypeIsPtr(src_type)) {
773 const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc));
774 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
775 try builtin_node.params.push(expr);
776 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
777 try cast_node.op.Call.params.push(&builtin_node.base);
778 cast_node.rtoken = try appendToken(rp.c, .RParen, ")");
779 return &cast_node.base;
780 }
781 if (cIsUnsignedInteger(src_type) and qualTypeIsPtr(dst_type)) {
782 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr");
783 try builtin_node.params.push(try transQualType(rp, dst_type, loc));
784 _ = try appendToken(rp.c, .Comma, ",");
785 try builtin_node.params.push(expr);
786 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
787 return &builtin_node.base;
788 }
789 // TODO: maybe widen to increase size
790 // TODO: maybe bitcast to change sign
791 // TODO: maybe truncate to reduce size
792 const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc));
793 try cast_node.op.Call.params.push(expr);
794 cast_node.rtoken = try appendToken(rp.c, .RParen, ")");
795 return &cast_node.base;
796}
797
798fn transExpr(
799 rp: RestorePoint,
800 scope: *Scope,
801 expr: *const ZigClangExpr,
802 used: ResultUsed,
803 lrvalue: LRValue,
804) TransError!TransResult {
805 return transStmt(rp, scope, @ptrCast(*const ZigClangStmt, expr), used, lrvalue);
806}
807
808fn findBlockScope(inner: *Scope) *Scope.Block {
809 var scope = inner;
810 while (true) : (scope = scope.parent orelse unreachable) {
811 if (scope.id == .Block) return @fieldParentPtr(Scope.Block, "base", scope);
812 }
813}
814
815fn transLookupZigIdentifier(inner: *Scope, c_name: []const u8) []const u8 {
816 var scope = inner;
817 while (true) : (scope = scope.parent orelse return c_name) {
818 if (scope.id == .Var) {
819 const var_scope = @ptrCast(*const Scope.Var, scope);
820 if (std.mem.eql(u8, var_scope.c_name, c_name)) return var_scope.zig_name;
821 }
822 }
823}
824
825fn transCPtrCast(
826 rp: RestorePoint,
827 loc: ZigClangSourceLocation,
828 dst_type: ZigClangQualType,
829 src_type: ZigClangQualType,
830 expr: *ast.Node,
831) !*ast.Node {
832 const ty = ZigClangQualType_getTypePtr(dst_type);
833 const child_type = ZigClangType_getPointeeType(ty);
834
835 // Implicit downcasting from higher to lower alignment values is forbidden,
836 // use @alignCast to side-step this problem
837 const ptrcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrCast");
838 const dst_type_node = try transType(rp, ty, loc);
839 try ptrcast_node.params.push(dst_type_node);
840 _ = try appendToken(rp.c, .Comma, ",");
841
842 if (ZigClangType_isVoidType(qualTypeCanon(child_type))) {
843 // void has 1-byte alignment, so @alignCast is not needed
844 try ptrcast_node.params.push(expr);
845 } else {
846 const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast");
847 const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf");
848 const child_type_node = try transQualType(rp, child_type, loc);
849 try alignof_node.params.push(child_type_node);
850 alignof_node.rparen_token = try appendToken(rp.c, .RParen, ")");
851 try aligncast_node.params.push(&alignof_node.base);
852 _ = try appendToken(rp.c, .Comma, ",");
853 try aligncast_node.params.push(expr);
854 aligncast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
855 try ptrcast_node.params.push(&aligncast_node.base);
856 }
857 ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
858
859 return &ptrcast_node.base;
860}
861
862fn maybeSuppressResult(
863 rp: RestorePoint,
864 scope: *Scope,
865 used: ResultUsed,
866 result: TransResult,
867) !TransResult {
868 if (used == .used) return result;
869 // NOTE: This is backwards, but the semicolon must immediately follow the node.
870 _ = try appendToken(rp.c, .Semicolon, ";");
871 const lhs = try appendIdentifier(rp.c, "_");
872 const op_token = try appendToken(rp.c, .Equal, "=");
873 const op_node = try rp.c.a().create(ast.Node.InfixOp);
874 op_node.* = ast.Node.InfixOp{
875 .base = ast.Node{ .id = .InfixOp },
876 .op_token = op_token,
877 .lhs = lhs,
878 .op = .Assign,
879 .rhs = result.node,
880 };
881 return TransResult{
882 .node = &op_node.base,
883 .child_scope = scope,
884 .node_scope = scope,
885 };
886}
887
371fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void {888fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void {
372 try c.tree.root_node.decls.push(decl_node);889 try c.tree.root_node.decls.push(decl_node);
373}890}
...@@ -376,11 +893,263 @@ fn transQualType(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSou...@@ -376,11 +893,263 @@ fn transQualType(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSou
376 return transType(rp, ZigClangQualType_getTypePtr(qt), source_loc);893 return transType(rp, ZigClangQualType_getTypePtr(qt), source_loc);
377}894}
378895
896fn qualTypeIsPtr(qt: ZigClangQualType) bool {
897 return ZigClangType_getTypeClass(qualTypeCanon(qt)) == .Pointer;
898}
899
900fn qualTypeChildIsFnProto(qt: ZigClangQualType) bool {
901 const ty = ZigClangQualType_getTypePtr(qt);
902 if (ZigClangType_getTypeClass(ty) == .Paren) {
903 const paren_type = @ptrCast(*const ZigClangParenType, ty);
904 const inner_type = ZigClangParenType_getInnerType(paren_type);
905 return ZigClangQualType_getTypeClass(inner_type) == .FunctionProto;
906 }
907 if (ZigClangType_getTypeClass(ty) == .Attributed) {
908 const attr_type = @ptrCast(*const ZigClangAttributedType, ty);
909 return qualTypeChildIsFnProto(ZigClangAttributedType_getEquivalentType(attr_type));
910 }
911 return false;
912}
913
379fn qualTypeCanon(qt: ZigClangQualType) *const ZigClangType {914fn qualTypeCanon(qt: ZigClangQualType) *const ZigClangType {
380 const canon = ZigClangQualType_getCanonicalType(qt);915 const canon = ZigClangQualType_getCanonicalType(qt);
381 return ZigClangQualType_getTypePtr(canon);916 return ZigClangQualType_getTypePtr(canon);
382}917}
383918
919fn getExprQualType(c: *Context, expr: *const ZigClangExpr) ZigClangQualType {
920 blk: {
921 // If this is a C `char *`, turn it into a `const char *`
922 if (ZigClangExpr_getStmtClass(expr) != .ImplicitCastExprClass) break :blk;
923 const cast_expr = @ptrCast(*const ZigClangImplicitCastExpr, expr);
924 if (ZigClangImplicitCastExpr_getCastKind(cast_expr) != .ArrayToPointerDecay) break :blk;
925 const sub_expr = ZigClangImplicitCastExpr_getSubExpr(cast_expr);
926 if (ZigClangExpr_getStmtClass(sub_expr) != .StringLiteralClass) break :blk;
927 const array_qt = ZigClangExpr_getType(sub_expr);
928 const array_type = @ptrCast(*const ZigClangArrayType, ZigClangQualType_getTypePtr(array_qt));
929 var pointee_qt = ZigClangArrayType_getElementType(array_type);
930 ZigClangQualType_addConst(&pointee_qt);
931 return ZigClangASTContext_getPointerType(c.clang_context, pointee_qt);
932 }
933 return ZigClangExpr_getType(expr);
934}
935
936fn typeIsOpaque(c: *Context, ty: *const ZigClangType, loc: ZigClangSourceLocation) bool {
937 switch (ZigClangType_getTypeClass(ty)) {
938 .Builtin => {
939 const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
940 return ZigClangBuiltinType_getKind(builtin_ty) == .Void;
941 },
942 .Record => {
943 const record_ty = @ptrCast(*const ZigClangRecordType, ty);
944 const record_decl = ZigClangRecordType_getDecl(record_ty);
945 return (ZigClangRecordDecl_getDefinition(record_decl) == null);
946 },
947 .Elaborated => {
948 const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty);
949 const qt = ZigClangElaboratedType_getNamedType(elaborated_ty);
950 return typeIsOpaque(c, ZigClangQualType_getTypePtr(qt), loc);
951 },
952 .Typedef => {
953 const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);
954 const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
955 const underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
956 return typeIsOpaque(c, ZigClangQualType_getTypePtr(underlying_type), loc);
957 },
958 else => return false,
959 }
960}
961
962fn cIsUnsignedInteger(qt: ZigClangQualType) bool {
963 const c_type = qualTypeCanon(qt);
964 if (ZigClangType_getTypeClass(c_type) != .Builtin) return false;
965 const builtin_ty = @ptrCast(*const ZigClangBuiltinType, c_type);
966 return switch (ZigClangBuiltinType_getKind(builtin_ty)) {
967 .Char_U,
968 .UChar,
969 .Char_S,
970 .UShort,
971 .UInt,
972 .ULong,
973 .ULongLong,
974 .UInt128,
975 .WChar_U,
976 => true,
977 else => false,
978 };
979}
980
981fn transCreateNodeAssign(
982 rp: RestorePoint,
983 scope: *Scope,
984 result_used: ResultUsed,
985 lhs: *const ZigClangExpr,
986 rhs: *const ZigClangExpr,
987) !*ast.Node.InfixOp {
988 // common case
989 // c: lhs = rhs
990 // zig: lhs = rhs
991 if (result_used == .unused) {
992 const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
993 const eq_token = try appendToken(rp.c, .Equal, "=");
994 const rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
995 _ = try appendToken(rp.c, .Semicolon, ";");
996
997 const node = try rp.c.a().create(ast.Node.InfixOp);
998 node.* = ast.Node.InfixOp{
999 .base = ast.Node{ .id = .InfixOp },
1000 .op_token = eq_token,
1001 .lhs = lhs_node.node,
1002 .op = .Assign,
1003 .rhs = rhs_node.node,
1004 };
1005 return node;
1006 }
1007
1008 // worst case
1009 // c: lhs = rhs
1010 // zig: (x: {
1011 // zig: const _tmp = rhs;
1012 // zig: lhs = _tmp;
1013 // zig: break :x _tmp
1014 // zig: })
1015 return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangExpr_getBeginLoc(lhs), "TODO: worst case assign op expr");
1016}
1017
1018fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.BuiltinCall {
1019 const builtin_token = try appendToken(c, .Builtin, name);
1020 _ = try appendToken(c, .LParen, "(");
1021 const node = try c.a().create(ast.Node.BuiltinCall);
1022 node.* = ast.Node.BuiltinCall{
1023 .base = ast.Node{ .id = .BuiltinCall },
1024 .builtin_token = builtin_token,
1025 .params = ast.Node.BuiltinCall.ParamList.init(c.a()),
1026 .rparen_token = undefined, // set after appending args
1027 };
1028 return node;
1029}
1030
1031fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp {
1032 _ = try appendToken(c, .LParen, "(");
1033 const node = try c.a().create(ast.Node.SuffixOp);
1034 node.* = ast.Node.SuffixOp{
1035 .base = ast.Node{ .id = .SuffixOp },
1036 .lhs = fn_expr,
1037 .op = ast.Node.SuffixOp.Op{
1038 .Call = ast.Node.SuffixOp.Op.Call{
1039 .params = ast.Node.SuffixOp.Op.Call.ParamList.init(c.a()),
1040 .async_attr = null,
1041 },
1042 },
1043 .rtoken = undefined, // set after appending args
1044 };
1045 return node;
1046}
1047
1048fn transCreateNodePrefixOp(
1049 c: *Context,
1050 op: ast.Node.PrefixOp.Op,
1051 op_tok_id: std.zig.Token.Id,
1052 bytes: []const u8,
1053) !*ast.Node.PrefixOp {
1054 const node = try c.a().create(ast.Node.PrefixOp);
1055 node.* = ast.Node.PrefixOp{
1056 .base = ast.Node{ .id = .PrefixOp },
1057 .op_token = try appendToken(c, op_tok_id, bytes),
1058 .op = op,
1059 .rhs = undefined, // translate and set afterward
1060 };
1061 return node;
1062}
1063
1064fn transCreateNodeInfixOp(
1065 rp: RestorePoint,
1066 scope: *Scope,
1067 stmt: *const ZigClangBinaryOperator,
1068 op: ast.Node.InfixOp.Op,
1069 op_tok_id: std.zig.Token.Id,
1070 bytes: []const u8,
1071 grouped: bool,
1072) !*ast.Node {
1073 const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined;
1074 const lhs = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value);
1075 const op_token = try appendToken(rp.c, op_tok_id, bytes);
1076 const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
1077 const node = try rp.c.a().create(ast.Node.InfixOp);
1078 node.* = ast.Node.InfixOp{
1079 .base = ast.Node{ .id = .InfixOp },
1080 .op_token = op_token,
1081 .lhs = lhs.node,
1082 .op = op,
1083 .rhs = rhs.node,
1084 };
1085 if (!grouped) return &node.base;
1086 const rparen = try appendToken(rp.c, .RParen, ")");
1087 const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
1088 grouped_expr.* = ast.Node.GroupedExpression{
1089 .base = ast.Node{ .id = .GroupedExpression },
1090 .lparen = lparen,
1091 .expr = &node.base,
1092 .rparen = rparen,
1093 };
1094 return &grouped_expr.base;
1095}
1096
1097fn transCreateNodePtrType(
1098 c: *Context,
1099 is_const: bool,
1100 is_volatile: bool,
1101 op_tok_id: std.zig.Token.Id,
1102 bytes: []const u8,
1103) !*ast.Node.PrefixOp {
1104 const node = try c.a().create(ast.Node.PrefixOp);
1105 node.* = ast.Node.PrefixOp{
1106 .base = ast.Node{ .id = .PrefixOp },
1107 .op_token = try appendToken(c, op_tok_id, bytes),
1108 .op = ast.Node.PrefixOp.Op{
1109 .PtrType = ast.Node.PrefixOp.PtrInfo{
1110 .allowzero_token = null,
1111 .align_info = null,
1112 .const_token = if (is_const) try appendToken(c, .Keyword_const, "const") else null,
1113 .volatile_token = if (is_volatile) try appendToken(c, .Keyword_volatile, "volatile") else null,
1114 },
1115 },
1116 .rhs = undefined, // translate and set afterward
1117 };
1118 return node;
1119}
1120
1121fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node {
1122 const num_limbs = ZigClangAPSInt_getNumWords(int.?);
1123 var big = try std.math.big.Int.initCapacity(c.a(), num_limbs);
1124 defer big.deinit();
1125 const data = ZigClangAPSInt_getRawData(int.?);
1126 var i: usize = 0;
1127 while (i < num_limbs) : (i += 1) big.limbs[i] = data[i];
1128 const str = big.toString(c.a(), 10) catch |err| switch (err) {
1129 error.OutOfMemory => return error.OutOfMemory,
1130 else => unreachable,
1131 };
1132 const token = try appendToken(c, .IntegerLiteral, str);
1133 const node = try c.a().create(ast.Node.IntegerLiteral);
1134 node.* = ast.Node.IntegerLiteral{
1135 .base = ast.Node{ .id = .IntegerLiteral },
1136 .token = token,
1137 };
1138 return &node.base;
1139}
1140
1141fn transCreateNodeReturnExpr(c: *Context) !*ast.Node {
1142 const ltoken = try appendToken(c, .Keyword_return, "return");
1143 const node = try c.a().create(ast.Node.ControlFlowExpression);
1144 node.* = ast.Node.ControlFlowExpression{
1145 .base = ast.Node{ .id = .ControlFlowExpression },
1146 .ltoken = ltoken,
1147 .kind = .Return,
1148 .rhs = null,
1149 };
1150 return &node.base;
1151}
1152
384const RestorePoint = struct {1153const RestorePoint = struct {
385 c: *Context,1154 c: *Context,
386 token_index: ast.TokenIndex,1155 token_index: ast.TokenIndex,
...@@ -429,9 +1198,43 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour...@@ -429,9 +1198,43 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
429 },1198 },
430 .FunctionProto => {1199 .FunctionProto => {
431 const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty);1200 const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty);
432 const fn_proto = try transFnProto(rp, fn_proto_ty, source_loc, null);1201 const fn_proto = try transFnProto(rp, fn_proto_ty, source_loc, null, false);
433 return &fn_proto.base;1202 return &fn_proto.base;
434 },1203 },
1204 .Paren => {
1205 const paren_ty = @ptrCast(*const ZigClangParenType, ty);
1206 return transQualType(rp, ZigClangParenType_getInnerType(paren_ty), source_loc);
1207 },
1208 .Pointer => {
1209 const child_qt = ZigClangType_getPointeeType(ty);
1210 if (qualTypeChildIsFnProto(child_qt)) {
1211 const optional_node = try transCreateNodePrefixOp(rp.c, .OptionalType, .QuestionMark, "?");
1212 optional_node.rhs = try transQualType(rp, child_qt, source_loc);
1213 return &optional_node.base;
1214 }
1215 if (typeIsOpaque(rp.c, ZigClangQualType_getTypePtr(child_qt), source_loc)) {
1216 const optional_node = try transCreateNodePrefixOp(rp.c, .OptionalType, .QuestionMark, "?");
1217 const pointer_node = try transCreateNodePtrType(
1218 rp.c,
1219 ZigClangQualType_isConstQualified(child_qt),
1220 ZigClangQualType_isVolatileQualified(child_qt),
1221 .Asterisk,
1222 "*",
1223 );
1224 optional_node.rhs = &pointer_node.base;
1225 pointer_node.rhs = try transQualType(rp, child_qt, source_loc);
1226 return &optional_node.base;
1227 }
1228 const pointer_node = try transCreateNodePtrType(
1229 rp.c,
1230 ZigClangQualType_isConstQualified(child_qt),
1231 ZigClangQualType_isVolatileQualified(child_qt),
1232 .BracketStarCBracket,
1233 "[*c]",
1234 );
1235 pointer_node.rhs = try transQualType(rp, child_qt, source_loc);
1236 return &pointer_node.base;
1237 },
435 else => {1238 else => {
436 const type_name = rp.c.str(ZigClangType_getTypeClassName(ty));1239 const type_name = rp.c.str(ZigClangType_getTypeClassName(ty));
437 return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported type: '{}'", type_name);1240 return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported type: '{}'", type_name);
...@@ -465,6 +1268,7 @@ fn transFnProto(...@@ -465,6 +1268,7 @@ fn transFnProto(
465 fn_proto_ty: *const ZigClangFunctionProtoType,1268 fn_proto_ty: *const ZigClangFunctionProtoType,
466 source_loc: ZigClangSourceLocation,1269 source_loc: ZigClangSourceLocation,
467 fn_decl_context: ?FnDeclContext,1270 fn_decl_context: ?FnDeclContext,
1271 is_pub: bool,
468) !*ast.Node.FnProto {1272) !*ast.Node.FnProto {
469 const fn_ty = @ptrCast(*const ZigClangFunctionType, fn_proto_ty);1273 const fn_ty = @ptrCast(*const ZigClangFunctionType, fn_proto_ty);
470 const cc = try transCC(rp, fn_ty, source_loc);1274 const cc = try transCC(rp, fn_ty, source_loc);
...@@ -475,7 +1279,7 @@ fn transFnProto(...@@ -475,7 +1279,7 @@ fn transFnProto(
475 return revertAndWarn(rp, error.UnsupportedType, source_loc, "TODO: implement parameters for FunctionProto in transType");1279 return revertAndWarn(rp, error.UnsupportedType, source_loc, "TODO: implement parameters for FunctionProto in transType");
476 }1280 }
4771281
478 return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc);1282 return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub);
479}1283}
4801284
481fn transFnNoProto(1285fn transFnNoProto(
...@@ -483,10 +1287,11 @@ fn transFnNoProto(...@@ -483,10 +1287,11 @@ fn transFnNoProto(
483 fn_ty: *const ZigClangFunctionType,1287 fn_ty: *const ZigClangFunctionType,
484 source_loc: ZigClangSourceLocation,1288 source_loc: ZigClangSourceLocation,
485 fn_decl_context: ?FnDeclContext,1289 fn_decl_context: ?FnDeclContext,
1290 is_pub: bool,
486) !*ast.Node.FnProto {1291) !*ast.Node.FnProto {
487 const cc = try transCC(rp, fn_ty, source_loc);1292 const cc = try transCC(rp, fn_ty, source_loc);
488 const is_var_args = if (fn_decl_context) |ctx| !ctx.is_export else true;1293 const is_var_args = if (fn_decl_context) |ctx| !ctx.is_export else true;
489 return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc);1294 return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub);
490}1295}
4911296
492fn finishTransFnProto(1297fn finishTransFnProto(
...@@ -496,18 +1301,20 @@ fn finishTransFnProto(...@@ -496,18 +1301,20 @@ fn finishTransFnProto(
496 fn_decl_context: ?FnDeclContext,1301 fn_decl_context: ?FnDeclContext,
497 is_var_args: bool,1302 is_var_args: bool,
498 cc: CallingConvention,1303 cc: CallingConvention,
1304 is_pub: bool,
499) !*ast.Node.FnProto {1305) !*ast.Node.FnProto {
500 const is_export = if (fn_decl_context) |ctx| ctx.is_export else false;1306 const is_export = if (fn_decl_context) |ctx| ctx.is_export else false;
1307 const is_extern = if (fn_decl_context) |ctx| !ctx.has_body else true;
5011308
502 // TODO check for always_inline attribute1309 // TODO check for always_inline attribute
503 // TODO check for align attribute1310 // TODO check for align attribute
5041311
505 // pub extern fn name(...) T1312 // pub extern fn name(...) T
506 const pub_tok = try appendToken(rp.c, .Keyword_pub, "pub");1313 const pub_tok = if (is_pub) try appendToken(rp.c, .Keyword_pub, "pub") else null;
507 const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null;1314 const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null;
508 const extern_export_inline_tok = if (is_export)1315 const extern_export_inline_tok = if (is_export)
509 try appendToken(rp.c, .Keyword_export, "export")1316 try appendToken(rp.c, .Keyword_export, "export")
510 else if (cc == .C)1317 else if (cc == .C and is_extern)
511 try appendToken(rp.c, .Keyword_extern, "extern")1318 try appendToken(rp.c, .Keyword_extern, "extern")
512 else1319 else
513 null;1320 null;
...@@ -657,7 +1464,7 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8,...@@ -657,7 +1464,7 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8,
657 .start = start_index,1464 .start = start_index,
658 .end = end_index,1465 .end = end_index,
659 };1466 };
660 try c.source_buffer.appendByte('\n');1467 try c.source_buffer.appendByte(' ');
6611468
662 return token_index;1469 return token_index;
663}1470}
src/ast_render.cpp+1-2
...@@ -444,9 +444,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -444,9 +444,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
444 const char *extern_str = extern_string(node->data.fn_proto.is_extern);444 const char *extern_str = extern_string(node->data.fn_proto.is_extern);
445 const char *export_str = export_string(node->data.fn_proto.is_export);445 const char *export_str = export_string(node->data.fn_proto.is_export);
446 const char *inline_str = inline_string(node->data.fn_proto.is_inline);446 const char *inline_str = inline_string(node->data.fn_proto.is_inline);
447 fprintf(ar->f, "%s%s%s%sfn", pub_str, inline_str, export_str, extern_str);447 fprintf(ar->f, "%s%s%s%sfn ", pub_str, inline_str, export_str, extern_str);
448 if (node->data.fn_proto.name != nullptr) {448 if (node->data.fn_proto.name != nullptr) {
449 fprintf(ar->f, " ");
450 print_symbol(ar, node->data.fn_proto.name);449 print_symbol(ar, node->data.fn_proto.name);
451 }450 }
452 fprintf(ar->f, "(");451 fprintf(ar->f, "(");
src/codegen.cpp+1-1
...@@ -3837,7 +3837,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3837,7 +3837,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3837 return result_loc;3837 return result_loc;
3838 } else if (handle_is_ptr(src_return_type)) {3838 } else if (handle_is_ptr(src_return_type)) {
3839 LLVMValueRef store_instr = LLVMBuildStore(g->builder, result, result_loc);3839 LLVMValueRef store_instr = LLVMBuildStore(g->builder, result, result_loc);
3840 LLVMSetAlignment(store_instr, LLVMGetAlignment(result_loc));3840 LLVMSetAlignment(store_instr, get_ptr_align(g, instruction->result_loc->value.type));
3841 return result_loc;3841 return result_loc;
3842 } else {3842 } else {
3843 return result;3843 return result;
src/zig_clang.cpp+160-1
...@@ -21,6 +21,7 @@...@@ -21,6 +21,7 @@
2121
22#include <clang/Frontend/ASTUnit.h>22#include <clang/Frontend/ASTUnit.h>
23#include <clang/Frontend/CompilerInstance.h>23#include <clang/Frontend/CompilerInstance.h>
24#include <clang/AST/APValue.h>
24#include <clang/AST/Expr.h>25#include <clang/AST/Expr.h>
2526
26#if __GNUC__ >= 827#if __GNUC__ >= 8
...@@ -1287,6 +1288,20 @@ static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind...@@ -1287,6 +1288,20 @@ static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind
1287static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_UTF16 == clang::StringLiteral::UTF16, "");1288static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_UTF16 == clang::StringLiteral::UTF16, "");
1288static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_UTF32 == clang::StringLiteral::UTF32, "");1289static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_UTF32 == clang::StringLiteral::UTF32, "");
12891290
1291static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Uninitialized == clang::APValue::ValueKind::Uninitialized, "");
1292static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Int == clang::APValue::ValueKind::Int, "");
1293static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Float == clang::APValue::ValueKind::Float, "");
1294static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_ComplexInt == clang::APValue::ValueKind::ComplexInt, "");
1295static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_ComplexFloat == clang::APValue::ValueKind::ComplexFloat, "");
1296static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_LValue == clang::APValue::ValueKind::LValue, "");
1297static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Vector == clang::APValue::ValueKind::Vector, "");
1298static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Array == clang::APValue::ValueKind::Array, "");
1299static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Struct == clang::APValue::ValueKind::Struct, "");
1300static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Union == clang::APValue::ValueKind::Union, "");
1301static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_MemberPointer == clang::APValue::ValueKind::MemberPointer, "");
1302static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_AddrLabelDiff == clang::APValue::ValueKind::AddrLabelDiff, "");
1303
1304static_assert(sizeof(ZigClangAPValue) == sizeof(clang::APValue), "");
12901305
1291static_assert(sizeof(ZigClangSourceLocation) == sizeof(clang::SourceLocation), "");1306static_assert(sizeof(ZigClangSourceLocation) == sizeof(clang::SourceLocation), "");
1292static ZigClangSourceLocation bitcast(clang::SourceLocation src) {1307static ZigClangSourceLocation bitcast(clang::SourceLocation src) {
...@@ -1312,6 +1327,13 @@ static clang::QualType bitcast(ZigClangQualType src) {...@@ -1312,6 +1327,13 @@ static clang::QualType bitcast(ZigClangQualType src) {
1312 return dest;1327 return dest;
1313}1328}
13141329
1330static_assert(sizeof(ZigClangExprEvalResult) == sizeof(clang::Expr::EvalResult), "");
1331static ZigClangExprEvalResult bitcast(clang::Expr::EvalResult src) {
1332 ZigClangExprEvalResult dest;
1333 memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangExprEvalResult));
1334 return dest;
1335}
1336
1315static_assert(sizeof(ZigClangAPValueLValueBase) == sizeof(clang::APValue::LValueBase), "");1337static_assert(sizeof(ZigClangAPValueLValueBase) == sizeof(clang::APValue::LValueBase), "");
1316static ZigClangAPValueLValueBase bitcast(clang::APValue::LValueBase src) {1338static ZigClangAPValueLValueBase bitcast(clang::APValue::LValueBase src) {
1317 ZigClangAPValueLValueBase dest;1339 ZigClangAPValueLValueBase dest;
...@@ -1331,6 +1353,12 @@ static ZigClangCompoundStmt_const_body_iterator bitcast(clang::CompoundStmt::con...@@ -1331,6 +1353,12 @@ static ZigClangCompoundStmt_const_body_iterator bitcast(clang::CompoundStmt::con
1331 return dest;1353 return dest;
1332}1354}
13331355
1356static_assert(sizeof(ZigClangDeclStmt_const_decl_iterator) == sizeof(clang::DeclStmt::const_decl_iterator), "");
1357static ZigClangDeclStmt_const_decl_iterator bitcast(clang::DeclStmt::const_decl_iterator src) {
1358 ZigClangDeclStmt_const_decl_iterator dest;
1359 memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangDeclStmt_const_decl_iterator));
1360 return dest;
1361}
13341362
1335ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const ZigClangSourceManager *self,1363ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const ZigClangSourceManager *self,
1336 ZigClangSourceLocation Loc)1364 ZigClangSourceLocation Loc)
...@@ -1381,7 +1409,7 @@ ZigClangSourceManager *ZigClangASTUnit_getSourceManager(ZigClangASTUnit *self) {...@@ -1381,7 +1409,7 @@ ZigClangSourceManager *ZigClangASTUnit_getSourceManager(ZigClangASTUnit *self) {
1381 return reinterpret_cast<ZigClangSourceManager *>(result);1409 return reinterpret_cast<ZigClangSourceManager *>(result);
1382}1410}
13831411
1384bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *self, void *context, 1412bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *self, void *context,
1385 bool (*Fn)(void *context, const ZigClangDecl *decl))1413 bool (*Fn)(void *context, const ZigClangDecl *decl))
1386{1414{
1387 return reinterpret_cast<clang::ASTUnit *>(self)->visitLocalTopLevelDecls(context,1415 return reinterpret_cast<clang::ASTUnit *>(self)->visitLocalTopLevelDecls(context,
...@@ -1540,6 +1568,11 @@ const ZigClangType *ZigClangQualType_getTypePtr(ZigClangQualType self) {...@@ -1540,6 +1568,11 @@ const ZigClangType *ZigClangQualType_getTypePtr(ZigClangQualType self) {
1540 return reinterpret_cast<const ZigClangType *>(ty);1568 return reinterpret_cast<const ZigClangType *>(ty);
1541}1569}
15421570
1571ZigClangTypeClass ZigClangQualType_getTypeClass(ZigClangQualType self) {
1572 clang::QualType ty = bitcast(self);
1573 return (ZigClangTypeClass)(ty->getTypeClass());
1574}
1575
1543void ZigClangQualType_addConst(ZigClangQualType *self) {1576void ZigClangQualType_addConst(ZigClangQualType *self) {
1544 reinterpret_cast<clang::QualType *>(self)->addConst();1577 reinterpret_cast<clang::QualType *>(self)->addConst();
1545}1578}
...@@ -1815,6 +1848,21 @@ void ZigClangASTUnit_delete(struct ZigClangASTUnit *self) {...@@ -1815,6 +1848,21 @@ void ZigClangASTUnit_delete(struct ZigClangASTUnit *self) {
1815 delete reinterpret_cast<clang::ASTUnit *>(self);1848 delete reinterpret_cast<clang::ASTUnit *>(self);
1816}1849}
18171850
1851struct ZigClangQualType ZigClangVarDecl_getType(const struct ZigClangVarDecl *self) {
1852 auto casted = reinterpret_cast<const clang::VarDecl *>(self);
1853 return bitcast(casted->getType());
1854}
1855
1856const struct ZigClangExpr *ZigClangVarDecl_getInit(const struct ZigClangVarDecl *self) {
1857 auto casted = reinterpret_cast<const clang::VarDecl *>(self);
1858 return reinterpret_cast<const ZigClangExpr *>(casted->getInit());
1859}
1860
1861enum ZigClangVarDecl_TLSKind ZigClangVarDecl_getTLSKind(const ZigClangVarDecl *self) {
1862 auto casted = reinterpret_cast<const clang::VarDecl *>(self);
1863 return (ZigClangVarDecl_TLSKind)casted->getTLSKind();
1864}
1865
1818enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBuiltinType *self) {1866enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBuiltinType *self) {
1819 auto casted = reinterpret_cast<const clang::BuiltinType *>(self);1867 auto casted = reinterpret_cast<const clang::BuiltinType *>(self);
1820 return (ZigClangBuiltinTypeKind)casted->getKind();1868 return (ZigClangBuiltinTypeKind)casted->getKind();
...@@ -1862,6 +1910,16 @@ ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_end(const str...@@ -1862,6 +1910,16 @@ ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_end(const str
1862 return bitcast(casted->body_end());1910 return bitcast(casted->body_end());
1863}1911}
18641912
1913ZigClangDeclStmt_const_decl_iterator ZigClangDeclStmt_decl_begin(const struct ZigClangDeclStmt *self) {
1914 auto casted = reinterpret_cast<const clang::DeclStmt *>(self);
1915 return bitcast(casted->decl_begin());
1916}
1917
1918ZigClangDeclStmt_const_decl_iterator ZigClangDeclStmt_decl_end(const struct ZigClangDeclStmt *self) {
1919 auto casted = reinterpret_cast<const clang::DeclStmt *>(self);
1920 return bitcast(casted->decl_end());
1921}
1922
1865unsigned ZigClangAPFloat_convertToHexString(const ZigClangAPFloat *self, char *DST,1923unsigned ZigClangAPFloat_convertToHexString(const ZigClangAPFloat *self, char *DST,
1866 unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM)1924 unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM)
1867{1925{
...@@ -1888,3 +1946,104 @@ const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName(...@@ -1888,3 +1946,104 @@ const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName(
1888 const clang::StringLiteral *result = casted->getFunctionName();1946 const clang::StringLiteral *result = casted->getFunctionName();
1889 return reinterpret_cast<const struct ZigClangStringLiteral *>(result);1947 return reinterpret_cast<const struct ZigClangStringLiteral *>(result);
1890}1948}
1949
1950ZigClangSourceLocation ZigClangImplicitCastExpr_getBeginLoc(const struct ZigClangImplicitCastExpr *self) {
1951 auto casted = reinterpret_cast<const clang::ImplicitCastExpr *>(self);
1952 return bitcast(casted->getBeginLoc());
1953}
1954
1955enum ZigClangCK ZigClangImplicitCastExpr_getCastKind(const struct ZigClangImplicitCastExpr *self) {
1956 auto casted = reinterpret_cast<const clang::ImplicitCastExpr *>(self);
1957 return (ZigClangCK)casted->getCastKind();
1958}
1959
1960const struct ZigClangExpr *ZigClangImplicitCastExpr_getSubExpr(const struct ZigClangImplicitCastExpr *self) {
1961 auto casted = reinterpret_cast<const clang::ImplicitCastExpr *>(self);
1962 return reinterpret_cast<const struct ZigClangExpr *>(casted->getSubExpr());
1963}
1964
1965struct ZigClangQualType ZigClangArrayType_getElementType(const struct ZigClangArrayType *self) {
1966 auto casted = reinterpret_cast<const clang::ArrayType *>(self);
1967 return bitcast(casted->getElementType());
1968}
1969
1970const struct ZigClangValueDecl *ZigClangDeclRefExpr_getDecl(const struct ZigClangDeclRefExpr *self) {
1971 auto casted = reinterpret_cast<const clang::DeclRefExpr *>(self);
1972 return reinterpret_cast<const struct ZigClangValueDecl *>(casted->getDecl());
1973}
1974
1975struct ZigClangQualType ZigClangParenType_getInnerType(const struct ZigClangParenType *self) {
1976 auto casted = reinterpret_cast<const clang::ParenType *>(self);
1977 return bitcast(casted->getInnerType());
1978}
1979
1980struct ZigClangQualType ZigClangAttributedType_getEquivalentType(const struct ZigClangAttributedType *self) {
1981 auto casted = reinterpret_cast<const clang::AttributedType *>(self);
1982 return bitcast(casted->getEquivalentType());
1983}
1984
1985struct ZigClangQualType ZigClangElaboratedType_getNamedType(const struct ZigClangElaboratedType *self) {
1986 auto casted = reinterpret_cast<const clang::ElaboratedType *>(self);
1987 return bitcast(casted->getNamedType());
1988}
1989
1990struct ZigClangSourceLocation ZigClangCStyleCastExpr_getBeginLoc(const struct ZigClangCStyleCastExpr *self) {
1991 auto casted = reinterpret_cast<const clang::CStyleCastExpr *>(self);
1992 return bitcast(casted->getBeginLoc());
1993}
1994
1995const struct ZigClangExpr *ZigClangCStyleCastExpr_getSubExpr(const struct ZigClangCStyleCastExpr *self) {
1996 auto casted = reinterpret_cast<const clang::CStyleCastExpr *>(self);
1997 return reinterpret_cast<const struct ZigClangExpr *>(casted->getSubExpr());
1998}
1999
2000struct ZigClangQualType ZigClangCStyleCastExpr_getType(const struct ZigClangCStyleCastExpr *self) {
2001 auto casted = reinterpret_cast<const clang::CStyleCastExpr *>(self);
2002 return bitcast(casted->getType());
2003}
2004
2005bool ZigClangIntegerLiteral_EvaluateAsInt(const struct ZigClangIntegerLiteral *self, struct ZigClangExprEvalResult *result, const struct ZigClangASTContext *ctx) {
2006 auto casted_self = reinterpret_cast<const clang::IntegerLiteral *>(self);
2007 auto casted_ctx = reinterpret_cast<const clang::ASTContext *>(ctx);
2008 clang::Expr::EvalResult eval_result;
2009 if (!casted_self->EvaluateAsInt(eval_result, *casted_ctx)) {
2010 return false;
2011 }
2012 *result = bitcast(eval_result);
2013 return true;
2014}
2015
2016struct ZigClangSourceLocation ZigClangIntegerLiteral_getBeginLoc(const struct ZigClangIntegerLiteral *self) {
2017 auto casted = reinterpret_cast<const clang::IntegerLiteral *>(self);
2018 return bitcast(casted->getBeginLoc());
2019}
2020
2021const struct ZigClangExpr *ZigClangReturnStmt_getRetValue(const struct ZigClangReturnStmt *self) {
2022 auto casted = reinterpret_cast<const clang::ReturnStmt *>(self);
2023 return reinterpret_cast<const struct ZigClangExpr *>(casted->getRetValue());
2024}
2025
2026enum ZigClangBO ZigClangBinaryOperator_getOpcode(const struct ZigClangBinaryOperator *self) {
2027 auto casted = reinterpret_cast<const clang::BinaryOperator *>(self);
2028 return (ZigClangBO)casted->getOpcode();
2029}
2030
2031struct ZigClangSourceLocation ZigClangBinaryOperator_getBeginLoc(const struct ZigClangBinaryOperator *self) {
2032 auto casted = reinterpret_cast<const clang::BinaryOperator *>(self);
2033 return bitcast(casted->getBeginLoc());
2034}
2035
2036const struct ZigClangExpr *ZigClangBinaryOperator_getLHS(const struct ZigClangBinaryOperator *self) {
2037 auto casted = reinterpret_cast<const clang::BinaryOperator *>(self);
2038 return reinterpret_cast<const struct ZigClangExpr *>(casted->getLHS());
2039}
2040
2041const struct ZigClangExpr *ZigClangBinaryOperator_getRHS(const struct ZigClangBinaryOperator *self) {
2042 auto casted = reinterpret_cast<const clang::BinaryOperator *>(self);
2043 return reinterpret_cast<const struct ZigClangExpr *>(casted->getRHS());
2044}
2045
2046struct ZigClangQualType ZigClangBinaryOperator_getType(const struct ZigClangBinaryOperator *self) {
2047 auto casted = reinterpret_cast<const clang::BinaryOperator *>(self);
2048 return bitcast(casted->getType());
2049}
src/zig_clang.h+78-1
...@@ -30,6 +30,38 @@ struct ZigClangAPValueLValueBase {...@@ -30,6 +30,38 @@ struct ZigClangAPValueLValueBase {
30 unsigned Version;30 unsigned Version;
31};31};
3232
33enum ZigClangAPValue_ValueKind {
34 ZigClangAPValue_ValueKind_Uninitialized,
35 ZigClangAPValue_ValueKind_Int,
36 ZigClangAPValue_ValueKind_Float,
37 ZigClangAPValue_ValueKind_ComplexInt,
38 ZigClangAPValue_ValueKind_ComplexFloat,
39 ZigClangAPValue_ValueKind_LValue,
40 ZigClangAPValue_ValueKind_Vector,
41 ZigClangAPValue_ValueKind_Array,
42 ZigClangAPValue_ValueKind_Struct,
43 ZigClangAPValue_ValueKind_Union,
44 ZigClangAPValue_ValueKind_MemberPointer,
45 ZigClangAPValue_ValueKind_AddrLabelDiff
46};
47
48struct ZigClangAPValue {
49 enum ZigClangAPValue_ValueKind Kind;
50 // experimentally-derived size of clang::APValue::DataType
51#ifdef _WIN32
52 char Data[52];
53#else
54 char Data[68];
55#endif
56};
57
58struct ZigClangExprEvalResult {
59 bool HasSideEffects;
60 bool HasUndefinedBehavior;
61 void *SmallVectorImpl;
62 ZigClangAPValue Val;
63};
64
33struct ZigClangAPValue;65struct ZigClangAPValue;
34struct ZigClangAPSInt;66struct ZigClangAPSInt;
35struct ZigClangAPFloat;67struct ZigClangAPFloat;
...@@ -105,6 +137,7 @@ struct ZigClangFunctionType;...@@ -105,6 +137,7 @@ struct ZigClangFunctionType;
105struct ZigClangPredefinedExpr;137struct ZigClangPredefinedExpr;
106138
107typedef struct ZigClangStmt *const * ZigClangCompoundStmt_const_body_iterator;139typedef struct ZigClangStmt *const * ZigClangCompoundStmt_const_body_iterator;
140typedef struct ZigClangDecl *const * ZigClangDeclStmt_const_decl_iterator;
108141
109enum ZigClangBO {142enum ZigClangBO {
110 ZigClangBO_PtrMemD,143 ZigClangBO_PtrMemD,
...@@ -732,6 +765,12 @@ enum ZigClangStringLiteral_StringKind {...@@ -732,6 +765,12 @@ enum ZigClangStringLiteral_StringKind {
732 ZigClangStringLiteral_StringKind_UTF32,765 ZigClangStringLiteral_StringKind_UTF32,
733};766};
734767
768enum ZigClangVarDecl_TLSKind {
769 ZigClangVarDecl_TLSKind_None,
770 ZigClangVarDecl_TLSKind_Static,
771 ZigClangVarDecl_TLSKind_Dynamic,
772};
773
735ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const struct ZigClangSourceManager *,774ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const struct ZigClangSourceManager *,
736 struct ZigClangSourceLocation Loc);775 struct ZigClangSourceLocation Loc);
737ZIG_EXTERN_C const char *ZigClangSourceManager_getFilename(const struct ZigClangSourceManager *,776ZIG_EXTERN_C const char *ZigClangSourceManager_getFilename(const struct ZigClangSourceManager *,
...@@ -754,7 +793,7 @@ ZIG_EXTERN_C void ZigClangErrorMsg_delete(struct Stage2ErrorMsg *ptr, size_t len...@@ -754,7 +793,7 @@ ZIG_EXTERN_C void ZigClangErrorMsg_delete(struct Stage2ErrorMsg *ptr, size_t len
754793
755ZIG_EXTERN_C struct ZigClangASTContext *ZigClangASTUnit_getASTContext(struct ZigClangASTUnit *);794ZIG_EXTERN_C struct ZigClangASTContext *ZigClangASTUnit_getASTContext(struct ZigClangASTUnit *);
756ZIG_EXTERN_C struct ZigClangSourceManager *ZigClangASTUnit_getSourceManager(struct ZigClangASTUnit *);795ZIG_EXTERN_C struct ZigClangSourceManager *ZigClangASTUnit_getSourceManager(struct ZigClangASTUnit *);
757ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(struct ZigClangASTUnit *, void *context, 796ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(struct ZigClangASTUnit *, void *context,
758 bool (*Fn)(void *context, const struct ZigClangDecl *decl));797 bool (*Fn)(void *context, const struct ZigClangDecl *decl));
759798
760ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordType_getDecl(const struct ZigClangRecordType *record_ty);799ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordType_getDecl(const struct ZigClangRecordType *record_ty);
...@@ -789,6 +828,10 @@ ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const struct ZigClangD...@@ -789,6 +828,10 @@ ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const struct ZigClangD
789ZIG_EXTERN_C enum ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *decl);828ZIG_EXTERN_C enum ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *decl);
790ZIG_EXTERN_C const char *ZigClangDecl_getDeclKindName(const struct ZigClangDecl *decl);829ZIG_EXTERN_C const char *ZigClangDecl_getDeclKindName(const struct ZigClangDecl *decl);
791830
831ZIG_EXTERN_C struct ZigClangQualType ZigClangVarDecl_getType(const struct ZigClangVarDecl *);
832ZIG_EXTERN_C const struct ZigClangExpr *ZigClangVarDecl_getInit(const struct ZigClangVarDecl *var_decl);
833ZIG_EXTERN_C enum ZigClangVarDecl_TLSKind ZigClangVarDecl_getTLSKind(const struct ZigClangVarDecl *var_decl);
834
792ZIG_EXTERN_C bool ZigClangSourceLocation_eq(struct ZigClangSourceLocation a, struct ZigClangSourceLocation b);835ZIG_EXTERN_C bool ZigClangSourceLocation_eq(struct ZigClangSourceLocation a, struct ZigClangSourceLocation b);
793836
794ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const struct ZigClangTypedefType *);837ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const struct ZigClangTypedefType *);
...@@ -796,6 +839,7 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangTypedefNameDecl_getUnderlyingType(c...@@ -796,6 +839,7 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangTypedefNameDecl_getUnderlyingType(c
796839
797ZIG_EXTERN_C struct ZigClangQualType ZigClangQualType_getCanonicalType(struct ZigClangQualType);840ZIG_EXTERN_C struct ZigClangQualType ZigClangQualType_getCanonicalType(struct ZigClangQualType);
798ZIG_EXTERN_C const struct ZigClangType *ZigClangQualType_getTypePtr(struct ZigClangQualType);841ZIG_EXTERN_C const struct ZigClangType *ZigClangQualType_getTypePtr(struct ZigClangQualType);
842ZIG_EXTERN_C enum ZigClangTypeClass ZigClangQualType_getTypeClass(struct ZigClangQualType);
799ZIG_EXTERN_C void ZigClangQualType_addConst(struct ZigClangQualType *);843ZIG_EXTERN_C void ZigClangQualType_addConst(struct ZigClangQualType *);
800ZIG_EXTERN_C bool ZigClangQualType_eq(struct ZigClangQualType, struct ZigClangQualType);844ZIG_EXTERN_C bool ZigClangQualType_eq(struct ZigClangQualType, struct ZigClangQualType);
801ZIG_EXTERN_C bool ZigClangQualType_isConstQualified(struct ZigClangQualType);845ZIG_EXTERN_C bool ZigClangQualType_isConstQualified(struct ZigClangQualType);
...@@ -846,6 +890,9 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionProtoType_getParamType(cons...@@ -846,6 +890,9 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionProtoType_getParamType(cons
846ZIG_EXTERN_C ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_begin(const struct ZigClangCompoundStmt *self);890ZIG_EXTERN_C ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_begin(const struct ZigClangCompoundStmt *self);
847ZIG_EXTERN_C ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_end(const struct ZigClangCompoundStmt *self);891ZIG_EXTERN_C ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_end(const struct ZigClangCompoundStmt *self);
848892
893ZIG_EXTERN_C ZigClangDeclStmt_const_decl_iterator ZigClangDeclStmt_decl_begin(const struct ZigClangDeclStmt *self);
894ZIG_EXTERN_C ZigClangDeclStmt_const_decl_iterator ZigClangDeclStmt_decl_end(const struct ZigClangDeclStmt *self);
895
849ZIG_EXTERN_C unsigned ZigClangAPFloat_convertToHexString(const struct ZigClangAPFloat *self, char *DST,896ZIG_EXTERN_C unsigned ZigClangAPFloat_convertToHexString(const struct ZigClangAPFloat *self, char *DST,
850 unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM);897 unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM);
851898
...@@ -855,4 +902,34 @@ ZIG_EXTERN_C const char *ZigClangStringLiteral_getString_bytes_begin_size(const...@@ -855,4 +902,34 @@ ZIG_EXTERN_C const char *ZigClangStringLiteral_getString_bytes_begin_size(const
855902
856ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName(903ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName(
857 const struct ZigClangPredefinedExpr *self);904 const struct ZigClangPredefinedExpr *self);
905
906ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangImplicitCastExpr_getBeginLoc(const struct ZigClangImplicitCastExpr *);
907ZIG_EXTERN_C enum ZigClangCK ZigClangImplicitCastExpr_getCastKind(const struct ZigClangImplicitCastExpr *);
908ZIG_EXTERN_C const struct ZigClangExpr *ZigClangImplicitCastExpr_getSubExpr(const struct ZigClangImplicitCastExpr *);
909
910ZIG_EXTERN_C struct ZigClangQualType ZigClangArrayType_getElementType(const struct ZigClangArrayType *);
911
912ZIG_EXTERN_C const struct ZigClangValueDecl *ZigClangDeclRefExpr_getDecl(const struct ZigClangDeclRefExpr *);
913
914ZIG_EXTERN_C struct ZigClangQualType ZigClangParenType_getInnerType(const struct ZigClangParenType *);
915
916ZIG_EXTERN_C struct ZigClangQualType ZigClangAttributedType_getEquivalentType(const struct ZigClangAttributedType *);
917
918ZIG_EXTERN_C struct ZigClangQualType ZigClangElaboratedType_getNamedType(const struct ZigClangElaboratedType *);
919
920ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangCStyleCastExpr_getBeginLoc(const struct ZigClangCStyleCastExpr *);
921ZIG_EXTERN_C const struct ZigClangExpr *ZigClangCStyleCastExpr_getSubExpr(const struct ZigClangCStyleCastExpr *);
922ZIG_EXTERN_C struct ZigClangQualType ZigClangCStyleCastExpr_getType(const struct ZigClangCStyleCastExpr *);
923
924ZIG_EXTERN_C bool ZigClangIntegerLiteral_EvaluateAsInt(const struct ZigClangIntegerLiteral *, struct ZigClangExprEvalResult *, const struct ZigClangASTContext *);
925ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangIntegerLiteral_getBeginLoc(const struct ZigClangIntegerLiteral *);
926
927ZIG_EXTERN_C const struct ZigClangExpr *ZigClangReturnStmt_getRetValue(const struct ZigClangReturnStmt *);
928
929ZIG_EXTERN_C enum ZigClangBO ZigClangBinaryOperator_getOpcode(const struct ZigClangBinaryOperator *);
930ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangBinaryOperator_getBeginLoc(const struct ZigClangBinaryOperator *);
931ZIG_EXTERN_C const struct ZigClangExpr *ZigClangBinaryOperator_getLHS(const struct ZigClangBinaryOperator *);
932ZIG_EXTERN_C const struct ZigClangExpr *ZigClangBinaryOperator_getRHS(const struct ZigClangBinaryOperator *);
933ZIG_EXTERN_C struct ZigClangQualType ZigClangBinaryOperator_getType(const struct ZigClangBinaryOperator *);
934
858#endif935#endif
test/translate_c.zig+85-25
...@@ -18,28 +18,80 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -18,28 +18,80 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
18 \\pub extern fn bar() c_int;18 \\pub extern fn bar() c_int;
19 );19 );
2020
21 cases.add_both("simple var decls",
22 \\void foo(void) {
23 \\ int a;
24 \\ char b = 123;
25 \\ const int c;
26 \\ const unsigned d = 440;
27 \\}
28 ,
29 \\pub fn foo() void {
30 \\ var a: c_int = undefined;
31 \\ var b: u8 = u8(123);
32 \\ const c: c_int = undefined;
33 \\ const d: c_uint = c_uint(440);
34 \\}
35 );
36
37 cases.add_both("ignore result, explicit function arguments",
38 \\void foo(void) {
39 \\ int a;
40 \\ 1;
41 \\ "hey";
42 \\ 1 + 1;
43 \\ 1 - 1;
44 \\ a = 1;
45 \\}
46 ,
47 \\pub fn foo() void {
48 \\ var a: c_int = undefined;
49 \\ _ = 1;
50 \\ _ = c"hey";
51 \\ _ = (1 + 1);
52 \\ _ = (1 - 1);
53 \\ a = 1;
54 \\}
55 );
56
21 /////////////// Cases that pass for only stage2 ////////////////57 /////////////// Cases that pass for only stage2 ////////////////
22 cases.add_2("Parameterless function prototypes",58 // TODO: restore these tests after removing "import mode" concept
59 // https://github.com/ziglang/zig/issues/2780
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",
23 \\void a() {}82 \\void a() {}
24 \\void b(void) {}83 \\void b(void) {}
25 \\void c();84 \\void c();
26 \\void d(void);85 \\void d(void);
27 ,86 ,
28 \\pub export fn a() void {}87 \\pub fn a(...) void {}
29 \\pub export fn b() void {}88 \\pub fn b() void {}
30 \\pub extern fn c(...) void;89 \\pub extern fn c(...) void;
31 \\pub extern fn d() void;90 \\pub extern fn d() void;
32 );91 );
3392
34 cases.add_2("simple function definition",
35 \\void foo(void) {}
36 \\static void bar(void) {}
37 ,
38 \\pub export fn foo() void {}
39 \\pub extern fn bar() void {}
40 );
41
42 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////93 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
94
43 cases.add("typedef of function in struct field",95 cases.add("typedef of function in struct field",
44 \\typedef void lws_callback_function(void);96 \\typedef void lws_callback_function(void);
45 \\struct Foo {97 \\struct Foo {
...@@ -47,9 +99,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -47,9 +99,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
47 \\ lws_callback_function *callback_http;99 \\ lws_callback_function *callback_http;
48 \\};100 \\};
49 ,101 ,
50 \\pub const lws_callback_function = extern fn() void;102 \\pub const lws_callback_function = extern fn () void;
51 \\pub const struct_Foo = extern struct {103 \\pub const struct_Foo = extern struct {
52 \\ func: ?extern fn() void,104 \\ func: ?extern fn () void,
53 \\ callback_http: ?lws_callback_function,105 \\ callback_http: ?lws_callback_function,
54 \\};106 \\};
55 );107 );
...@@ -68,13 +120,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -68,13 +120,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
68 \\};120 \\};
69 );121 );
70122
123 cases.add_both("simple function definition",
124 \\void foo(void) {}
125 \\static void bar(void) {}
126 ,
127 \\pub fn foo() void {}
128 \\pub fn bar() void {}
129 );
130
71 cases.add("macro with left shift",131 cases.add("macro with left shift",
72 \\#define REDISMODULE_READ (1<<0)132 \\#define REDISMODULE_READ (1<<0)
73 ,133 ,
74 \\pub const REDISMODULE_READ = 1 << 0;134 \\pub const REDISMODULE_READ = 1 << 0;
75 );135 );
76136
77 cases.add("casting pointers to ints and ints to pointers",137 cases.add_both("casting pointers to ints and ints to pointers",
78 \\void foo(void);138 \\void foo(void);
79 \\void bar(void) {139 \\void bar(void) {
80 \\ void *func_ptr = foo;140 \\ void *func_ptr = foo;
...@@ -84,7 +144,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -84,7 +144,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
84 \\pub extern fn foo() void;144 \\pub extern fn foo() void;
85 \\pub fn bar() void {145 \\pub fn bar() void {
86 \\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo);146 \\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo);
87 \\ var typed_func_ptr: ?extern fn() void = @intToPtr(?extern fn() void, c_ulong(@ptrToInt(func_ptr)));147 \\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, c_ulong(@ptrToInt(func_ptr)));
88 \\}148 \\}
89 );149 );
90150
...@@ -159,7 +219,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -159,7 +219,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
159 \\}219 \\}
160 );220 );
161221
162 cases.add("ignore result",222 cases.add("ignore result, no function arguments",
163 \\void foo() {223 \\void foo() {
164 \\ int a;224 \\ int a;
165 \\ 1;225 \\ 1;
...@@ -260,7 +320,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -260,7 +320,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
260 \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64) void;320 \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64) void;
261 );321 );
262322
263 cases.add("noreturn attribute",323 cases.add_both("noreturn attribute",
264 \\void foo(void) __attribute__((noreturn));324 \\void foo(void) __attribute__((noreturn));
265 ,325 ,
266 \\pub extern fn foo() noreturn;326 \\pub extern fn foo() noreturn;
...@@ -384,7 +444,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -384,7 +444,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
384 \\};444 \\};
385 ,445 ,
386 \\pub const struct_Foo = extern struct {446 \\pub const struct_Foo = extern struct {
387 \\ derp: ?extern fn([*c]struct_Foo) void,447 \\ derp: ?extern fn ([*c]struct_Foo) void,
388 \\};448 \\};
389 ,449 ,
390 \\pub const Foo = struct_Foo;450 \\pub const Foo = struct_Foo;
...@@ -467,13 +527,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -467,13 +527,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
467 \\extern char (*fn_ptr2)(int, float);527 \\extern char (*fn_ptr2)(int, float);
468 \\#define bar fn_ptr2528 \\#define bar fn_ptr2
469 ,529 ,
470 \\pub extern var fn_ptr: ?extern fn() void;530 \\pub extern var fn_ptr: ?extern fn () void;
471 ,531 ,
472 \\pub inline fn foo() void {532 \\pub inline fn foo() void {
473 \\ return fn_ptr.?();533 \\ return fn_ptr.?();
474 \\}534 \\}
475 ,535 ,
476 \\pub extern var fn_ptr2: ?extern fn(c_int, f32) u8;536 \\pub extern var fn_ptr2: ?extern fn (c_int, f32) u8;
477 ,537 ,
478 \\pub inline fn bar(arg0: c_int, arg1: f32) u8 {538 \\pub inline fn bar(arg0: c_int, arg1: f32) u8 {
479 \\ return fn_ptr2.?(arg0, arg1);539 \\ return fn_ptr2.?(arg0, arg1);
...@@ -489,7 +549,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -489,7 +549,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
489 cases.add("__cdecl doesn't mess up function pointers",549 cases.add("__cdecl doesn't mess up function pointers",
490 \\void foo(void (__cdecl *fn_ptr)(void));550 \\void foo(void (__cdecl *fn_ptr)(void));
491 ,551 ,
492 \\pub extern fn foo(fn_ptr: ?extern fn() void) void;552 \\pub extern fn foo(fn_ptr: ?extern fn () void) void;
493 );553 );
494554
495 cases.add("comment after integer literal",555 cases.add("comment after integer literal",
...@@ -1236,8 +1296,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1236,8 +1296,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1236 \\ return 0;1296 \\ return 0;
1237 \\}1297 \\}
1238 \\pub export fn bar() void {1298 \\pub export fn bar() void {
1239 \\ var f: ?extern fn() void = foo;1299 \\ var f: ?extern fn () void = foo;
1240 \\ var b: ?extern fn() c_int = baz;1300 \\ var b: ?extern fn () c_int = baz;
1241 \\ f.?();1301 \\ f.?();
1242 \\ f.?();1302 \\ f.?();
1243 \\ foo();1303 \\ foo();
...@@ -1372,9 +1432,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1372,9 +1432,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1372 ,1432 ,
1373 \\pub const GLbitfield = c_uint;1433 \\pub const GLbitfield = c_uint;
1374 ,1434 ,
1375 \\pub const PFNGLCLEARPROC = ?extern fn(GLbitfield) void;1435 \\pub const PFNGLCLEARPROC = ?extern fn (GLbitfield) void;
1376 ,1436 ,
1377 \\pub const OpenGLProc = ?extern fn() void;1437 \\pub const OpenGLProc = ?extern fn () void;
1378 ,1438 ,
1379 \\pub const union_OpenGLProcs = extern union {1439 \\pub const union_OpenGLProcs = extern union {
1380 \\ ptr: [1]OpenGLProc,1440 \\ ptr: [1]OpenGLProc,