mirror of
https://github.com/ziglang/zig.git
synced 2026-01-03 12:03:19 +00:00
translate-c-2 function calls
This commit is contained in:
parent
c2666c48a4
commit
d54c288bd3
@ -839,6 +839,7 @@ pub extern fn ZigClangFunctionType_getReturnType(self: *const ZigClangFunctionTy
|
||||
pub extern fn ZigClangFunctionProtoType_isVariadic(self: *const struct_ZigClangFunctionProtoType) bool;
|
||||
pub extern fn ZigClangFunctionProtoType_getNumParams(self: *const struct_ZigClangFunctionProtoType) c_uint;
|
||||
pub extern fn ZigClangFunctionProtoType_getParamType(self: *const struct_ZigClangFunctionProtoType, i: c_uint) ZigClangQualType;
|
||||
pub extern fn ZigClangFunctionProtoType_getReturnType(self: *const ZigClangFunctionProtoType) ZigClangQualType;
|
||||
|
||||
pub const ZigClangSourceLocation = struct_ZigClangSourceLocation;
|
||||
pub const ZigClangQualType = struct_ZigClangQualType;
|
||||
@ -993,6 +994,7 @@ pub extern fn ZigClangIncompleteArrayType_getElementType(*const ZigClangIncomple
|
||||
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 ZigClangDeclRefExpr_getFoundDecl(*const ZigClangDeclRefExpr) *const ZigClangNamedDecl;
|
||||
|
||||
pub extern fn ZigClangParenType_getInnerType(*const ZigClangParenType) ZigClangQualType;
|
||||
|
||||
@ -1105,3 +1107,7 @@ pub extern fn ZigClangMemberExpr_getMemberDecl(*const ZigClangMemberExpr) *const
|
||||
pub extern fn ZigClangArraySubscriptExpr_getBase(*const ZigClangArraySubscriptExpr) *const ZigClangExpr;
|
||||
pub extern fn ZigClangArraySubscriptExpr_getIdx(*const ZigClangArraySubscriptExpr) *const ZigClangExpr;
|
||||
|
||||
pub extern fn ZigClangCallExpr_getCallee(*const ZigClangCallExpr) *const ZigClangExpr;
|
||||
pub extern fn ZigClangCallExpr_getNumArgs(*const ZigClangCallExpr) c_uint;
|
||||
pub extern fn ZigClangCallExpr_getArgs(*const ZigClangCallExpr) [*]const *const ZigClangExpr;
|
||||
|
||||
|
||||
@ -851,6 +851,7 @@ fn transStmt(
|
||||
.StmtExprClass => return transStmtExpr(rp, scope, @ptrCast(*const ZigClangStmtExpr, stmt), result_used),
|
||||
.MemberExprClass => return transMemberExpr(rp, scope, @ptrCast(*const ZigClangMemberExpr, stmt), result_used),
|
||||
.ArraySubscriptExprClass => return transArrayAccess(rp, scope, @ptrCast(*const ZigClangArraySubscriptExpr, stmt), result_used),
|
||||
.CallExprClass => return transCallExpr(rp, scope, @ptrCast(*const ZigClangCallExpr, stmt), result_used),
|
||||
else => {
|
||||
return revertAndWarn(
|
||||
rp,
|
||||
@ -2004,6 +2005,73 @@ fn transArrayAccess(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangArrayS
|
||||
return maybeSuppressResult(rp, scope, result_used, &node.base);
|
||||
}
|
||||
|
||||
fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr, result_used: ResultUsed) TransError!*ast.Node {
|
||||
const callee = ZigClangCallExpr_getCallee(stmt);
|
||||
var raw_fn_expr = try transExpr(rp, scope, callee, .used, .r_value);
|
||||
|
||||
var is_ptr = false;
|
||||
const fn_ty = qualTypeGetFnProto(ZigClangExpr_getType(callee), &is_ptr);
|
||||
|
||||
const fn_expr = if (is_ptr and fn_ty != null) blk: {
|
||||
if (ZigClangExpr_getStmtClass(callee) == .ImplicitCastExprClass) {
|
||||
const implicit_cast = @ptrCast(*const ZigClangImplicitCastExpr, callee);
|
||||
|
||||
if (ZigClangImplicitCastExpr_getCastKind(implicit_cast) == .FunctionToPointerDecay) {
|
||||
const subexpr = ZigClangImplicitCastExpr_getSubExpr(implicit_cast);
|
||||
if (ZigClangExpr_getStmtClass(subexpr) == .DeclRefExprClass) {
|
||||
const decl_ref = @ptrCast(*const ZigClangDeclRefExpr, subexpr);
|
||||
const named_decl = ZigClangDeclRefExpr_getFoundDecl(decl_ref);
|
||||
if (ZigClangDecl_getKind(@ptrCast(*const ZigClangDecl, named_decl)) == .Function) {
|
||||
break :blk raw_fn_expr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break :blk try transCreateNodeUnwrapNull(rp.c, raw_fn_expr);
|
||||
} else
|
||||
raw_fn_expr;
|
||||
const node = try transCreateNodeFnCall(rp.c, fn_expr);
|
||||
|
||||
const num_args = ZigClangCallExpr_getNumArgs(stmt);
|
||||
const args = ZigClangCallExpr_getArgs(stmt);
|
||||
var i: usize = 0;
|
||||
while (i < num_args) : (i+=1) {
|
||||
if (i != 0) {
|
||||
_ = try appendToken(rp.c, .Comma, ",");
|
||||
}
|
||||
const arg = try transExpr(rp, scope, args[i], .used, .r_value);
|
||||
try node.op.Call.params.push(arg);
|
||||
}
|
||||
node.rtoken = try appendToken(rp.c, .RParen, ")");
|
||||
|
||||
if (fn_ty) |ty| {
|
||||
const canon = ZigClangQualType_getCanonicalType(ZigClangFunctionProtoType_getReturnType(ty));
|
||||
const ret_ty = ZigClangQualType_getTypePtr(canon);
|
||||
if (ZigClangType_isVoidType(ret_ty)) {
|
||||
_ = try appendToken(rp.c, .Semicolon, ";");
|
||||
return &node.base;
|
||||
}
|
||||
}
|
||||
|
||||
return maybeSuppressResult(rp, scope, result_used, &node.base);
|
||||
}
|
||||
|
||||
fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?*const ZigClangFunctionProtoType {
|
||||
const canon = ZigClangQualType_getCanonicalType(qt);
|
||||
var ty = ZigClangQualType_getTypePtr(canon);
|
||||
is_ptr.* = false;
|
||||
|
||||
if (ZigClangType_getTypeClass(ty) == .Pointer) {
|
||||
is_ptr.* = true;
|
||||
const child_qt = ZigClangType_getPointeeType(ty);
|
||||
ty = ZigClangQualType_getTypePtr(child_qt);
|
||||
}
|
||||
if (ZigClangType_getTypeClass(ty) == .FunctionProto) {
|
||||
return @ptrCast(*const ZigClangFunctionProtoType, ty);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
fn transCPtrCast(
|
||||
rp: RestorePoint,
|
||||
loc: ZigClangSourceLocation,
|
||||
@ -3947,6 +4015,22 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
|
||||
if (it.next().?.id != .RBrace)
|
||||
return error.ParseError;
|
||||
},
|
||||
.LParen => {
|
||||
const call_node = try transCreateNodeFnCall(rp.c, node);
|
||||
while (true) {
|
||||
const arg = try parseCExpr(rp, it, source_loc, scope);
|
||||
try call_node.op.Call.params.push(arg);
|
||||
const next = it.next().?;
|
||||
if (next.id == .Comma)
|
||||
_ = try appendToken(rp.c, .Comma, ",")
|
||||
else if (next.id == .RParen)
|
||||
break
|
||||
else
|
||||
return error.ParseError;
|
||||
}
|
||||
call_node.rtoken = try appendToken(rp.c, .RParen, ")");
|
||||
node = &call_node.base;
|
||||
},
|
||||
else => {
|
||||
_ = it.prev();
|
||||
return node;
|
||||
|
||||
@ -702,6 +702,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC_both("function call",
|
||||
\\static void bar(void) { }
|
||||
\\void foo(int *(baz)(void)) {
|
||||
\\ bar();
|
||||
\\ baz();
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub fn bar() void {}
|
||||
\\pub export fn foo(baz: ?extern fn () [*c]c_int) void {
|
||||
\\ bar();
|
||||
\\ _ = baz.?();
|
||||
\\}
|
||||
});
|
||||
|
||||
/////////////// Cases that pass for only stage2 ////////////////
|
||||
|
||||
cases.add_2("Parameterless function prototypes",
|
||||
@ -1538,6 +1552,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub const ACCESS = array[2];
|
||||
});
|
||||
|
||||
cases.add_2("macro call",
|
||||
\\#define CALL(arg) bar(arg)
|
||||
, &[_][]const u8{
|
||||
\\pub inline fn CALL(arg: var) @TypeOf(bar(arg)) {
|
||||
\\ return bar(arg);
|
||||
\\}
|
||||
});
|
||||
|
||||
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
|
||||
|
||||
cases.addAllowWarnings("simple data types",
|
||||
@ -1728,24 +1750,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("function call",
|
||||
\\static void bar(void) { }
|
||||
\\static int baz(void) { return 0; }
|
||||
\\void foo(void) {
|
||||
\\ bar();
|
||||
\\ baz();
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub fn bar() void {}
|
||||
\\pub fn baz() c_int {
|
||||
\\ return 0;
|
||||
\\}
|
||||
\\pub export fn foo() void {
|
||||
\\ bar();
|
||||
\\ _ = baz();
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("sizeof",
|
||||
\\#include <stddef.h>
|
||||
\\size_t size_of(void) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user