Merge pull request #3896 from Vexu/translate-c-2
Translate-c self-hosted var decl and remove translate modemaster
commit
21a85d4fb6
|
@ -1,5 +1,6 @@
|
|||
const builtin = @import("builtin");
|
||||
|
||||
pub const struct_ZigClangAPInt = @OpaqueType();
|
||||
pub const struct_ZigClangAPSInt = @OpaqueType();
|
||||
pub const struct_ZigClangAPFloat = @OpaqueType();
|
||||
pub const struct_ZigClangASTContext = @OpaqueType();
|
||||
|
@ -73,6 +74,7 @@ pub const struct_ZigClangVarDecl = @OpaqueType();
|
|||
pub const struct_ZigClangWhileStmt = @OpaqueType();
|
||||
pub const struct_ZigClangFunctionType = @OpaqueType();
|
||||
pub const struct_ZigClangPredefinedExpr = @OpaqueType();
|
||||
pub const struct_ZigClangInitListExpr = @OpaqueType();
|
||||
|
||||
pub const ZigClangBO = extern enum {
|
||||
PtrMemD,
|
||||
|
@ -733,7 +735,7 @@ pub extern fn ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl: ?*const s
|
|||
pub extern fn ZigClangEnumDecl_getIntegerType(self: ?*const struct_ZigClangEnumDecl) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangDecl_getName_bytes_begin(decl: ?*const struct_ZigClangDecl) [*c]const u8;
|
||||
pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: struct_ZigClangSourceLocation) bool;
|
||||
pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) ?*const struct_ZigClangTypedefNameDecl;
|
||||
pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) *const struct_ZigClangTypedefNameDecl;
|
||||
pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(self: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangQualType_getCanonicalType(self: struct_ZigClangQualType) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangQualType_getTypeClass(self: struct_ZigClangQualType) ZigClangTypeClass;
|
||||
|
@ -747,17 +749,19 @@ pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigCl
|
|||
pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
|
||||
pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*:0]const u8;
|
||||
pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType;
|
||||
pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;
|
||||
pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;
|
||||
pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;
|
||||
pub extern fn ZigClangExpr_getStmtClass(self: ?*const struct_ZigClangExpr) ZigClangStmtClass;
|
||||
pub extern fn ZigClangExpr_getType(self: ?*const struct_ZigClangExpr) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;
|
||||
pub extern fn ZigClangInitListExpr_getInit(self: ?*const struct_ZigClangInitListExpr, i: c_uint) *const ZigClangExpr;
|
||||
pub extern fn ZigClangInitListExpr_getArrayFiller(self: ?*const struct_ZigClangInitListExpr) *const ZigClangExpr;
|
||||
pub extern fn ZigClangInitListExpr_getNumInits(self: ?*const struct_ZigClangInitListExpr) c_uint;
|
||||
pub extern fn ZigClangAPValue_getKind(self: ?*const struct_ZigClangAPValue) ZigClangAPValueKind;
|
||||
pub extern fn ZigClangAPValue_getInt(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPSInt;
|
||||
pub extern fn ZigClangAPValue_getArrayInitializedElts(self: ?*const struct_ZigClangAPValue) c_uint;
|
||||
pub extern fn ZigClangAPValue_getArrayInitializedElt(self: ?*const struct_ZigClangAPValue, i: c_uint) ?*const struct_ZigClangAPValue;
|
||||
pub extern fn ZigClangAPValue_getArrayFiller(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPValue;
|
||||
pub extern fn ZigClangAPValue_getArraySize(self: ?*const struct_ZigClangAPValue) c_uint;
|
||||
pub extern fn ZigClangAPValue_getLValueBase(self: ?*const struct_ZigClangAPValue) struct_ZigClangAPValueLValueBase;
|
||||
pub extern fn ZigClangAPSInt_isSigned(self: ?*const struct_ZigClangAPSInt) bool;
|
||||
|
@ -766,6 +770,8 @@ pub extern fn ZigClangAPSInt_negate(self: ?*const struct_ZigClangAPSInt) ?*const
|
|||
pub extern fn ZigClangAPSInt_free(self: ?*const struct_ZigClangAPSInt) void;
|
||||
pub extern fn ZigClangAPSInt_getRawData(self: ?*const struct_ZigClangAPSInt) [*c]const u64;
|
||||
pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_uint;
|
||||
|
||||
pub extern fn ZigClangAPInt_getLimitedValue(self: *const struct_ZigClangAPInt, limit: u64) u64;
|
||||
pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr;
|
||||
pub extern fn ZigClangASTUnit_delete(self: ?*struct_ZigClangASTUnit) void;
|
||||
|
||||
|
@ -863,6 +869,7 @@ pub const ZigClangVarDecl = struct_ZigClangVarDecl;
|
|||
pub const ZigClangWhileStmt = struct_ZigClangWhileStmt;
|
||||
pub const ZigClangFunctionType = struct_ZigClangFunctionType;
|
||||
pub const ZigClangPredefinedExpr = struct_ZigClangPredefinedExpr;
|
||||
pub const ZigClangInitListExpr = struct_ZigClangInitListExpr;
|
||||
|
||||
pub const struct_ZigClangSourceLocation = extern struct {
|
||||
ID: c_uint,
|
||||
|
@ -916,6 +923,9 @@ pub const ZigClangDeclStmt_const_decl_iterator = [*c]const *struct_ZigClangDecl;
|
|||
pub extern fn ZigClangDeclStmt_decl_begin(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator;
|
||||
pub extern fn ZigClangDeclStmt_decl_end(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator;
|
||||
|
||||
pub extern fn ZigClangVarDecl_getLocation(self: *const struct_ZigClangVarDecl) ZigClangSourceLocation;
|
||||
pub extern fn ZigClangVarDecl_hasInit(self: *const struct_ZigClangVarDecl) bool;
|
||||
pub extern fn ZigClangVarDecl_getStorageClass(self: *const ZigClangVarDecl) ZigClangStorageClass;
|
||||
pub extern fn ZigClangVarDecl_getType(self: ?*const struct_ZigClangVarDecl) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangVarDecl_getInit(*const ZigClangVarDecl) ?*const ZigClangExpr;
|
||||
pub extern fn ZigClangVarDecl_getTLSKind(self: ?*const struct_ZigClangVarDecl) ZigClangVarDecl_TLSKind;
|
||||
|
@ -930,7 +940,10 @@ pub extern fn ZigClangImplicitCastExpr_getCastKind(*const ZigClangImplicitCastEx
|
|||
pub extern fn ZigClangImplicitCastExpr_getSubExpr(*const ZigClangImplicitCastExpr) *const ZigClangExpr;
|
||||
|
||||
pub extern fn ZigClangArrayType_getElementType(*const ZigClangArrayType) ZigClangQualType;
|
||||
pub extern fn ZigClangIncompleteArrayType_getElementType(*const ZigClangIncompleteArrayType) ZigClangQualType;
|
||||
|
||||
pub extern fn ZigClangConstantArrayType_getElementType(self: *const struct_ZigClangConstantArrayType) ZigClangQualType;
|
||||
pub extern fn ZigClangConstantArrayType_getSize(self: *const struct_ZigClangConstantArrayType) *const struct_ZigClangAPInt;
|
||||
pub extern fn ZigClangDeclRefExpr_getDecl(*const ZigClangDeclRefExpr) *const ZigClangValueDecl;
|
||||
|
||||
pub extern fn ZigClangParenType_getInnerType(*const ZigClangParenType) ZigClangQualType;
|
||||
|
@ -957,6 +970,7 @@ pub const struct_ZigClangAPValue = extern struct {
|
|||
Kind: ZigClangAPValueKind,
|
||||
Data: if (builtin.os == .windows and builtin.abi == .msvc) [52]u8 else [68]u8,
|
||||
};
|
||||
pub extern fn ZigClangVarDecl_getTypeSourceInfo_getType(self: *const struct_ZigClangVarDecl) struct_ZigClangQualType;
|
||||
|
||||
pub extern fn ZigClangIntegerLiteral_EvaluateAsInt(*const ZigClangIntegerLiteral, *ZigClangExprEvalResult, *const ZigClangASTContext) bool;
|
||||
pub extern fn ZigClangIntegerLiteral_getBeginLoc(*const ZigClangIntegerLiteral) ZigClangSourceLocation;
|
||||
|
|
|
@ -33,12 +33,6 @@ export fn stage2_panic(ptr: [*]const u8, len: usize) void {
|
|||
@panic(ptr[0..len]);
|
||||
}
|
||||
|
||||
// ABI warning
|
||||
const TranslateMode = extern enum {
|
||||
import,
|
||||
translate,
|
||||
};
|
||||
|
||||
// ABI warning
|
||||
const Error = extern enum {
|
||||
None,
|
||||
|
@ -99,14 +93,10 @@ export fn stage2_translate_c(
|
|||
out_errors_len: *usize,
|
||||
args_begin: [*]?[*]const u8,
|
||||
args_end: [*]?[*]const u8,
|
||||
mode: TranslateMode,
|
||||
resources_path: [*]const u8,
|
||||
) Error {
|
||||
var errors: []translate_c.ClangErrMsg = undefined;
|
||||
out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, switch (mode) {
|
||||
.import => translate_c.Mode.import,
|
||||
.translate => translate_c.Mode.translate,
|
||||
}, &errors, resources_path) catch |err| switch (err) {
|
||||
out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) {
|
||||
error.SemanticAnalyzeFail => {
|
||||
out_errors_ptr.* = errors.ptr;
|
||||
out_errors_len.* = errors.len;
|
||||
|
|
|
@ -7,11 +7,6 @@ const ast = std.zig.ast;
|
|||
const Token = std.zig.Token;
|
||||
usingnamespace @import("clang.zig");
|
||||
|
||||
pub const Mode = enum {
|
||||
import,
|
||||
translate,
|
||||
};
|
||||
|
||||
const CallingConvention = std.builtin.TypeInfo.CallingConvention;
|
||||
|
||||
pub const ClangErrMsg = Stage2ErrorMsg;
|
||||
|
@ -104,7 +99,6 @@ const Context = struct {
|
|||
source_manager: *ZigClangSourceManager,
|
||||
decl_table: DeclTable,
|
||||
global_scope: *Scope.Root,
|
||||
mode: Mode,
|
||||
ptr_params: std.BufSet,
|
||||
clang_context: *ZigClangASTContext,
|
||||
|
||||
|
@ -133,7 +127,6 @@ pub fn translate(
|
|||
backing_allocator: *std.mem.Allocator,
|
||||
args_begin: [*]?[*]const u8,
|
||||
args_end: [*]?[*]const u8,
|
||||
mode: Mode,
|
||||
errors: *[]ClangErrMsg,
|
||||
resources_path: [*]const u8,
|
||||
) !*ast.Tree {
|
||||
|
@ -185,7 +178,6 @@ pub fn translate(
|
|||
.err = undefined,
|
||||
.decl_table = DeclTable.init(arena),
|
||||
.global_scope = try arena.create(Scope.Root),
|
||||
.mode = mode,
|
||||
.ptr_params = std.BufSet.init(arena),
|
||||
.clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
|
||||
};
|
||||
|
@ -228,7 +220,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
|
|||
return visitFnDecl(c, @ptrCast(*const ZigClangFunctionDecl, decl));
|
||||
},
|
||||
.Typedef => {
|
||||
try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for typedefs", .{});
|
||||
try resolveTypeDef(c, @ptrCast(*const ZigClangTypedefNameDecl, decl));
|
||||
},
|
||||
.Enum => {
|
||||
try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for enums", .{});
|
||||
|
@ -237,7 +229,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
|
|||
try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for structs", .{});
|
||||
},
|
||||
.Var => {
|
||||
try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for variables", .{});
|
||||
return visitVarDecl(c, @ptrCast(*const ZigClangVarDecl, decl));
|
||||
},
|
||||
else => {
|
||||
const decl_name = try c.str(ZigClangDecl_getDeclKindName(decl));
|
||||
|
@ -262,7 +254,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
|
|||
.storage_class = storage_class,
|
||||
.scope = &scope,
|
||||
.is_export = switch (storage_class) {
|
||||
.None => has_body and c.mode != .import,
|
||||
.None => has_body,
|
||||
.Extern, .Static => false,
|
||||
.PrivateExtern => return failDecl(c, fn_decl_loc, fn_name, "unsupported storage class: private extern", .{}),
|
||||
.Auto => unreachable, // Not legal on functions
|
||||
|
@ -310,6 +302,130 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
|
|||
return addTopLevelDecl(c, fn_name, &proto_node.base);
|
||||
}
|
||||
|
||||
fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
|
||||
if (try c.decl_table.put(@ptrToInt(var_decl), {})) |_| return; // Avoid processing this decl twice
|
||||
const rp = makeRestorePoint(c);
|
||||
const visib_tok = try appendToken(c, .Keyword_pub, "pub");
|
||||
|
||||
const thread_local_token = if (ZigClangVarDecl_getTLSKind(var_decl) == .None)
|
||||
null
|
||||
else
|
||||
try appendToken(c, .Keyword_threadlocal, "threadlocal");
|
||||
|
||||
var scope = &c.global_scope.base;
|
||||
const var_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, var_decl)));
|
||||
const var_decl_loc = ZigClangVarDecl_getLocation(var_decl);
|
||||
|
||||
const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);
|
||||
const storage_class = ZigClangVarDecl_getStorageClass(var_decl);
|
||||
const is_const = ZigClangQualType_isConstQualified(qual_type);
|
||||
|
||||
const extern_tok = if (storage_class == .Extern)
|
||||
try appendToken(c, .Keyword_extern, "extern")
|
||||
else if (storage_class != .Static)
|
||||
try appendToken(c, .Keyword_export, "export")
|
||||
else
|
||||
null;
|
||||
|
||||
const mut_tok = if (is_const)
|
||||
try appendToken(c, .Keyword_const, "const")
|
||||
else
|
||||
try appendToken(c, .Keyword_var, "var");
|
||||
|
||||
const name_tok = try appendToken(c, .Identifier, var_name);
|
||||
|
||||
_ = try appendToken(c, .Colon, ":");
|
||||
const type_node = transQualType(rp, qual_type, var_decl_loc) catch |err| switch (err) {
|
||||
error.UnsupportedType => {
|
||||
return failDecl(c, var_decl_loc, var_name, "unable to resolve variable type", .{});
|
||||
},
|
||||
error.OutOfMemory => |e| return e,
|
||||
};
|
||||
|
||||
var eq_tok: ast.TokenIndex = undefined;
|
||||
var init_node: ?*ast.Node = null;
|
||||
|
||||
if (ZigClangVarDecl_hasInit(var_decl)) {
|
||||
eq_tok = try appendToken(c, .Equal, "=");
|
||||
init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr| blk: {
|
||||
var res = transExpr(rp, &c.global_scope.base, expr, .used, .r_value) catch |err| switch (err) {
|
||||
error.UnsupportedTranslation,
|
||||
error.UnsupportedType,
|
||||
=> {
|
||||
return failDecl(c, var_decl_loc, var_name, "unable to translate initializer", .{});
|
||||
},
|
||||
error.OutOfMemory => |e| return e,
|
||||
};
|
||||
break :blk res.node;
|
||||
} else
|
||||
try transCreateNodeUndefinedLiteral(c);
|
||||
} else if (storage_class != .Extern) {
|
||||
return failDecl(c, var_decl_loc, var_name, "non-extern variable has no initializer", .{});
|
||||
}
|
||||
|
||||
const node = try c.a().create(ast.Node.VarDecl);
|
||||
node.* = ast.Node.VarDecl{
|
||||
.base = ast.Node{ .id = .VarDecl },
|
||||
.doc_comments = null,
|
||||
.visib_token = visib_tok,
|
||||
.thread_local_token = thread_local_token,
|
||||
.name_token = name_tok,
|
||||
.eq_token = eq_tok,
|
||||
.mut_token = mut_tok,
|
||||
.comptime_token = null,
|
||||
.extern_export_token = extern_tok,
|
||||
.lib_name = null,
|
||||
.type_node = type_node,
|
||||
.align_node = null,
|
||||
.section_node = null,
|
||||
.init_node = init_node,
|
||||
.semicolon_token = try appendToken(c, .Semicolon, ";"),
|
||||
};
|
||||
return addTopLevelDecl(c, var_name, &node.base);
|
||||
}
|
||||
|
||||
fn resolveTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error!void {
|
||||
if (try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), {})) |_| return; // Avoid processing this decl twice
|
||||
const rp = makeRestorePoint(c);
|
||||
const visib_tok = try appendToken(c, .Keyword_pub, "pub");
|
||||
const const_tok = try appendToken(c, .Keyword_const, "const");
|
||||
|
||||
const typedef_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));
|
||||
const name_tok = try appendToken(c, .Identifier, typedef_name);
|
||||
const eq_tok = try appendToken(c, .Equal, "=");
|
||||
|
||||
const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
|
||||
const typedef_loc = ZigClangTypedefNameDecl_getLocation(typedef_decl);
|
||||
const type_node = transQualType(rp, child_qt, typedef_loc) catch |err| switch (err) {
|
||||
error.UnsupportedType => {
|
||||
const node = try failDecl(c, typedef_loc, typedef_name, "unable to resolve typedef child type", .{});
|
||||
_ = try c.decl_table.put(@ptrToInt(typedef_decl), node);
|
||||
return node;
|
||||
},
|
||||
error.OutOfMemory => |e| return e,
|
||||
};
|
||||
|
||||
const node = try c.a().create(ast.Node.VarDecl);
|
||||
node.* = ast.Node.VarDecl{
|
||||
.base = ast.Node{ .id = .VarDecl },
|
||||
.doc_comments = null,
|
||||
.visib_token = visib_tok,
|
||||
.thread_local_token = null,
|
||||
.name_token = name_tok,
|
||||
.eq_token = eq_tok,
|
||||
.mut_token = const_tok,
|
||||
.comptime_token = null,
|
||||
.extern_export_token = null,
|
||||
.lib_name = null,
|
||||
.type_node = null,
|
||||
.align_node = null,
|
||||
.section_node = null,
|
||||
.init_node = type_node,
|
||||
.semicolon_token = try appendToken(c, .Semicolon, ";"),
|
||||
};
|
||||
try addTopLevelDecl(c, typedef_name, &node.base);
|
||||
}
|
||||
|
||||
const ResultUsed = enum {
|
||||
used,
|
||||
unused,
|
||||
|
@ -339,6 +455,7 @@ fn transStmt(
|
|||
.ReturnStmtClass => return transReturnStmt(rp, scope, @ptrCast(*const ZigClangReturnStmt, stmt)),
|
||||
.StringLiteralClass => return transStringLiteral(rp, scope, @ptrCast(*const ZigClangStringLiteral, stmt), result_used),
|
||||
.ParenExprClass => return transExpr(rp, scope, ZigClangParenExpr_getSubExpr(@ptrCast(*const ZigClangParenExpr, stmt)), result_used, lrvalue),
|
||||
.InitListExprClass => return transInitListExpr(rp, scope, @ptrCast(*const ZigClangInitListExpr, stmt), result_used),
|
||||
else => {
|
||||
return revertAndWarn(
|
||||
rp,
|
||||
|
@ -564,7 +681,7 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe
|
|||
null
|
||||
else
|
||||
try appendToken(c, .Keyword_threadlocal, "threadlocal");
|
||||
const qual_type = ZigClangVarDecl_getType(var_decl);
|
||||
const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);
|
||||
const mut_token = if (ZigClangQualType_isConstQualified(qual_type))
|
||||
try appendToken(c, .Keyword_const, "const")
|
||||
else
|
||||
|
@ -589,15 +706,8 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe
|
|||
const eq_token = try appendToken(c, .Equal, "=");
|
||||
const init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr|
|
||||
(try transExpr(rp, scope, expr, .used, .r_value)).node
|
||||
else blk: {
|
||||
const undefined_token = try appendToken(c, .Keyword_undefined, "undefined");
|
||||
const undefined_node = try rp.c.a().create(ast.Node.UndefinedLiteral);
|
||||
undefined_node.* = ast.Node.UndefinedLiteral{
|
||||
.base = ast.Node{ .id = .UndefinedLiteral },
|
||||
.token = undefined_token,
|
||||
};
|
||||
break :blk &undefined_node.base;
|
||||
};
|
||||
else
|
||||
try transCreateNodeUndefinedLiteral(c);
|
||||
const semicolon_token = try appendToken(c, .Semicolon, ";");
|
||||
|
||||
const node = try c.a().create(ast.Node.VarDecl);
|
||||
|
@ -687,7 +797,7 @@ fn transImplicitCastExpr(
|
|||
.FunctionToPointerDecay, .ArrayToPointerDecay => {
|
||||
return maybeSuppressResult(rp, scope, result_used, sub_expr_node);
|
||||
},
|
||||
.LValueToRValue => {
|
||||
.LValueToRValue, .NoOp => {
|
||||
return transExpr(rp, scope, sub_expr, .used, .r_value);
|
||||
},
|
||||
else => |kind| return revertAndWarn(
|
||||
|
@ -868,6 +978,88 @@ fn transExpr(
|
|||
return transStmt(rp, scope, @ptrCast(*const ZigClangStmt, expr), used, lrvalue);
|
||||
}
|
||||
|
||||
fn transInitListExpr(
|
||||
rp: RestorePoint,
|
||||
scope: *Scope,
|
||||
expr: *const ZigClangInitListExpr,
|
||||
used: ResultUsed,
|
||||
) TransError!TransResult {
|
||||
// TODO use anon literals once they work properly
|
||||
const qt = getExprQualType(rp.c, @ptrCast(*const ZigClangExpr, expr));
|
||||
const qual_type = ZigClangQualType_getTypePtr(qt);
|
||||
const source_loc = ZigClangExpr_getBeginLoc(@ptrCast(*const ZigClangExpr, expr));
|
||||
const arr_type = ZigClangType_getAsArrayTypeUnsafe(qual_type);
|
||||
const child_qt = ZigClangArrayType_getElementType(arr_type);
|
||||
const init_count = ZigClangInitListExpr_getNumInits(expr);
|
||||
const all_count = 200; //ZigClangArrayType_getSize(arr_type);
|
||||
const leftover_count = all_count - init_count;
|
||||
|
||||
var init_node: *ast.Node.SuffixOp = undefined;
|
||||
var cat_tok: ast.TokenIndex = undefined;
|
||||
if (init_count != 0) {
|
||||
var type_node = try transQualType(rp, qt, source_loc);
|
||||
init_node = try transCreateNodeArrayInitializer(rp.c, type_node);
|
||||
var i: c_uint = 0;
|
||||
while (i < init_count) : (i += 1) {
|
||||
const elem_expr = ZigClangInitListExpr_getInit(expr, i);
|
||||
try init_node.op.ArrayInitializer.push((try transExpr(rp, scope, elem_expr, .used, .r_value)).node);
|
||||
_ = try appendToken(rp.c, .Comma, ",");
|
||||
}
|
||||
init_node.rtoken = try appendToken(rp.c, .RBrace, "}");
|
||||
if (leftover_count == 0) {
|
||||
return TransResult{
|
||||
.node = &init_node.base,
|
||||
.child_scope = scope,
|
||||
.node_scope = scope,
|
||||
};
|
||||
}
|
||||
cat_tok = try appendToken(rp.c, .PlusPlus, "++");
|
||||
}
|
||||
|
||||
var filler_type_node = try transQualType(rp, qt, source_loc);
|
||||
var filler_init_node = try transCreateNodeArrayInitializer(rp.c, filler_type_node);
|
||||
const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr);
|
||||
try filler_init_node.op.ArrayInitializer.push((try transExpr(rp, scope, filler_val_expr, .used, .r_value)).node);
|
||||
filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}");
|
||||
|
||||
const rhs_node = if (leftover_count == 1)
|
||||
&filler_init_node.base
|
||||
else blk: {
|
||||
const mul_tok = try appendToken(rp.c, .AsteriskAsterisk, "**");
|
||||
const mul_node = try rp.c.a().create(ast.Node.InfixOp);
|
||||
mul_node.* = .{
|
||||
.base = .{ .id = .InfixOp },
|
||||
.op_token = mul_tok,
|
||||
.lhs = &filler_init_node.base,
|
||||
.op = .ArrayMult,
|
||||
.rhs = try transCreateNodeInt(rp.c, leftover_count),
|
||||
};
|
||||
break :blk &mul_node.base;
|
||||
};
|
||||
|
||||
if (init_count == 0) {
|
||||
return TransResult{
|
||||
.node = rhs_node,
|
||||
.child_scope = scope,
|
||||
.node_scope = scope,
|
||||
};
|
||||
}
|
||||
|
||||
const cat_node = try rp.c.a().create(ast.Node.InfixOp);
|
||||
cat_node.* = .{
|
||||
.base = .{ .id = .InfixOp },
|
||||
.op_token = cat_tok,
|
||||
.lhs = &init_node.base,
|
||||
.op = .ArrayCat,
|
||||
.rhs = rhs_node,
|
||||
};
|
||||
return TransResult{
|
||||
.node = &cat_node.base,
|
||||
.child_scope = scope,
|
||||
.node_scope = scope,
|
||||
};
|
||||
}
|
||||
|
||||
fn findBlockScope(inner: *Scope) *Scope.Block {
|
||||
var scope = inner;
|
||||
while (true) : (scope = scope.parent orelse unreachable) {
|
||||
|
@ -1233,6 +1425,40 @@ fn transCreateNodeReturnExpr(c: *Context) !*ast.Node {
|
|||
return &node.base;
|
||||
}
|
||||
|
||||
fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node {
|
||||
const token = try appendToken(c, .Keyword_undefined, "undefined");
|
||||
const node = try c.a().create(ast.Node.UndefinedLiteral);
|
||||
node.* = ast.Node.UndefinedLiteral{
|
||||
.base = ast.Node{ .id = .UndefinedLiteral },
|
||||
.token = token,
|
||||
};
|
||||
return &node.base;
|
||||
}
|
||||
|
||||
fn transCreateNodeArrayInitializer(c: *Context, type_node: *ast.Node) !*ast.Node.SuffixOp {
|
||||
_ = try appendToken(c, .LBrace, "{");
|
||||
const node = try c.a().create(ast.Node.SuffixOp);
|
||||
node.* = ast.Node.SuffixOp{
|
||||
.base = ast.Node{ .id = .SuffixOp },
|
||||
.lhs = .{ .node = type_node },
|
||||
.op = .{
|
||||
.ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
|
||||
},
|
||||
.rtoken = undefined, // set after appending values
|
||||
};
|
||||
return node;
|
||||
}
|
||||
|
||||
fn transCreateNodeInt(c: *Context, int: var) !*ast.Node {
|
||||
const token = try appendToken(c, .IntegerLiteral, try std.fmt.allocPrint(c.a(), "{}", .{int}));
|
||||
const node = try c.a().create(ast.Node.IntegerLiteral);
|
||||
node.* = ast.Node.IntegerLiteral{
|
||||
.base = ast.Node{ .id = .IntegerLiteral },
|
||||
.token = token,
|
||||
};
|
||||
return &node.base;
|
||||
}
|
||||
|
||||
const RestorePoint = struct {
|
||||
c: *Context,
|
||||
token_index: ast.TokenIndex,
|
||||
|
@ -1316,6 +1542,47 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
|
|||
pointer_node.rhs = try transQualType(rp, child_qt, source_loc);
|
||||
return &pointer_node.base;
|
||||
},
|
||||
.ConstantArray => {
|
||||
const const_arr_ty = @ptrCast(*const ZigClangConstantArrayType, ty);
|
||||
|
||||
const size_ap_int = ZigClangConstantArrayType_getSize(const_arr_ty);
|
||||
const size = ZigClangAPInt_getLimitedValue(size_ap_int, std.math.maxInt(usize));
|
||||
var node = try transCreateNodePrefixOp(
|
||||
rp.c,
|
||||
.{
|
||||
.ArrayType = .{
|
||||
.len_expr = undefined,
|
||||
.sentinel = null,
|
||||
},
|
||||
},
|
||||
.LBracket,
|
||||
"[",
|
||||
);
|
||||
node.op.ArrayType.len_expr = try transCreateNodeInt(rp.c, size);
|
||||
_ = try appendToken(rp.c, .RBracket, "]");
|
||||
node.rhs = try transQualType(rp, ZigClangConstantArrayType_getElementType(const_arr_ty), source_loc);
|
||||
return &node.base;
|
||||
},
|
||||
.IncompleteArray => {
|
||||
const incomplete_array_ty = @ptrCast(*const ZigClangIncompleteArrayType, ty);
|
||||
|
||||
const child_qt = ZigClangIncompleteArrayType_getElementType(incomplete_array_ty);
|
||||
var node = try transCreateNodePtrType(
|
||||
rp.c,
|
||||
ZigClangQualType_isConstQualified(child_qt),
|
||||
ZigClangQualType_isVolatileQualified(child_qt),
|
||||
.Identifier,
|
||||
);
|
||||
node.rhs = try transQualType(rp, child_qt, source_loc);
|
||||
return &node.base;
|
||||
},
|
||||
.Typedef => {
|
||||
const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);
|
||||
|
||||
const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
|
||||
const typedef_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));
|
||||
return appendIdentifier(rp.c, typedef_name);
|
||||
},
|
||||
else => {
|
||||
const type_name = rp.c.str(ZigClangType_getTypeClassName(ty));
|
||||
return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported type: '{}'", .{type_name});
|
||||
|
@ -1323,6 +1590,15 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
|
|||
}
|
||||
}
|
||||
|
||||
fn isCVoid(qt: ZigClangQualType) bool {
|
||||
const ty = ZigClangQualType_getTypePtr(qt);
|
||||
if (ZigClangType_getTypeClass(ty) == .Builtin) {
|
||||
const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
|
||||
return ZigClangBuiltinType_getKind(builtin_ty) == .Void;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const FnDeclContext = struct {
|
||||
fn_name: []const u8,
|
||||
has_body: bool,
|
||||
|
@ -1473,7 +1749,8 @@ fn finishTransFnProto(
|
|||
break :blk try appendIdentifier(rp.c, "noreturn");
|
||||
} else {
|
||||
const return_qt = ZigClangFunctionType_getReturnType(fn_ty);
|
||||
if (ZigClangType_isVoidType(qualTypeCanon(return_qt))) {
|
||||
if (isCVoid(return_qt)) {
|
||||
// convert primitive c_void to actual void (only for return type)
|
||||
break :blk try appendIdentifier(rp.c, "void");
|
||||
} else {
|
||||
break :blk transQualType(rp, return_qt, source_loc) catch |err| switch (err) {
|
||||
|
@ -1568,7 +1845,7 @@ fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comptime
|
|||
.init_node = &call_node.base,
|
||||
.semicolon_token = semi_tok,
|
||||
};
|
||||
try c.tree.root_node.decls.push(&var_decl_node.base);
|
||||
try addTopLevelDecl(c, name, &var_decl_node.base);
|
||||
}
|
||||
|
||||
fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenIndex {
|
||||
|
|
|
@ -9016,8 +9016,8 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
|
|||
|
||||
init(g);
|
||||
|
||||
Stage2TranslateMode trans_mode = buf_ends_with_str(full_path, ".h") ?
|
||||
Stage2TranslateModeImport : Stage2TranslateModeTranslate;
|
||||
TranslateMode trans_mode = buf_ends_with_str(full_path, ".h") ?
|
||||
TranslateModeImport : TranslateModeTranslate;
|
||||
|
||||
|
||||
ZigList<const char *> clang_argv = {0};
|
||||
|
@ -9043,7 +9043,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
|
|||
|
||||
if (use_userland_implementation) {
|
||||
err = stage2_translate_c(&ast, &errors_ptr, &errors_len,
|
||||
&clang_argv.at(0), &clang_argv.last(), trans_mode, resources_path);
|
||||
&clang_argv.at(0), &clang_argv.last(), resources_path);
|
||||
} else {
|
||||
err = parse_h_file(g, &root_node, &errors_ptr, &errors_len, &clang_argv.at(0), &clang_argv.last(),
|
||||
trans_mode, resources_path);
|
||||
|
|
|
@ -23303,7 +23303,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
|
|||
const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir);
|
||||
|
||||
if ((err = parse_h_file(ira->codegen, &root_node, &errors_ptr, &errors_len,
|
||||
&clang_argv.at(0), &clang_argv.last(), Stage2TranslateModeImport, resources_path)))
|
||||
&clang_argv.at(0), &clang_argv.last(), TranslateModeImport, resources_path)))
|
||||
{
|
||||
if (err != ErrorCCompileErrors) {
|
||||
ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err)));
|
||||
|
|
|
@ -64,7 +64,6 @@ struct TransScopeWhile {
|
|||
|
||||
struct Context {
|
||||
AstNode *root;
|
||||
VisibMod visib_mod;
|
||||
bool want_export;
|
||||
HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
|
||||
HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
|
||||
|
@ -367,7 +366,7 @@ static AstNode *trans_create_node_var_decl(Context *c, VisibMod visib_mod, bool
|
|||
static AstNode *trans_create_node_var_decl_global(Context *c, bool is_const, Buf *var_name, AstNode *type_node,
|
||||
AstNode *init_node)
|
||||
{
|
||||
return trans_create_node_var_decl(c, c->visib_mod, is_const, var_name, type_node, init_node);
|
||||
return trans_create_node_var_decl(c, VisibModPub, is_const, var_name, type_node, init_node);
|
||||
}
|
||||
|
||||
static AstNode *trans_create_node_var_decl_local(Context *c, bool is_const, Buf *var_name, AstNode *type_node,
|
||||
|
@ -379,7 +378,7 @@ static AstNode *trans_create_node_var_decl_local(Context *c, bool is_const, Buf
|
|||
static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, AstNode *ref_node, AstNode *src_proto_node) {
|
||||
AstNode *fn_def = trans_create_node(c, NodeTypeFnDef);
|
||||
AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto);
|
||||
fn_proto->data.fn_proto.visib_mod = c->visib_mod;
|
||||
fn_proto->data.fn_proto.visib_mod = VisibModPub;
|
||||
fn_proto->data.fn_proto.name = fn_name;
|
||||
fn_proto->data.fn_proto.fn_inline = FnInlineAlways;
|
||||
fn_proto->data.fn_proto.return_type = src_proto_node->data.fn_proto.return_type; // TODO ok for these to alias?
|
||||
|
@ -4091,10 +4090,10 @@ static void visit_fn_decl(Context *c, const ZigClangFunctionDecl *fn_decl) {
|
|||
|
||||
ZigClangStorageClass sc = ZigClangFunctionDecl_getStorageClass(fn_decl);
|
||||
if (sc == ZigClangStorageClass_None) {
|
||||
proto_node->data.fn_proto.visib_mod = c->visib_mod;
|
||||
proto_node->data.fn_proto.visib_mod = VisibModPub;
|
||||
proto_node->data.fn_proto.is_export = ZigClangFunctionDecl_hasBody(fn_decl) ? c->want_export : false;
|
||||
} else if (sc == ZigClangStorageClass_Extern || sc == ZigClangStorageClass_Static) {
|
||||
proto_node->data.fn_proto.visib_mod = c->visib_mod;
|
||||
proto_node->data.fn_proto.visib_mod = VisibModPub;
|
||||
} else if (sc == ZigClangStorageClass_PrivateExtern) {
|
||||
emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl), "unsupported storage class: private extern");
|
||||
return;
|
||||
|
@ -5113,16 +5112,14 @@ static void process_preprocessor_entities(Context *c, ZigClangASTUnit *unit) {
|
|||
Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
|
||||
Stage2ErrorMsg **errors_ptr, size_t *errors_len,
|
||||
const char **args_begin, const char **args_end,
|
||||
Stage2TranslateMode mode, const char *resources_path)
|
||||
TranslateMode mode, const char *resources_path)
|
||||
{
|
||||
Context context = {0};
|
||||
Context *c = &context;
|
||||
c->warnings_on = codegen->verbose_cimport;
|
||||
if (mode == Stage2TranslateModeImport) {
|
||||
c->visib_mod = VisibModPub;
|
||||
if (mode == TranslateModeImport) {
|
||||
c->want_export = false;
|
||||
} else {
|
||||
c->visib_mod = VisibModPub;
|
||||
c->want_export = true;
|
||||
}
|
||||
c->decl_table.init(8);
|
||||
|
|
|
@ -11,9 +11,14 @@
|
|||
|
||||
#include "all_types.hpp"
|
||||
|
||||
enum TranslateMode {
|
||||
TranslateModeImport,
|
||||
TranslateModeTranslate,
|
||||
};
|
||||
|
||||
Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
|
||||
Stage2ErrorMsg **errors_ptr, size_t *errors_len,
|
||||
const char **args_begin, const char **args_end,
|
||||
Stage2TranslateMode mode, const char *resources_path);
|
||||
TranslateMode mode, const char *resources_path);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
|
||||
Error stage2_translate_c(struct Stage2Ast **out_ast,
|
||||
struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
|
||||
const char **args_begin, const char **args_end, enum Stage2TranslateMode mode,
|
||||
const char *resources_path)
|
||||
const char **args_begin, const char **args_end, const char *resources_path)
|
||||
{
|
||||
const char *msg = "stage0 called stage2_translate_c";
|
||||
stage2_panic(msg, strlen(msg));
|
||||
|
|
|
@ -80,12 +80,6 @@ enum Error {
|
|||
ErrorImportOutsidePkgPath,
|
||||
};
|
||||
|
||||
// ABI warning
|
||||
enum Stage2TranslateMode {
|
||||
Stage2TranslateModeImport,
|
||||
Stage2TranslateModeTranslate,
|
||||
};
|
||||
|
||||
// ABI warning
|
||||
struct Stage2ErrorMsg {
|
||||
const char *filename_ptr; // can be null
|
||||
|
@ -104,8 +98,7 @@ struct Stage2Ast;
|
|||
// ABI warning
|
||||
ZIG_EXTERN_C enum Error stage2_translate_c(struct Stage2Ast **out_ast,
|
||||
struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
|
||||
const char **args_begin, const char **args_end, enum Stage2TranslateMode mode,
|
||||
const char *resources_path);
|
||||
const char **args_begin, const char **args_end, const char *resources_path);
|
||||
|
||||
// ABI warning
|
||||
ZIG_EXTERN_C void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len);
|
||||
|
|
|
@ -1825,6 +1825,23 @@ bool ZigClangExpr_EvaluateAsConstantExpr(const ZigClangExpr *self, ZigClangExprE
|
|||
return true;
|
||||
}
|
||||
|
||||
const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *self, unsigned i) {
|
||||
auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
|
||||
const clang::Expr *result = casted->getInit(i);
|
||||
return reinterpret_cast<const ZigClangExpr *>(result);
|
||||
}
|
||||
|
||||
const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *self) {
|
||||
auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
|
||||
const clang::Expr *result = casted->getArrayFiller();
|
||||
return reinterpret_cast<const ZigClangExpr *>(result);
|
||||
}
|
||||
|
||||
unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *self) {
|
||||
auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
|
||||
return casted->getNumInits();
|
||||
}
|
||||
|
||||
ZigClangAPValueKind ZigClangAPValue_getKind(const ZigClangAPValue *self) {
|
||||
auto casted = reinterpret_cast<const clang::APValue *>(self);
|
||||
return (ZigClangAPValueKind)casted->getKind();
|
||||
|
@ -2065,6 +2082,11 @@ const ZigClangAPValue * ZigClangVarDecl_evaluateValue(const struct ZigClangVarDe
|
|||
return reinterpret_cast<const ZigClangAPValue *>(result);
|
||||
}
|
||||
|
||||
enum ZigClangStorageClass ZigClangVarDecl_getStorageClass(const struct ZigClangVarDecl *self) {
|
||||
auto casted = reinterpret_cast<const clang::VarDecl *>(self);
|
||||
return (ZigClangStorageClass)casted->getStorageClass();
|
||||
}
|
||||
|
||||
enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBuiltinType *self) {
|
||||
auto casted = reinterpret_cast<const clang::BuiltinType *>(self);
|
||||
return (ZigClangBuiltinTypeKind)casted->getKind();
|
||||
|
|
|
@ -144,6 +144,7 @@ struct ZigClangUnaryOperator;
|
|||
struct ZigClangValueDecl;
|
||||
struct ZigClangVarDecl;
|
||||
struct ZigClangWhileStmt;
|
||||
struct ZigClangInitListExpr;
|
||||
|
||||
typedef struct ZigClangStmt *const * ZigClangCompoundStmt_const_body_iterator;
|
||||
typedef struct ZigClangDecl *const * ZigClangDeclStmt_const_decl_iterator;
|
||||
|
@ -904,6 +905,7 @@ ZIG_EXTERN_C bool ZigClangVarDecl_isFileVarDecl(const struct ZigClangVarDecl *);
|
|||
ZIG_EXTERN_C bool ZigClangVarDecl_hasInit(const struct ZigClangVarDecl *);
|
||||
ZIG_EXTERN_C const struct ZigClangAPValue *ZigClangVarDecl_evaluateValue(const struct ZigClangVarDecl *);
|
||||
ZIG_EXTERN_C struct ZigClangQualType ZigClangVarDecl_getTypeSourceInfo_getType(const struct ZigClangVarDecl *);
|
||||
ZIG_EXTERN_C enum ZigClangStorageClass ZigClangVarDecl_getStorageClass(const struct ZigClangVarDecl *self);
|
||||
|
||||
ZIG_EXTERN_C bool ZigClangSourceLocation_eq(struct ZigClangSourceLocation a, struct ZigClangSourceLocation b);
|
||||
|
||||
|
@ -939,6 +941,10 @@ ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsFloat(const struct ZigClangExpr *self,
|
|||
ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *,
|
||||
struct ZigClangExprEvalResult *, ZigClangExpr_ConstExprUsage, const struct ZigClangASTContext *);
|
||||
|
||||
ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned);
|
||||
ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *);
|
||||
ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *);
|
||||
|
||||
ZIG_EXTERN_C enum ZigClangAPValueKind ZigClangAPValue_getKind(const struct ZigClangAPValue *self);
|
||||
ZIG_EXTERN_C const struct ZigClangAPSInt *ZigClangAPValue_getInt(const struct ZigClangAPValue *self);
|
||||
ZIG_EXTERN_C unsigned ZigClangAPValue_getArrayInitializedElts(const struct ZigClangAPValue *self);
|
||||
|
|
|
@ -1651,17 +1651,6 @@ pub const TranslateCContext = struct {
|
|||
self.addCase(tc);
|
||||
}
|
||||
|
||||
pub fn addC_2(
|
||||
self: *TranslateCContext,
|
||||
name: []const u8,
|
||||
source: []const u8,
|
||||
expected_lines: []const []const u8,
|
||||
) void {
|
||||
const tc = self.create(false, "source.c", name, source, expected_lines);
|
||||
tc.stage2 = true;
|
||||
self.addCase(tc);
|
||||
}
|
||||
|
||||
pub fn addAllowWarnings(
|
||||
self: *TranslateCContext,
|
||||
name: []const u8,
|
||||
|
|
|
@ -3,10 +3,9 @@ const builtin = @import("builtin");
|
|||
|
||||
// add_both - test for stage1 and stage2, in #include mode
|
||||
// add - test stage1 only, in #include mode
|
||||
// add_2 - test stage2 only, in #include mode
|
||||
// add_2 - test stage2 only
|
||||
// addC_both - test for stage1 and stage2, in -c mode
|
||||
// addC - test stage1 only, in -c mode
|
||||
// addC_2 - test stage2 only, in -c mode
|
||||
|
||||
pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
/////////////// Cases that pass for both stage1/stage2 ////////////////
|
||||
|
@ -18,7 +17,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||
\\pub extern fn bar() c_int;
|
||||
});
|
||||
|
||||
cases.add_both("simple var decls",
|
||||
cases.addC_both("simple var decls",
|
||||
\\void foo(void) {
|
||||
\\ int a;
|
||||
\\ char b = 123;
|
||||
|
@ -26,7 +25,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||
\\ const unsigned d = 440;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub fn foo() void {
|
||||
\\pub export fn foo() void {
|
||||
\\ var a: c_int = undefined;
|
||||
\\ var b: u8 = @as(u8, 123);
|
||||
\\ const c: c_int = undefined;
|
||||
|
@ -34,7 +33,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||
\\}
|
||||
});
|
||||
|
||||
cases.add_both("ignore result, explicit function arguments",
|
||||
cases.addC_both("ignore result, explicit function arguments",
|
||||
\\void foo(void) {
|
||||
\\ int a;
|
||||
\\ 1;
|
||||
|
@ -44,7 +43,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||
\\ a = 1;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub fn foo() void {
|
||||
\\pub export fn foo() void {
|
||||
\\ var a: c_int = undefined;
|
||||
\\ _ = 1;
|
||||
\\ _ = "hey";
|
||||
|
@ -54,42 +53,139 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||
\\}
|
||||
});
|
||||
|
||||
cases.addC_both("variables",
|
||||
\\extern int extern_var;
|
||||
\\static const int int_var = 13;
|
||||
, &[_][]const u8{
|
||||
\\pub extern var extern_var: c_int;
|
||||
,
|
||||
\\pub const int_var: c_int = 13;
|
||||
});
|
||||
|
||||
cases.add_both("const ptr initializer",
|
||||
\\static const char *v0 = "0.0.0";
|
||||
, &[_][]const u8{
|
||||
\\pub var v0: [*c]const u8 = "0.0.0";
|
||||
});
|
||||
|
||||
cases.addC_both("static incomplete array inside function",
|
||||
\\void foo(void) {
|
||||
\\ static const char v2[] = "2.2.2";
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() void {
|
||||
\\ const v2: [*c]const u8 = "2.2.2";
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC_both("simple function definition",
|
||||
\\void foo(void) {}
|
||||
\\static void bar(void) {}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() void {}
|
||||
\\pub fn bar() void {}
|
||||
});
|
||||
|
||||
cases.add_both("typedef void",
|
||||
\\typedef void Foo;
|
||||
\\Foo fun(Foo *a);
|
||||
, &[_][]const u8{
|
||||
\\pub const Foo = c_void;
|
||||
,
|
||||
\\pub extern fn fun(a: ?*Foo) Foo;
|
||||
});
|
||||
|
||||
cases.add_both("duplicate typedef",
|
||||
\\typedef long foo;
|
||||
\\typedef int bar;
|
||||
\\typedef long foo;
|
||||
\\typedef int baz;
|
||||
, &[_][]const u8{
|
||||
\\pub const foo = c_long;
|
||||
\\pub const bar = c_int;
|
||||
\\pub const baz = c_int;
|
||||
});
|
||||
|
||||
cases.addC_both("casting pointers to ints and ints to pointers",
|
||||
\\void foo(void);
|
||||
\\void bar(void) {
|
||||
\\ void *func_ptr = foo;
|
||||
\\ void (*typed_func_ptr)(void) = (void (*)(void)) (unsigned long) func_ptr;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub extern fn foo() void;
|
||||
\\pub export fn bar() void {
|
||||
\\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo);
|
||||
\\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, @as(c_ulong, @ptrToInt(func_ptr)));
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add_both("noreturn attribute",
|
||||
\\void foo(void) __attribute__((noreturn));
|
||||
, &[_][]const u8{
|
||||
\\pub extern fn foo() noreturn;
|
||||
});
|
||||
|
||||
cases.addC_both("add, sub, mul, div, rem",
|
||||
\\int s(int a, int b) {
|
||||
\\ int c;
|
||||
\\ c = a + b;
|
||||
\\ c = a - b;
|
||||
\\ c = a * b;
|
||||
\\ c = a / b;
|
||||
\\ c = a % b;
|
||||
\\}
|
||||
\\unsigned u(unsigned a, unsigned b) {
|
||||
\\ unsigned c;
|
||||
\\ c = a + b;
|
||||
\\ c = a - b;
|
||||
\\ c = a * b;
|
||||
\\ c = a / b;
|
||||
\\ c = a % b;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn s(a: c_int, b: c_int) c_int {
|
||||
\\ var c: c_int = undefined;
|
||||
\\ c = (a + b);
|
||||
\\ c = (a - b);
|
||||
\\ c = (a * b);
|
||||
\\ c = @divTrunc(a, b);
|
||||
\\ c = @rem(a, b);
|
||||
\\}
|
||||
\\pub export fn u(a: c_uint, b: c_uint) c_uint {
|
||||
\\ var c: c_uint = undefined;
|
||||
\\ c = (a +% b);
|
||||
\\ c = (a -% b);
|
||||
\\ c = (a *% b);
|
||||
\\ c = (a / b);
|
||||
\\ c = (a % b);
|
||||
\\}
|
||||
});
|
||||
|
||||
/////////////// Cases that pass for only stage2 ////////////////
|
||||
// TODO: restore these tests after removing "import mode" concept
|
||||
// https://github.com/ziglang/zig/issues/2780
|
||||
|
||||
// cases.add_2("Parameterless function prototypes",
|
||||
// \\void a() {}
|
||||
// \\void b(void) {}
|
||||
// \\void c();
|
||||
// \\void d(void);
|
||||
// ,
|
||||
// \\pub export fn a() void {}
|
||||
// \\pub export fn b() void {}
|
||||
// \\pub extern fn c(...) void;
|
||||
// \\pub extern fn d() void;
|
||||
// );
|
||||
|
||||
// cases.add_2("simple function definition",
|
||||
// \\void foo(void) {}
|
||||
// \\static void bar(void) {}
|
||||
// ,
|
||||
// \\pub export fn foo() void {}
|
||||
// \\pub extern fn bar() void {}
|
||||
// );
|
||||
|
||||
cases.add_2("parameterless function prototypes",
|
||||
cases.add_2("Parameterless function prototypes",
|
||||
\\void a() {}
|
||||
\\void b(void) {}
|
||||
\\void c();
|
||||
\\void d(void);
|
||||
, &[_][]const u8{
|
||||
\\pub fn a(...) void {}
|
||||
\\pub fn b() void {}
|
||||
\\pub export fn a() void {}
|
||||
\\pub export fn b() void {}
|
||||
\\pub extern fn c(...) void;
|
||||
\\pub extern fn d() void;
|
||||
});
|
||||
|
||||
cases.add_2("variable declarations",
|
||||
\\extern char arr0[] = "hello";
|
||||
\\static char arr1[] = "hello";
|
||||
\\char arr2[] = "hello";
|
||||
, &[_][]const u8{
|
||||
\\pub extern var arr0: [*c]u8 = "hello";
|
||||
\\pub var arr1: [*c]u8 = "hello";
|
||||
\\pub export var arr2: [*c]u8 = "hello";
|
||||
});
|
||||
|
||||
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
|
||||
|
||||
cases.add("typedef of function in struct field",
|
||||
|
@ -120,34 +216,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||
\\};
|
||||
});
|
||||
|
||||
cases.add_both("simple function definition",
|
||||
\\void foo(void) {}
|
||||
\\static void bar(void) {}
|
||||
, &[_][]const u8{
|
||||
\\pub fn foo() void {}
|
||||
\\pub fn bar() void {}
|
||||
});
|
||||
|
||||
cases.add("macro with left shift",
|
||||
\\#define REDISMODULE_READ (1<<0)
|
||||
, &[_][]const u8{
|
||||
\\pub const REDISMODULE_READ = 1 << 0;
|
||||
});
|
||||
|
||||
cases.add_both("casting pointers to ints and ints to pointers",
|
||||
\\void foo(void);
|
||||
\\void bar(void) {
|
||||
\\ void *func_ptr = foo;
|
||||
\\ void (*typed_func_ptr)(void) = (void (*)(void)) (unsigned long) func_ptr;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub extern fn foo() void;
|
||||
\\pub fn bar() void {
|
||||
\\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo);
|
||||
\\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, @as(c_ulong, @ptrToInt(func_ptr)));
|
||||
\\}
|
||||
});
|
||||
|
||||
if (builtin.os != builtin.Os.windows) {
|
||||
// Windows treats this as an enum with type c_int
|
||||
cases.add("big negative enum init values when C ABI supports long long enums",
|
||||
|
@ -320,12 +394,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||
\\pub extern fn baz(a: i8, b: i16, c: i32, d: i64) void;
|
||||
});
|
||||
|
||||
cases.add_both("noreturn attribute",
|
||||
\\void foo(void) __attribute__((noreturn));
|
||||
, &[_][]const u8{
|
||||
\\pub extern fn foo() noreturn;
|
||||
});
|
||||
|
||||
cases.addC("simple function",
|
||||
\\int abs(int a) {
|
||||
\\ return a < 0 ? -a : a;
|
||||
|
@ -482,15 +550,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||
\\pub const THING2 = THING1;
|
||||
});
|
||||
|
||||
cases.add("variables",
|
||||
\\extern int extern_var;
|
||||
\\static const int int_var = 13;
|
||||
, &[_][]const u8{
|
||||
\\pub extern var extern_var: c_int;
|
||||
,
|
||||
\\pub const int_var: c_int = 13;
|
||||
});
|
||||
|
||||
cases.add("circular struct definitions",
|
||||
\\struct Bar;
|
||||
\\
|
||||
|
@ -511,15 +570,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||
\\};
|
||||
});
|
||||
|
||||
cases.add("typedef void",
|
||||
\\typedef void Foo;
|
||||
\\Foo fun(Foo *a);
|
||||
, &[_][]const u8{
|
||||
\\pub const Foo = c_void;
|
||||
,
|
||||
\\pub extern fn fun(a: ?*Foo) Foo;
|
||||
});
|
||||
|
||||
cases.add("generate inline func for #define global extern fn",
|
||||
\\extern void (*fn_ptr)(void);
|
||||
\\#define foo fn_ptr
|
||||
|
@ -719,42 +769,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||
\\}
|
||||
});
|
||||
|
||||
cases.addC_both("add, sub, mul, div, rem",
|
||||
\\int s(int a, int b) {
|
||||
\\ int c;
|
||||
\\ c = a + b;
|
||||
\\ c = a - b;
|
||||
\\ c = a * b;
|
||||
\\ c = a / b;
|
||||
\\ c = a % b;
|
||||
\\}
|
||||
\\unsigned u(unsigned a, unsigned b) {
|
||||
\\ unsigned c;
|
||||
\\ c = a + b;
|
||||
\\ c = a - b;
|
||||
\\ c = a * b;
|
||||
\\ c = a / b;
|
||||
\\ c = a % b;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn s(a: c_int, b: c_int) c_int {
|
||||
\\ var c: c_int = undefined;
|
||||
\\ c = (a + b);
|
||||
\\ c = (a - b);
|
||||
\\ c = (a * b);
|
||||
\\ c = @divTrunc(a, b);
|
||||
\\ c = @rem(a, b);
|
||||
\\}
|
||||
\\pub export fn u(a: c_uint, b: c_uint) c_uint {
|
||||
\\ var c: c_uint = undefined;
|
||||
\\ c = (a +% b);
|
||||
\\ c = (a -% b);
|
||||
\\ c = (a *% b);
|
||||
\\ c = (a / b);
|
||||
\\ c = (a % b);
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("bitwise binary operators",
|
||||
\\int max(int a, int b) {
|
||||
\\ return (a & b) ^ (a | b);
|
||||
|
@ -1147,17 +1161,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||
\\}
|
||||
});
|
||||
|
||||
cases.addC("duplicate typedef",
|
||||
\\typedef long foo;
|
||||
\\typedef int bar;
|
||||
\\typedef long foo;
|
||||
\\typedef int baz;
|
||||
, &[_][]const u8{
|
||||
\\pub const foo = c_long;
|
||||
\\pub const bar = c_int;
|
||||
\\pub const baz = c_int;
|
||||
});
|
||||
|
||||
cases.addC("post increment/decrement",
|
||||
\\void foo(void) {
|
||||
\\ int i = 0;
|
||||
|
@ -1520,22 +1523,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||
\\}
|
||||
});
|
||||
|
||||
cases.add("const ptr initializer",
|
||||
\\static const char *v0 = "0.0.0";
|
||||
, &[_][]const u8{
|
||||
\\pub var v0: [*c]const u8 = "0.0.0";
|
||||
});
|
||||
|
||||
cases.add("static incomplete array inside function",
|
||||
\\void foo(void) {
|
||||
\\ static const char v2[] = "2.2.2";
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub fn foo() void {
|
||||
\\ const v2: [*c]const u8 = "2.2.2";
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("macro pointer cast",
|
||||
\\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
|
||||
, &[_][]const u8{
|
||||
|
|
Loading…
Reference in New Issue