@@ -328,6 +328,16 @@ pub const Context = struct {
328328
329329 pattern_list : PatternList ,
330330
331+ /// This is used to emit different code depending on whether
332+ /// the output zig source code is intended to be compiled with stage1 or stage2.
333+ /// Ideally we will have stage1 and stage2 support the exact same Zig language,
334+ /// but for now they diverge because I would rather focus on finishing and shipping
335+ /// stage2 than implementing the features in stage1.
336+ /// The list of differences are currently:
337+ /// * function pointers in stage1 are e.g. `fn()void`
338+ /// but in stage2 they are `*const fn()void`.
339+ zig_is_stage1 : bool ,
340+
331341 fn getMangle (c : * Context ) u32 {
332342 c .mangle_count += 1 ;
333343 return c .mangle_count ;
@@ -356,6 +366,7 @@ pub fn translate(
356366 args_end : [* ]? [* ]const u8 ,
357367 errors : * []ClangErrMsg ,
358368 resources_path : [* :0 ]const u8 ,
369+ zig_is_stage1 : bool ,
359370) ! std.zig.Ast {
360371 const ast_unit = clang .LoadFromCommandLine (
361372 args_begin ,
@@ -383,6 +394,7 @@ pub fn translate(
383394 .global_scope = try arena_allocator .create (Scope .Root ),
384395 .clang_context = ast_unit .getASTContext (),
385396 .pattern_list = try PatternList .init (gpa ),
397+ .zig_is_stage1 = zig_is_stage1 ,
386398 };
387399 context .global_scope .* = Scope .Root .init (& context );
388400 defer {
@@ -3630,7 +3642,7 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat
36303642 else
36313643 return transCreatePreCrement (c , scope , stmt , .sub_assign , used ),
36323644 .AddrOf = > {
3633- if (cIsFunctionDeclRef (op_expr )) {
3645+ if (c . zig_is_stage1 and cIsFunctionDeclRef (op_expr )) {
36343646 return transExpr (c , scope , op_expr , used );
36353647 }
36363648 return Tag .address_of .create (c .arena , try transExpr (c , scope , op_expr , used ));
@@ -4656,18 +4668,27 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan
46564668 },
46574669 .Pointer = > {
46584670 const child_qt = ty .getPointeeType ();
4659- if (qualTypeChildIsFnProto (child_qt )) {
4671+ const is_fn_proto = qualTypeChildIsFnProto (child_qt );
4672+ if (c .zig_is_stage1 and is_fn_proto ) {
46604673 return Tag .optional_type .create (c .arena , try transQualType (c , scope , child_qt , source_loc ));
46614674 }
4662- const is_const = child_qt .isConstQualified ();
4675+ const is_const = is_fn_proto or child_qt .isConstQualified ();
46634676 const is_volatile = child_qt .isVolatileQualified ();
46644677 const elem_type = try transQualType (c , scope , child_qt , source_loc );
4665- if (typeIsOpaque (c , child_qt .getTypePtr (), source_loc ) or qualTypeWasDemotedToOpaque (c , child_qt )) {
4666- const ptr = try Tag .single_pointer .create (c .arena , .{ .is_const = is_const , .is_volatile = is_volatile , .elem_type = elem_type });
4678+ const ptr_info = .{
4679+ .is_const = is_const ,
4680+ .is_volatile = is_volatile ,
4681+ .elem_type = elem_type ,
4682+ };
4683+ if (is_fn_proto or
4684+ typeIsOpaque (c , child_qt .getTypePtr (), source_loc ) or
4685+ qualTypeWasDemotedToOpaque (c , child_qt ))
4686+ {
4687+ const ptr = try Tag .single_pointer .create (c .arena , ptr_info );
46674688 return Tag .optional_type .create (c .arena , ptr );
46684689 }
46694690
4670- return Tag .c_pointer .create (c .arena , .{ . is_const = is_const , . is_volatile = is_volatile , . elem_type = elem_type } );
4691+ return Tag .c_pointer .create (c .arena , ptr_info );
46714692 },
46724693 .ConstantArray = > {
46734694 const const_arr_ty = @ptrCast (* const clang .ConstantArrayType , ty );
@@ -6517,8 +6538,16 @@ fn getFnProto(c: *Context, ref: Node) ?*ast.Payload.Func {
65176538 return null ;
65186539 if (getContainerTypeOf (c , init )) | ty_node | {
65196540 if (ty_node .castTag (.optional_type )) | prefix | {
6520- if (prefix .data .castTag (.func )) | fn_proto | {
6521- return fn_proto ;
6541+ if (c .zig_is_stage1 ) {
6542+ if (prefix .data .castTag (.func )) | fn_proto | {
6543+ return fn_proto ;
6544+ }
6545+ } else {
6546+ if (prefix .data .castTag (.single_pointer )) | sp | {
6547+ if (sp .data .elem_type .castTag (.func )) | fn_proto | {
6548+ return fn_proto ;
6549+ }
6550+ }
65226551 }
65236552 }
65246553 }
0 commit comments