Commit a4a9330648
Changed files (5)
src/zig_clang.cpp
@@ -1625,6 +1625,10 @@ unsigned ZigClangFunctionDecl_getAlignedAttribute(const struct ZigClangFunctionD
return 0;
}
+ZigClangQualType ZigClangParmVarDecl_getOriginalType(const struct ZigClangParmVarDecl *self) {
+ return bitcast(reinterpret_cast<const clang::ParmVarDecl *>(self)->getOriginalType());
+}
+
const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *zig_record_decl) {
const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(zig_record_decl);
const clang::RecordDecl *definition = record_decl->getDefinition();
src/zig_clang.h
@@ -866,6 +866,8 @@ ZIG_EXTERN_C const char* ZigClangVarDecl_getSectionAttribute(const struct ZigCla
ZIG_EXTERN_C unsigned ZigClangVarDecl_getAlignedAttribute(const struct ZigClangVarDecl *self, const ZigClangASTContext* ctx);
ZIG_EXTERN_C unsigned ZigClangFunctionDecl_getAlignedAttribute(const struct ZigClangFunctionDecl *self, const ZigClangASTContext* ctx);
+ZIG_EXTERN_C struct ZigClangQualType ZigClangParmVarDecl_getOriginalType(const struct ZigClangParmVarDecl *self);
+
ZIG_EXTERN_C bool ZigClangRecordDecl_getPackedAttribute(const struct ZigClangRecordDecl *);
ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const struct ZigClangRecordDecl *);
ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const struct ZigClangEnumDecl *);
src-self-hosted/clang.zig
@@ -768,6 +768,7 @@ pub extern fn ZigClangFieldDecl_getCanonicalDecl(field_decl: ?*const struct_ZigC
pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl;
pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl;
pub extern fn ZigClangFunctionDecl_getCanonicalDecl(self: ?*const struct_ZigClangFunctionDecl) ?*const struct_ZigClangFunctionDecl;
+pub extern fn ZigClangParmVarDecl_getOriginalType(self: ?*const struct_ZigClangParmVarDecl) struct_ZigClangQualType;
pub extern fn ZigClangVarDecl_getCanonicalDecl(self: ?*const struct_ZigClangVarDecl) ?*const struct_ZigClangVarDecl;
pub extern fn ZigClangVarDecl_getSectionAttribute(self: *const ZigClangVarDecl, len: *usize) ?[*]const u8;
pub extern fn ZigClangFunctionDecl_getAlignedAttribute(self: *const ZigClangFunctionDecl, *const ZigClangASTContext) c_uint;
src-self-hosted/translate_c.zig
@@ -485,6 +485,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
block_scope.block_node = block_node;
var it = proto_node.params.iterator(0);
+ var param_id: c_uint = 0;
while (it.next()) |p| {
const param = @fieldParentPtr(ast.Node.ParamDecl, "base", p.*);
const param_name = if (param.name_token) |name_tok|
@@ -498,18 +499,27 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
const mangled_param_name = try block_scope.makeMangledName(c, param_name);
+ const c_param = ZigClangFunctionDecl_getParamDecl(fn_decl, param_id);
+ const qual_type = ZigClangParmVarDecl_getOriginalType(c_param);
+ const is_const = ZigClangQualType_isConstQualified(qual_type);
+
const arg_name = blk: {
- const bare_arg_name = try std.fmt.allocPrint(c.a(), "arg_{}", .{mangled_param_name});
+ const param_prefix = if (is_const) "" else "arg_";
+ const bare_arg_name = try std.fmt.allocPrint(c.a(), "{}{}", .{param_prefix, mangled_param_name});
break :blk try block_scope.makeMangledName(c, bare_arg_name);
};
- const node = try transCreateNodeVarDecl(c, false, false, mangled_param_name);
- node.eq_token = try appendToken(c, .Equal, "=");
- node.init_node = try transCreateNodeIdentifier(c, arg_name);
- node.semicolon_token = try appendToken(c, .Semicolon, ";");
- try block_node.statements.push(&node.base);
- param.name_token = try appendIdentifier(c, arg_name);
- _ = try appendToken(c, .Colon, ":");
+ if (!is_const) {
+ const node = try transCreateNodeVarDecl(c, false, false, mangled_param_name);
+ node.eq_token = try appendToken(c, .Equal, "=");
+ node.init_node = try transCreateNodeIdentifier(c, arg_name);
+ node.semicolon_token = try appendToken(c, .Semicolon, ";");
+ try block_node.statements.push(&node.base);
+ param.name_token = try appendIdentifier(c, arg_name);
+ _ = try appendToken(c, .Colon, ":");
+ }
+
+ param_id += 1;
}
transCompoundStmtInline(rp, &block_scope.base, @ptrCast(*const ZigClangCompoundStmt, body_stmt), block_node) catch |err| switch (err) {
test/translate_c.zig
@@ -2615,4 +2615,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return foo((@intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(c)))) != @intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(b))))));
\\}
});
+
+ cases.add("Don't make const parameters mutable",
+ \\int max(const int x, int y) {
+ \\ return (x > y) ? x : y;
+ \\}
+ , &[_][]const u8{
+ \\pub export fn max(x: c_int, arg_y: c_int) c_int {
+ \\ var y = arg_y;
+ \\ return if (x > y) x else y;
+ \\}
+ });
+
}