authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-15 22:15:53-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-15 22:19:54-04:00
log6fe3b209620a340da536da4c9f3d07e0e6051840
tree869081c3e7593e44ae947770000f8fbee7141a34
parent3f4abe97bdbe666dbb3532c14a97e414aae4caca
parent0e38f7215bede51b2ad3b8574e8b472c279d3db4
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'translate-c-userland' of https://github.com/hryx/zig into hryx-translate-c-userland


6 files changed, 1223 insertions(+), 44 deletions(-)

src-self-hosted/clang.zig+78-1
......@@ -1,4 +1,5 @@
1pub const struct_ZigClangAPValue = @OpaqueType();
1const builtin = @import("builtin");
2
23pub const struct_ZigClangAPSInt = @OpaqueType();
34pub const struct_ZigClangAPFloat = @OpaqueType();
45pub const struct_ZigClangASTContext = @OpaqueType();
......@@ -723,6 +724,7 @@ pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: str
723724pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) ?*const struct_ZigClangTypedefNameDecl;
724725pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(self: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType;
725726pub extern fn ZigClangQualType_getCanonicalType(self: struct_ZigClangQualType) struct_ZigClangQualType;
727pub extern fn ZigClangQualType_getTypeClass(self: struct_ZigClangQualType) ZigClangTypeClass;
726728pub extern fn ZigClangQualType_getTypePtr(self: struct_ZigClangQualType) *const struct_ZigClangType;
727729pub extern fn ZigClangQualType_addConst(self: [*c]struct_ZigClangQualType) void;
728730pub extern fn ZigClangQualType_eq(self: struct_ZigClangQualType, arg1: struct_ZigClangQualType) bool;
......@@ -730,6 +732,7 @@ pub extern fn ZigClangQualType_isConstQualified(self: struct_ZigClangQualType) b
730732pub extern fn ZigClangQualType_isVolatileQualified(self: struct_ZigClangQualType) bool;
731733pub extern fn ZigClangQualType_isRestrictQualified(self: struct_ZigClangQualType) bool;
732734pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass;
735pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) struct_ZigClangQualType;
733736pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
734737pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*]const u8;
735738pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;
......@@ -894,3 +897,77 @@ pub const ZigClangCompoundStmt_const_body_iterator = [*c]const *struct_ZigClangS
894897
895898pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
896899pub 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;
2020
2121pub const Error = error{OutOfMemory};
2222const TypeError = Error || error{UnsupportedType};
23const TransError = Error || error{UnsupportedTranslation};
23const TransError = TypeError || error{UnsupportedTranslation};
2424
2525const DeclTable = std.HashMap(usize, void, addrHash, addrEql);
2626
......@@ -107,6 +107,8 @@ const Context = struct {
107107 decl_table: DeclTable,
108108 global_scope: *Scope.Root,
109109 mode: Mode,
110 ptr_params: std.BufSet,
111 clang_context: *ZigClangASTContext,
110112
111113 fn a(c: *Context) *std.mem.Allocator {
112114 return &c.tree.arena_allocator.allocator;
......@@ -183,6 +185,8 @@ pub fn translate(
183185 .decl_table = DeclTable.init(arena),
184186 .global_scope = try arena.create(Scope.Root),
185187 .mode = mode,
188 .ptr_params = std.BufSet.init(arena),
189 .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
186190 };
187191 context.global_scope.* = Scope.Root{
188192 .base = Scope{
......@@ -195,7 +199,7 @@ pub fn translate(
195199 return context.err;
196200 }
197201
198 _ = try appendToken(&context, .Eof, "");
202 tree.root_node.eof_token = try appendToken(&context, .Eof, "");
199203 tree.source = source_buffer.toOwnedSlice();
200204 if (false) {
201205 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 {
257261 .storage_class = storage_class,
258262 .scope = &scope,
259263 .is_export = switch (storage_class) {
260 .None => has_body,
264 .None => has_body and c.mode != .import,
261265 .Extern, .Static => false,
262266 .PrivateExtern => return failDecl(c, fn_decl_loc, fn_name, "unsupported storage class: private extern"),
263267 .Auto => unreachable, // Not legal on functions
......@@ -267,7 +271,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
267271 const proto_node = switch (ZigClangType_getTypeClass(fn_type)) {
268272 .FunctionProto => blk: {
269273 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) {
271275 error.UnsupportedType => {
272276 return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function");
273277 },
......@@ -276,7 +280,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
276280 },
277281 .FunctionNoProto => blk: {
278282 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) {
280284 error.UnsupportedType => {
281285 return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function");
282286 },
......@@ -295,7 +299,9 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
295299 const body_stmt = ZigClangFunctionDecl_getBody(fn_decl);
296300 const result = transStmt(rp, scope, body_stmt, .unused, .r_value) catch |err| switch (err) {
297301 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"),
299305 };
300306 assert(result.node.id == ast.Node.Id.Block);
301307 proto_node.body_node = result.node;
......@@ -322,7 +328,15 @@ fn transStmt(
322328) !TransResult {
323329 const sc = ZigClangStmt_getStmtClass(stmt);
324330 switch (sc) {
331 .BinaryOperatorClass => return transBinaryOperator(rp, scope, @ptrCast(*const ZigClangBinaryOperator, stmt), result_used),
325332 .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),
326340 else => {
327341 return revertAndWarn(
328342 rp,
......@@ -335,6 +349,87 @@ fn transStmt(
335349 }
336350}
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
338433fn transCompoundStmtInline(
339434 rp: RestorePoint,
340435 parent_scope: *Scope,
......@@ -345,9 +440,10 @@ fn transCompoundStmtInline(
345440 const end_it = ZigClangCompoundStmt_body_end(stmt);
346441 var scope = parent_scope;
347442 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);
349444 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);
351447 }
352448 return TransResult{
353449 .node = &block_node.base,
......@@ -368,6 +464,427 @@ fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompo
368464 };
369465}
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
371888fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void {
372889 try c.tree.root_node.decls.push(decl_node);
373890}
......@@ -376,11 +893,263 @@ fn transQualType(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSou
376893 return transType(rp, ZigClangQualType_getTypePtr(qt), source_loc);
377894}
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
379914fn qualTypeCanon(qt: ZigClangQualType) *const ZigClangType {
380915 const canon = ZigClangQualType_getCanonicalType(qt);
381916 return ZigClangQualType_getTypePtr(canon);
382917}
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
3841153const RestorePoint = struct {
3851154 c: *Context,
3861155 token_index: ast.TokenIndex,
......@@ -429,9 +1198,43 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
4291198 },
4301199 .FunctionProto => {
4311200 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);
4331202 return &fn_proto.base;
4341203 },
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 },
4351238 else => {
4361239 const type_name = rp.c.str(ZigClangType_getTypeClassName(ty));
4371240 return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported type: '{}'", type_name);
......@@ -465,6 +1268,7 @@ fn transFnProto(
4651268 fn_proto_ty: *const ZigClangFunctionProtoType,
4661269 source_loc: ZigClangSourceLocation,
4671270 fn_decl_context: ?FnDeclContext,
1271 is_pub: bool,
4681272) !*ast.Node.FnProto {
4691273 const fn_ty = @ptrCast(*const ZigClangFunctionType, fn_proto_ty);
4701274 const cc = try transCC(rp, fn_ty, source_loc);
......@@ -475,7 +1279,7 @@ fn transFnProto(
4751279 return revertAndWarn(rp, error.UnsupportedType, source_loc, "TODO: implement parameters for FunctionProto in transType");
4761280 }
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);
4791283}
4801284
4811285fn transFnNoProto(
......@@ -483,10 +1287,11 @@ fn transFnNoProto(
4831287 fn_ty: *const ZigClangFunctionType,
4841288 source_loc: ZigClangSourceLocation,
4851289 fn_decl_context: ?FnDeclContext,
1290 is_pub: bool,
4861291) !*ast.Node.FnProto {
4871292 const cc = try transCC(rp, fn_ty, source_loc);
4881293 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);
4901295}
4911296
4921297fn finishTransFnProto(
......@@ -496,18 +1301,20 @@ fn finishTransFnProto(
4961301 fn_decl_context: ?FnDeclContext,
4971302 is_var_args: bool,
4981303 cc: CallingConvention,
1304 is_pub: bool,
4991305) !*ast.Node.FnProto {
5001306 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
5021309 // TODO check for always_inline attribute
5031310 // TODO check for align attribute
5041311
5051312 // 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;
5071314 const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null;
5081315 const extern_export_inline_tok = if (is_export)
5091316 try appendToken(rp.c, .Keyword_export, "export")
510 else if (cc == .C)
1317 else if (cc == .C and is_extern)
5111318 try appendToken(rp.c, .Keyword_extern, "extern")
5121319 else
5131320 null;
......@@ -657,7 +1464,7 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8,
6571464 .start = start_index,
6581465 .end = end_index,
6591466 };
660 try c.source_buffer.appendByte('\n');
1467 try c.source_buffer.appendByte(' ');
6611468
6621469 return token_index;
6631470}
src/ast_render.cpp+1-2
......@@ -444,9 +444,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
444444 const char *extern_str = extern_string(node->data.fn_proto.is_extern);
445445 const char *export_str = export_string(node->data.fn_proto.is_export);
446446 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);
448448 if (node->data.fn_proto.name != nullptr) {
449 fprintf(ar->f, " ");
450449 print_symbol(ar, node->data.fn_proto.name);
451450 }
452451 fprintf(ar->f, "(");
src/zig_clang.cpp+160-1
......@@ -21,6 +21,7 @@
2121
2222#include <clang/Frontend/ASTUnit.h>
2323#include <clang/Frontend/CompilerInstance.h>
24#include <clang/AST/APValue.h>
2425#include <clang/AST/Expr.h>
2526
2627#if __GNUC__ >= 8
......@@ -1287,6 +1288,20 @@ static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind
12871288static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_UTF16 == clang::StringLiteral::UTF16, "");
12881289static_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
12911306static_assert(sizeof(ZigClangSourceLocation) == sizeof(clang::SourceLocation), "");
12921307static ZigClangSourceLocation bitcast(clang::SourceLocation src) {
......@@ -1312,6 +1327,13 @@ static clang::QualType bitcast(ZigClangQualType src) {
13121327 return dest;
13131328}
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
13151337static_assert(sizeof(ZigClangAPValueLValueBase) == sizeof(clang::APValue::LValueBase), "");
13161338static ZigClangAPValueLValueBase bitcast(clang::APValue::LValueBase src) {
13171339 ZigClangAPValueLValueBase dest;
......@@ -1331,6 +1353,12 @@ static ZigClangCompoundStmt_const_body_iterator bitcast(clang::CompoundStmt::con
13311353 return dest;
13321354}
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
13351363ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const ZigClangSourceManager *self,
13361364 ZigClangSourceLocation Loc)
......@@ -1381,7 +1409,7 @@ ZigClangSourceManager *ZigClangASTUnit_getSourceManager(ZigClangASTUnit *self) {
13811409 return reinterpret_cast<ZigClangSourceManager *>(result);
13821410}
13831411
1384bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *self, void *context,
1412bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *self, void *context,
13851413 bool (*Fn)(void *context, const ZigClangDecl *decl))
13861414{
13871415 return reinterpret_cast<clang::ASTUnit *>(self)->visitLocalTopLevelDecls(context,
......@@ -1540,6 +1568,11 @@ const ZigClangType *ZigClangQualType_getTypePtr(ZigClangQualType self) {
15401568 return reinterpret_cast<const ZigClangType *>(ty);
15411569}
15421570
1571ZigClangTypeClass ZigClangQualType_getTypeClass(ZigClangQualType self) {
1572 clang::QualType ty = bitcast(self);
1573 return (ZigClangTypeClass)(ty->getTypeClass());
1574}
1575
15431576void ZigClangQualType_addConst(ZigClangQualType *self) {
15441577 reinterpret_cast<clang::QualType *>(self)->addConst();
15451578}
......@@ -1815,6 +1848,21 @@ void ZigClangASTUnit_delete(struct ZigClangASTUnit *self) {
18151848 delete reinterpret_cast<clang::ASTUnit *>(self);
18161849}
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
18181866enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBuiltinType *self) {
18191867 auto casted = reinterpret_cast<const clang::BuiltinType *>(self);
18201868 return (ZigClangBuiltinTypeKind)casted->getKind();
......@@ -1862,6 +1910,16 @@ ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_end(const str
18621910 return bitcast(casted->body_end());
18631911}
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
18651923unsigned ZigClangAPFloat_convertToHexString(const ZigClangAPFloat *self, char *DST,
18661924 unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM)
18671925{
......@@ -1888,3 +1946,104 @@ const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName(
18881946 const clang::StringLiteral *result = casted->getFunctionName();
18891947 return reinterpret_cast<const struct ZigClangStringLiteral *>(result);
18901948}
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 {
3030 unsigned Version;
3131};
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
3365struct ZigClangAPValue;
3466struct ZigClangAPSInt;
3567struct ZigClangAPFloat;
......@@ -105,6 +137,7 @@ struct ZigClangFunctionType;
105137struct ZigClangPredefinedExpr;
106138
107139typedef struct ZigClangStmt *const * ZigClangCompoundStmt_const_body_iterator;
140typedef struct ZigClangDecl *const * ZigClangDeclStmt_const_decl_iterator;
108141
109142enum ZigClangBO {
110143 ZigClangBO_PtrMemD,
......@@ -732,6 +765,12 @@ enum ZigClangStringLiteral_StringKind {
732765 ZigClangStringLiteral_StringKind_UTF32,
733766};
734767
768enum ZigClangVarDecl_TLSKind {
769 ZigClangVarDecl_TLSKind_None,
770 ZigClangVarDecl_TLSKind_Static,
771 ZigClangVarDecl_TLSKind_Dynamic,
772};
773
735774ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const struct ZigClangSourceManager *,
736775 struct ZigClangSourceLocation Loc);
737776ZIG_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
754793
755794ZIG_EXTERN_C struct ZigClangASTContext *ZigClangASTUnit_getASTContext(struct ZigClangASTUnit *);
756795ZIG_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,
758797 bool (*Fn)(void *context, const struct ZigClangDecl *decl));
759798
760799ZIG_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
789828ZIG_EXTERN_C enum ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *decl);
790829ZIG_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
792835ZIG_EXTERN_C bool ZigClangSourceLocation_eq(struct ZigClangSourceLocation a, struct ZigClangSourceLocation b);
793836
794837ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const struct ZigClangTypedefType *);
......@@ -796,6 +839,7 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangTypedefNameDecl_getUnderlyingType(c
796839
797840ZIG_EXTERN_C struct ZigClangQualType ZigClangQualType_getCanonicalType(struct ZigClangQualType);
798841ZIG_EXTERN_C const struct ZigClangType *ZigClangQualType_getTypePtr(struct ZigClangQualType);
842ZIG_EXTERN_C enum ZigClangTypeClass ZigClangQualType_getTypeClass(struct ZigClangQualType);
799843ZIG_EXTERN_C void ZigClangQualType_addConst(struct ZigClangQualType *);
800844ZIG_EXTERN_C bool ZigClangQualType_eq(struct ZigClangQualType, struct ZigClangQualType);
801845ZIG_EXTERN_C bool ZigClangQualType_isConstQualified(struct ZigClangQualType);
......@@ -846,6 +890,9 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionProtoType_getParamType(cons
846890ZIG_EXTERN_C ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_begin(const struct ZigClangCompoundStmt *self);
847891ZIG_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
849896ZIG_EXTERN_C unsigned ZigClangAPFloat_convertToHexString(const struct ZigClangAPFloat *self, char *DST,
850897 unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM);
851898
......@@ -855,4 +902,34 @@ ZIG_EXTERN_C const char *ZigClangStringLiteral_getString_bytes_begin_size(const
855902
856903ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName(
857904 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
858935#endif
test/translate_c.zig+85-25
......@@ -18,28 +18,80 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1818 \\pub extern fn bar() c_int;
1919 );
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
2157 /////////////// 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",
2382 \\void a() {}
2483 \\void b(void) {}
2584 \\void c();
2685 \\void d(void);
2786 ,
28 \\pub export fn a() void {}
29 \\pub export fn b() void {}
87 \\pub fn a(...) void {}
88 \\pub fn b() void {}
3089 \\pub extern fn c(...) void;
3190 \\pub extern fn d() void;
3291 );
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
4293 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
94
4395 cases.add("typedef of function in struct field",
4496 \\typedef void lws_callback_function(void);
4597 \\struct Foo {
......@@ -47,9 +99,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
4799 \\ lws_callback_function *callback_http;
48100 \\};
49101 ,
50 \\pub const lws_callback_function = extern fn() void;
102 \\pub const lws_callback_function = extern fn () void;
51103 \\pub const struct_Foo = extern struct {
52 \\ func: ?extern fn() void,
104 \\ func: ?extern fn () void,
53105 \\ callback_http: ?lws_callback_function,
54106 \\};
55107 );
......@@ -68,13 +120,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
68120 \\};
69121 );
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
71131 cases.add("macro with left shift",
72132 \\#define REDISMODULE_READ (1<<0)
73133 ,
74134 \\pub const REDISMODULE_READ = 1 << 0;
75135 );
76136
77 cases.add("casting pointers to ints and ints to pointers",
137 cases.add_both("casting pointers to ints and ints to pointers",
78138 \\void foo(void);
79139 \\void bar(void) {
80140 \\ void *func_ptr = foo;
......@@ -84,7 +144,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
84144 \\pub extern fn foo() void;
85145 \\pub fn bar() void {
86146 \\ 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)));
88148 \\}
89149 );
90150
......@@ -159,7 +219,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
159219 \\}
160220 );
161221
162 cases.add("ignore result",
222 cases.add("ignore result, no function arguments",
163223 \\void foo() {
164224 \\ int a;
165225 \\ 1;
......@@ -260,7 +320,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
260320 \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64) void;
261321 );
262322
263 cases.add("noreturn attribute",
323 cases.add_both("noreturn attribute",
264324 \\void foo(void) __attribute__((noreturn));
265325 ,
266326 \\pub extern fn foo() noreturn;
......@@ -384,7 +444,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
384444 \\};
385445 ,
386446 \\pub const struct_Foo = extern struct {
387 \\ derp: ?extern fn([*c]struct_Foo) void,
447 \\ derp: ?extern fn ([*c]struct_Foo) void,
388448 \\};
389449 ,
390450 \\pub const Foo = struct_Foo;
......@@ -467,13 +527,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
467527 \\extern char (*fn_ptr2)(int, float);
468528 \\#define bar fn_ptr2
469529 ,
470 \\pub extern var fn_ptr: ?extern fn() void;
530 \\pub extern var fn_ptr: ?extern fn () void;
471531 ,
472532 \\pub inline fn foo() void {
473533 \\ return fn_ptr.?();
474534 \\}
475535 ,
476 \\pub extern var fn_ptr2: ?extern fn(c_int, f32) u8;
536 \\pub extern var fn_ptr2: ?extern fn (c_int, f32) u8;
477537 ,
478538 \\pub inline fn bar(arg0: c_int, arg1: f32) u8 {
479539 \\ return fn_ptr2.?(arg0, arg1);
......@@ -489,7 +549,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
489549 cases.add("__cdecl doesn't mess up function pointers",
490550 \\void foo(void (__cdecl *fn_ptr)(void));
491551 ,
492 \\pub extern fn foo(fn_ptr: ?extern fn() void) void;
552 \\pub extern fn foo(fn_ptr: ?extern fn () void) void;
493553 );
494554
495555 cases.add("comment after integer literal",
......@@ -1236,8 +1296,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
12361296 \\ return 0;
12371297 \\}
12381298 \\pub export fn bar() void {
1239 \\ var f: ?extern fn() void = foo;
1240 \\ var b: ?extern fn() c_int = baz;
1299 \\ var f: ?extern fn () void = foo;
1300 \\ var b: ?extern fn () c_int = baz;
12411301 \\ f.?();
12421302 \\ f.?();
12431303 \\ foo();
......@@ -1372,9 +1432,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
13721432 ,
13731433 \\pub const GLbitfield = c_uint;
13741434 ,
1375 \\pub const PFNGLCLEARPROC = ?extern fn(GLbitfield) void;
1435 \\pub const PFNGLCLEARPROC = ?extern fn (GLbitfield) void;
13761436 ,
1377 \\pub const OpenGLProc = ?extern fn() void;
1437 \\pub const OpenGLProc = ?extern fn () void;
13781438 ,
13791439 \\pub const union_OpenGLProcs = extern union {
13801440 \\ ptr: [1]OpenGLProc,