translate-c-2 macro inline fn
This commit is contained in:
parent
75218d4765
commit
57170f9eb6
@ -33,8 +33,7 @@ fn addrEql(a: usize, b: usize) bool {
|
|||||||
return a == b;
|
return a == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MacroTable = std.StringHashMap(*ast.Node);
|
const SymbolTable = std.StringHashMap(*ast.Node);
|
||||||
const SymbolTable = std.StringHashMap(void);
|
|
||||||
const AliasList = std.SegmentedList(struct {
|
const AliasList = std.SegmentedList(struct {
|
||||||
alias: []const u8,
|
alias: []const u8,
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
@ -109,7 +108,7 @@ const Context = struct {
|
|||||||
decl_table: DeclTable,
|
decl_table: DeclTable,
|
||||||
alias_list: AliasList,
|
alias_list: AliasList,
|
||||||
sym_table: SymbolTable,
|
sym_table: SymbolTable,
|
||||||
macro_table: MacroTable,
|
macro_table: SymbolTable,
|
||||||
global_scope: *Scope.Root,
|
global_scope: *Scope.Root,
|
||||||
ptr_params: std.BufSet,
|
ptr_params: std.BufSet,
|
||||||
clang_context: *ZigClangASTContext,
|
clang_context: *ZigClangASTContext,
|
||||||
@ -197,7 +196,7 @@ pub fn translate(
|
|||||||
.decl_table = DeclTable.init(arena),
|
.decl_table = DeclTable.init(arena),
|
||||||
.alias_list = AliasList.init(arena),
|
.alias_list = AliasList.init(arena),
|
||||||
.sym_table = SymbolTable.init(arena),
|
.sym_table = SymbolTable.init(arena),
|
||||||
.macro_table = MacroTable.init(arena),
|
.macro_table = SymbolTable.init(arena),
|
||||||
.global_scope = try arena.create(Scope.Root),
|
.global_scope = try arena.create(Scope.Root),
|
||||||
.ptr_params = std.BufSet.init(arena),
|
.ptr_params = std.BufSet.init(arena),
|
||||||
.clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
|
.clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
|
||||||
@ -215,11 +214,7 @@ pub fn translate(
|
|||||||
|
|
||||||
try transPreprocessorEntities(&context, ast_unit);
|
try transPreprocessorEntities(&context, ast_unit);
|
||||||
|
|
||||||
var macro_it = context.macro_table.iterator();
|
try addMacros(&context);
|
||||||
while (macro_it.next()) |kv| {
|
|
||||||
try addTopLevelDecl(&context, kv.key, kv.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
var it = context.alias_list.iterator(0);
|
var it = context.alias_list.iterator(0);
|
||||||
while (it.next()) |alias| {
|
while (it.next()) |alias| {
|
||||||
if (!context.sym_table.contains(alias.alias)) {
|
if (!context.sym_table.contains(alias.alias)) {
|
||||||
@ -962,12 +957,11 @@ fn transReturnStmt(
|
|||||||
) !TransResult {
|
) !TransResult {
|
||||||
const node = try transCreateNodeReturnExpr(rp.c);
|
const node = try transCreateNodeReturnExpr(rp.c);
|
||||||
if (ZigClangReturnStmt_getRetValue(expr)) |val_expr| {
|
if (ZigClangReturnStmt_getRetValue(expr)) |val_expr| {
|
||||||
const ret_node = node.cast(ast.Node.ControlFlowExpression).?;
|
node.rhs = (try transExpr(rp, scope, val_expr, .used, .r_value)).node;
|
||||||
ret_node.rhs = (try transExpr(rp, scope, val_expr, .used, .r_value)).node;
|
|
||||||
}
|
}
|
||||||
_ = try appendToken(rp.c, .Semicolon, ";");
|
_ = try appendToken(rp.c, .Semicolon, ";");
|
||||||
return TransResult{
|
return TransResult{
|
||||||
.node = node,
|
.node = &node.base,
|
||||||
.child_scope = scope,
|
.child_scope = scope,
|
||||||
.node_scope = scope,
|
.node_scope = scope,
|
||||||
};
|
};
|
||||||
@ -1327,7 +1321,7 @@ fn maybeSuppressResult(
|
|||||||
|
|
||||||
fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void {
|
fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void {
|
||||||
try c.tree.root_node.decls.push(decl_node);
|
try c.tree.root_node.decls.push(decl_node);
|
||||||
_ = try c.sym_table.put(name, {});
|
_ = try c.sym_table.put(name, decl_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transQualType(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) TypeError!*ast.Node {
|
fn transQualType(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) TypeError!*ast.Node {
|
||||||
@ -1767,7 +1761,7 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp {
|
|||||||
_ = try appendToken(c, .LParen, "(");
|
_ = try appendToken(c, .LParen, "(");
|
||||||
const node = try c.a().create(ast.Node.SuffixOp);
|
const node = try c.a().create(ast.Node.SuffixOp);
|
||||||
node.* = ast.Node.SuffixOp{
|
node.* = ast.Node.SuffixOp{
|
||||||
.lhs = fn_expr,
|
.lhs = .{ .node = fn_expr },
|
||||||
.op = ast.Node.SuffixOp.Op{
|
.op = ast.Node.SuffixOp.Op{
|
||||||
.Call = ast.Node.SuffixOp.Op.Call{
|
.Call = ast.Node.SuffixOp.Op.Call{
|
||||||
.params = ast.Node.SuffixOp.Op.Call.ParamList.init(c.a()),
|
.params = ast.Node.SuffixOp.Op.Call.ParamList.init(c.a()),
|
||||||
@ -1881,7 +1875,7 @@ fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node {
|
|||||||
return &node.base;
|
return &node.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transCreateNodeReturnExpr(c: *Context) !*ast.Node {
|
fn transCreateNodeReturnExpr(c: *Context) !*ast.Node.ControlFlowExpression {
|
||||||
const ltoken = try appendToken(c, .Keyword_return, "return");
|
const ltoken = try appendToken(c, .Keyword_return, "return");
|
||||||
const node = try c.a().create(ast.Node.ControlFlowExpression);
|
const node = try c.a().create(ast.Node.ControlFlowExpression);
|
||||||
node.* = ast.Node.ControlFlowExpression{
|
node.* = ast.Node.ControlFlowExpression{
|
||||||
@ -1889,7 +1883,7 @@ fn transCreateNodeReturnExpr(c: *Context) !*ast.Node {
|
|||||||
.kind = .Return,
|
.kind = .Return,
|
||||||
.rhs = null,
|
.rhs = null,
|
||||||
};
|
};
|
||||||
return &node.base;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node {
|
fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node {
|
||||||
@ -1959,6 +1953,100 @@ fn transCreateNodeOpaqueType(c: *Context) !*ast.Node {
|
|||||||
return &call_node.base;
|
return &call_node.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_alias_node: *ast.Node) !*ast.Node {
|
||||||
|
const pub_tok = try appendToken(c, .Keyword_pub, "pub");
|
||||||
|
const inline_tok = try appendToken(c, .Keyword_inline, "inline");
|
||||||
|
const fn_tok = try appendToken(c, .Keyword_fn, "fn");
|
||||||
|
const name_tok = try appendIdentifier(c, name);
|
||||||
|
_ = try appendToken(c, .LParen, "(");
|
||||||
|
|
||||||
|
const proto_alias = proto_alias_node.cast(ast.Node.FnProto).?;
|
||||||
|
|
||||||
|
var fn_params = ast.Node.FnProto.ParamList.init(c.a());
|
||||||
|
var it = proto_alias.params.iterator(0);
|
||||||
|
while (it.next()) |pn| {
|
||||||
|
if (it.index != 0) {
|
||||||
|
_ = try appendToken(c, .Comma, ",");
|
||||||
|
}
|
||||||
|
const param = pn.*.cast(ast.Node.ParamDecl).?;
|
||||||
|
|
||||||
|
const param_name_tok = param.name_token orelse
|
||||||
|
try appendTokenFmt(c, .Identifier, "arg_{}", .{c.getMangle()});
|
||||||
|
|
||||||
|
_ = try appendToken(c, .Colon, ":");
|
||||||
|
|
||||||
|
const param_node = try c.a().create(ast.Node.ParamDecl);
|
||||||
|
param_node.* = .{
|
||||||
|
.doc_comments = null,
|
||||||
|
.comptime_token = null,
|
||||||
|
.noalias_token = param.noalias_token,
|
||||||
|
.name_token = param_name_tok,
|
||||||
|
.type_node = param.type_node,
|
||||||
|
.var_args_token = null,
|
||||||
|
};
|
||||||
|
try fn_params.push(¶m_node.base);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = try appendToken(c, .RParen, ")");
|
||||||
|
|
||||||
|
const fn_proto = try c.a().create(ast.Node.FnProto);
|
||||||
|
fn_proto.* = .{
|
||||||
|
.doc_comments = null,
|
||||||
|
.visib_token = pub_tok,
|
||||||
|
.fn_token = fn_tok,
|
||||||
|
.name_token = name_tok,
|
||||||
|
.params = fn_params,
|
||||||
|
.return_type = proto_alias.return_type,
|
||||||
|
.var_args_token = null,
|
||||||
|
.extern_export_inline_token = inline_tok,
|
||||||
|
.cc_token = null,
|
||||||
|
.body_node = null,
|
||||||
|
.lib_name = null,
|
||||||
|
.align_expr = null,
|
||||||
|
.section_expr = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const block = try c.a().create(ast.Node.Block);
|
||||||
|
block.* = .{
|
||||||
|
.label = null,
|
||||||
|
.lbrace = try appendToken(c, .LBrace, "{"),
|
||||||
|
.statements = ast.Node.Block.StatementList.init(c.a()),
|
||||||
|
.rbrace = undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
const return_expr = try transCreateNodeReturnExpr(c);
|
||||||
|
const unwrap_expr = try transCreateNodeUnwrapNull(c, ref.cast(ast.Node.VarDecl).?.init_node.?);
|
||||||
|
const call_expr = try transCreateNodeFnCall(c, unwrap_expr);
|
||||||
|
it = fn_params.iterator(0);
|
||||||
|
while (it.next()) |pn| {
|
||||||
|
if (it.index != 0) {
|
||||||
|
_ = try appendToken(c, .Comma, ",");
|
||||||
|
}
|
||||||
|
const param = pn.*.cast(ast.Node.ParamDecl).?;
|
||||||
|
try call_expr.op.Call.params.push(try transCreateNodeIdentifier(c, tokenSlice(c, param.name_token.?)));
|
||||||
|
}
|
||||||
|
call_expr.rtoken = try appendToken(c, .RParen, ")");
|
||||||
|
return_expr.rhs = &call_expr.base;
|
||||||
|
_ = try appendToken(c, .Semicolon, ";");
|
||||||
|
|
||||||
|
block.rbrace = try appendToken(c, .RBrace, "}");
|
||||||
|
try block.statements.push(&return_expr.base);
|
||||||
|
fn_proto.body_node = &block.base;
|
||||||
|
return &fn_proto.base;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transCreateNodeUnwrapNull(c: *Context, wrapped: *ast.Node) !*ast.Node {
|
||||||
|
_ = try appendToken(c, .Period, ".");
|
||||||
|
const qm = try appendToken(c, .QuestionMark, "?");
|
||||||
|
const node = try c.a().create(ast.Node.SuffixOp);
|
||||||
|
node.* = ast.Node.SuffixOp{
|
||||||
|
.op = .UnwrapOptional,
|
||||||
|
.lhs = .{ .node = wrapped },
|
||||||
|
.rtoken = qm,
|
||||||
|
};
|
||||||
|
return &node.base;
|
||||||
|
}
|
||||||
|
|
||||||
const RestorePoint = struct {
|
const RestorePoint = struct {
|
||||||
c: *Context,
|
c: *Context,
|
||||||
token_index: ast.TokenIndex,
|
token_index: ast.TokenIndex,
|
||||||
@ -1982,28 +2070,28 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
|
|||||||
switch (ZigClangType_getTypeClass(ty)) {
|
switch (ZigClangType_getTypeClass(ty)) {
|
||||||
.Builtin => {
|
.Builtin => {
|
||||||
const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
|
const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
|
||||||
switch (ZigClangBuiltinType_getKind(builtin_ty)) {
|
return transCreateNodeIdentifier(rp.c, switch (ZigClangBuiltinType_getKind(builtin_ty)) {
|
||||||
.Void => return transCreateNodeIdentifier(rp.c, "c_void"),
|
.Void => "c_void",
|
||||||
.Bool => return transCreateNodeIdentifier(rp.c, "bool"),
|
.Bool => "bool",
|
||||||
.Char_U, .UChar, .Char_S, .Char8 => return transCreateNodeIdentifier(rp.c, "u8"),
|
.Char_U, .UChar, .Char_S, .Char8 => "u8",
|
||||||
.SChar => return transCreateNodeIdentifier(rp.c, "i8"),
|
.SChar => "i8",
|
||||||
.UShort => return transCreateNodeIdentifier(rp.c, "c_ushort"),
|
.UShort => "c_ushort",
|
||||||
.UInt => return transCreateNodeIdentifier(rp.c, "c_uint"),
|
.UInt => "c_uint",
|
||||||
.ULong => return transCreateNodeIdentifier(rp.c, "c_ulong"),
|
.ULong => "c_ulong",
|
||||||
.ULongLong => return transCreateNodeIdentifier(rp.c, "c_ulonglong"),
|
.ULongLong => "c_ulonglong",
|
||||||
.Short => return transCreateNodeIdentifier(rp.c, "c_short"),
|
.Short => "c_short",
|
||||||
.Int => return transCreateNodeIdentifier(rp.c, "c_int"),
|
.Int => "c_int",
|
||||||
.Long => return transCreateNodeIdentifier(rp.c, "c_long"),
|
.Long => "c_long",
|
||||||
.LongLong => return transCreateNodeIdentifier(rp.c, "c_longlong"),
|
.LongLong => "c_longlong",
|
||||||
.UInt128 => return transCreateNodeIdentifier(rp.c, "u128"),
|
.UInt128 => "u128",
|
||||||
.Int128 => return transCreateNodeIdentifier(rp.c, "i128"),
|
.Int128 => "i128",
|
||||||
.Float => return transCreateNodeIdentifier(rp.c, "f32"),
|
.Float => "f32",
|
||||||
.Double => return transCreateNodeIdentifier(rp.c, "f64"),
|
.Double => "f64",
|
||||||
.Float128 => return transCreateNodeIdentifier(rp.c, "f128"),
|
.Float128 => "f128",
|
||||||
.Float16 => return transCreateNodeIdentifier(rp.c, "f16"),
|
.Float16 => "f16",
|
||||||
.LongDouble => return transCreateNodeIdentifier(rp.c, "c_longdouble"),
|
.LongDouble => "c_longdouble",
|
||||||
else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}),
|
else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type", .{}),
|
||||||
}
|
});
|
||||||
},
|
},
|
||||||
.FunctionProto => {
|
.FunctionProto => {
|
||||||
const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty);
|
const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty);
|
||||||
@ -2693,8 +2781,6 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
|
|||||||
node = &access_node.base;
|
node = &access_node.base;
|
||||||
},
|
},
|
||||||
.Shl => {
|
.Shl => {
|
||||||
const rhs_node = try parseCPrimaryExpr(rp, it, source_loc);
|
|
||||||
|
|
||||||
const op_token = try appendToken(rp.c, .AngleBracketAngleBracketLeft, "<<");
|
const op_token = try appendToken(rp.c, .AngleBracketAngleBracketLeft, "<<");
|
||||||
const rhs = try parseCPrimaryExpr(rp, it, source_loc);
|
const rhs = try parseCPrimaryExpr(rp, it, source_loc);
|
||||||
const bitshift_node = try rp.c.a().create(ast.Node.InfixOp);
|
const bitshift_node = try rp.c.a().create(ast.Node.InfixOp);
|
||||||
@ -2718,9 +2804,64 @@ fn parseCPrefixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
|
|||||||
const op_tok = it.next().?;
|
const op_tok = it.next().?;
|
||||||
|
|
||||||
switch (op_tok.id) {
|
switch (op_tok.id) {
|
||||||
|
.Bang => {
|
||||||
|
const node = try transCreateNodePrefixOp(rp.c, .BoolNot, .Bang, "!");
|
||||||
|
node.rhs = try parseCPrefixOpExpr(rp, it, source_loc);
|
||||||
|
return &node.base;
|
||||||
|
},
|
||||||
|
.Minus => {
|
||||||
|
const node = try transCreateNodePrefixOp(rp.c, .Negation, .Minus, "-");
|
||||||
|
node.rhs = try parseCPrefixOpExpr(rp, it, source_loc);
|
||||||
|
return &node.base;
|
||||||
|
},
|
||||||
|
.Tilde => {
|
||||||
|
const node = try transCreateNodePrefixOp(rp.c, .BitNot, .Tilde, "~");
|
||||||
|
node.rhs = try parseCPrefixOpExpr(rp, it, source_loc);
|
||||||
|
return &node.base;
|
||||||
|
},
|
||||||
else => {
|
else => {
|
||||||
_ = it.prev();
|
_ = it.prev();
|
||||||
return try parseCSuffixOpExpr(rp, it, source_loc);
|
return try parseCSuffixOpExpr(rp, it, source_loc);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tokenSlice(c: *Context, token: ast.TokenIndex) []const u8 {
|
||||||
|
const tok = c.tree.tokens.at(token);
|
||||||
|
return c.source_buffer.toSliceConst()[tok.start..tok.end];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getFnDecl(c: *Context, ref: *ast.Node) ?*ast.Node {
|
||||||
|
const init = ref.cast(ast.Node.VarDecl).?.init_node.?;
|
||||||
|
const name = if (init.cast(ast.Node.Identifier)) |id|
|
||||||
|
tokenSlice(c, id.token)
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
// TODO a.b.c
|
||||||
|
if (c.sym_table.get(name)) |kv| {
|
||||||
|
if (kv.value.cast(ast.Node.VarDecl)) |val| {
|
||||||
|
if (val.type_node) |type_node| {
|
||||||
|
if (type_node.cast(ast.Node.PrefixOp)) |casted| {
|
||||||
|
if (casted.rhs.id == .FnProto) {
|
||||||
|
return casted.rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn addMacros(c: *Context) !void {
|
||||||
|
var macro_it = c.macro_table.iterator();
|
||||||
|
while (macro_it.next()) |kv| {
|
||||||
|
if (getFnDecl(c, kv.value)) |proto_node| {
|
||||||
|
// If a macro aliases a global variable which is a function pointer, we conclude that
|
||||||
|
// the macro is intended to represent a function that assumes the function pointer
|
||||||
|
// variable is non-null and calls it.
|
||||||
|
try addTopLevelDecl(c, kv.key, try transCreateNodeMacroFn(c, kv.key, kv.value, proto_node));
|
||||||
|
} else {
|
||||||
|
try addTopLevelDecl(c, kv.key, kv.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -339,6 +339,64 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 0x00000020);
|
\\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 0x00000020);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cases.add_2("generate inline func for #define global extern fn",
|
||||||
|
\\extern void (*fn_ptr)(void);
|
||||||
|
\\#define foo fn_ptr
|
||||||
|
\\
|
||||||
|
\\extern char (*fn_ptr2)(int, float);
|
||||||
|
\\#define bar fn_ptr2
|
||||||
|
, &[_][]const u8{
|
||||||
|
\\pub extern var fn_ptr: ?extern fn () void;
|
||||||
|
,
|
||||||
|
\\pub inline fn foo() void {
|
||||||
|
\\ return fn_ptr.?();
|
||||||
|
\\}
|
||||||
|
,
|
||||||
|
\\pub extern var fn_ptr2: ?extern fn (c_int, f32) u8;
|
||||||
|
,
|
||||||
|
\\pub inline fn bar(arg_1: c_int, arg_2: f32) u8 {
|
||||||
|
\\ return fn_ptr2.?(arg_1, arg_2);
|
||||||
|
\\}
|
||||||
|
});
|
||||||
|
|
||||||
|
cases.add_2("macros with field targets",
|
||||||
|
\\typedef unsigned int GLbitfield;
|
||||||
|
\\typedef void (*PFNGLCLEARPROC) (GLbitfield mask);
|
||||||
|
\\typedef void(*OpenGLProc)(void);
|
||||||
|
\\union OpenGLProcs {
|
||||||
|
\\ OpenGLProc ptr[1];
|
||||||
|
\\ struct {
|
||||||
|
\\ PFNGLCLEARPROC Clear;
|
||||||
|
\\ } gl;
|
||||||
|
\\};
|
||||||
|
\\extern union OpenGLProcs glProcs;
|
||||||
|
\\#define glClearUnion glProcs.gl.Clear
|
||||||
|
\\#define glClearPFN PFNGLCLEARPROC
|
||||||
|
, &[_][]const u8{
|
||||||
|
\\pub const GLbitfield = c_uint;
|
||||||
|
,
|
||||||
|
\\pub const PFNGLCLEARPROC = ?extern fn (GLbitfield) void;
|
||||||
|
,
|
||||||
|
\\pub const OpenGLProc = ?extern fn () void;
|
||||||
|
,
|
||||||
|
\\pub const union_OpenGLProcs = extern union {
|
||||||
|
\\ ptr: [1]OpenGLProc,
|
||||||
|
\\ gl: extern struct {
|
||||||
|
\\ Clear: PFNGLCLEARPROC,
|
||||||
|
\\ },
|
||||||
|
\\};
|
||||||
|
,
|
||||||
|
\\pub extern var glProcs: union_OpenGLProcs;
|
||||||
|
,
|
||||||
|
\\pub const glClearPFN = PFNGLCLEARPROC;
|
||||||
|
// , // TODO
|
||||||
|
// \\pub inline fn glClearUnion(arg_1: GLbitfield) void {
|
||||||
|
// \\ return glProcs.gl.Clear.?(arg_1);
|
||||||
|
// \\}
|
||||||
|
,
|
||||||
|
\\pub const OpenGLProcs = union_OpenGLProcs;
|
||||||
|
});
|
||||||
|
|
||||||
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
|
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
|
||||||
|
|
||||||
cases.add_both("typedef of function in struct field",
|
cases.add_both("typedef of function in struct field",
|
||||||
@ -1844,7 +1902,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
cases.addC(//todo
|
cases.add_both(
|
||||||
"bitwise not on u-suffixed 0 (zero) in macro definition",
|
"bitwise not on u-suffixed 0 (zero) in macro definition",
|
||||||
"#define NOT_ZERO (~0U)",
|
"#define NOT_ZERO (~0U)",
|
||||||
&[_][]const u8{
|
&[_][]const u8{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user