From fceedada5c18ca5e9fa3ca14e74f6722eda85600 Mon Sep 17 00:00:00 2001 From: hryx Date: Sun, 26 May 2019 15:43:13 -0700 Subject: [PATCH 01/35] WIP translate var decl --- src-self-hosted/clang.zig | 5 +++ src-self-hosted/translate_c.zig | 79 +++++++++++++++++++++++++++++++++ src/zig_clang.cpp | 18 +++++++- src/zig_clang.h | 6 ++- 4 files changed, 106 insertions(+), 2 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 92fe7b7cd..bb87589c0 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -864,3 +864,8 @@ pub const ZigClangCompoundStmt_const_body_iterator = [*c]const *struct_ZigClangS pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator; pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator; + +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; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 9f42f198b..6b70dfacf 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -323,6 +323,7 @@ fn transStmt( const sc = ZigClangStmt_getStmtClass(stmt); switch (sc) { .CompoundStmtClass => return transCompoundStmt(rp, scope, @ptrCast(*const ZigClangCompoundStmt, stmt)), + .DeclStmtClass => return transDeclStmt(rp, scope, @ptrCast(*const ZigClangDeclStmt, stmt)), else => { return revertAndWarn( rp, @@ -368,6 +369,84 @@ fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompo }; } +fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) !TransResult { + const c = rp.c; + const block_scope = findBlockScope(scope); + var it = ZigClangDeclStmt_decl_begin(stmt); + const end_it = ZigClangDeclStmt_decl_end(stmt); + while (it != end_it) : (it += 1) { + switch (ZigClangDecl_getKind(it.*)) { + .Var => { + const var_decl = @ptrCast(*const ZigClangVarDecl, it.*); + + // TODO: + // const thread_local_token = if (ZigClangVarDecl_getTLSKind() == .None) + // null + // else + // try appendToken(c, .Keyword_threadlocal, "threadlocal"); + const thread_local_token: ?ast.TokenIndex = null; + // TODO: + // const mut_token = if (ZigClangQualType_isConstQualified(qual_type)) + // try appendToken(c, .Keyword_const, "const") + // else + // try appendToken(c, .Keyword_var, "var"); + const mut_token = try appendToken(c, .Keyword_var, "var"); + const name_token = blk: { + const name = try c.str(ZigClangDecl_getName_bytes_begin( + @ptrCast(*const ZigClangDecl, var_decl), + )); + break :blk try appendToken(c, .Identifier, name); + }; + const eq_token = try appendToken(c, .Equal, "="); + // TODO: init_node + const init_node: ?*ast.Node = null; + const semicolon_token = try appendToken(c, .Semicolon, ";"); + + const node = try rp.c.a().create(ast.Node.VarDecl); + node.* = ast.Node.VarDecl{ + .base = ast.Node{ .id = .VarDecl }, + .doc_comments = null, + .visib_token = null, + .thread_local_token = thread_local_token, + .name_token = name_token, + .eq_token = eq_token, + .mut_token = mut_token, + .comptime_token = null, // TODO IsConstexpr ? + .extern_export_token = null, // TODO ?TokenIndex, + .lib_name = null, // TODO ?*Node, + .type_node = null, // TODO ?*Node, + .align_node = null, // TODO ?*Node, + .section_node = null, // TODO ?*Node, + .init_node = init_node, + .semicolon_token = semicolon_token, + }; + try block_scope.block_node.statements.push(&node.base); + }, + + else => |kind| return revertAndWarn( + rp, + error.UnsupportedTranslation, + ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt)), + "TODO implement translation of DeclStmt kind {}", + @tagName(kind), + ), + } + } + + return TransResult{ + .node = &block_scope.block_node.base, + .node_scope = scope, + .child_scope = scope, + }; +} + +fn findBlockScope(inner: *Scope) *Scope.Block { + var scope = inner; + while (true) : (scope = scope.parent orelse unreachable) { + if (scope.id == .Block) return @fieldParentPtr(Scope.Block, "base", scope); + } +} + fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void { try c.tree.root_node.decls.push(decl_node); } diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 28062ea69..9fca49e77 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1331,6 +1331,12 @@ static ZigClangCompoundStmt_const_body_iterator bitcast(clang::CompoundStmt::con return dest; } +static_assert(sizeof(ZigClangDeclStmt_const_decl_iterator) == sizeof(clang::DeclStmt::const_decl_iterator), ""); +static ZigClangDeclStmt_const_decl_iterator bitcast(clang::DeclStmt::const_decl_iterator src) { + ZigClangDeclStmt_const_decl_iterator dest; + memcpy(&dest, static_cast(&src), sizeof(ZigClangDeclStmt_const_decl_iterator)); + return dest; +} ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const ZigClangSourceManager *self, ZigClangSourceLocation Loc) @@ -1381,7 +1387,7 @@ ZigClangSourceManager *ZigClangASTUnit_getSourceManager(ZigClangASTUnit *self) { return reinterpret_cast(result); } -bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *self, void *context, +bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *self, void *context, bool (*Fn)(void *context, const ZigClangDecl *decl)) { return reinterpret_cast(self)->visitLocalTopLevelDecls(context, @@ -1862,6 +1868,16 @@ ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_end(const str return bitcast(casted->body_end()); } +ZigClangDeclStmt_const_decl_iterator ZigClangDeclStmt_decl_begin(const struct ZigClangDeclStmt *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->decl_begin()); +} + +ZigClangDeclStmt_const_decl_iterator ZigClangDeclStmt_decl_end(const struct ZigClangDeclStmt *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->decl_end()); +} + unsigned ZigClangAPFloat_convertToHexString(const ZigClangAPFloat *self, char *DST, unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM) { diff --git a/src/zig_clang.h b/src/zig_clang.h index 1bdf34fc2..7698de5aa 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -105,6 +105,7 @@ struct ZigClangFunctionType; struct ZigClangPredefinedExpr; typedef struct ZigClangStmt *const * ZigClangCompoundStmt_const_body_iterator; +typedef struct ZigClangDecl *const * ZigClangDeclStmt_const_decl_iterator; enum ZigClangBO { ZigClangBO_PtrMemD, @@ -754,7 +755,7 @@ ZIG_EXTERN_C void ZigClangErrorMsg_delete(struct Stage2ErrorMsg *ptr, size_t len ZIG_EXTERN_C struct ZigClangASTContext *ZigClangASTUnit_getASTContext(struct ZigClangASTUnit *); ZIG_EXTERN_C struct ZigClangSourceManager *ZigClangASTUnit_getSourceManager(struct ZigClangASTUnit *); -ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(struct ZigClangASTUnit *, void *context, +ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(struct ZigClangASTUnit *, void *context, bool (*Fn)(void *context, const struct ZigClangDecl *decl)); ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordType_getDecl(const struct ZigClangRecordType *record_ty); @@ -846,6 +847,9 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionProtoType_getParamType(cons ZIG_EXTERN_C ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_begin(const struct ZigClangCompoundStmt *self); ZIG_EXTERN_C ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_end(const struct ZigClangCompoundStmt *self); +ZIG_EXTERN_C ZigClangDeclStmt_const_decl_iterator ZigClangDeclStmt_decl_begin(const struct ZigClangDeclStmt *self); +ZIG_EXTERN_C ZigClangDeclStmt_const_decl_iterator ZigClangDeclStmt_decl_end(const struct ZigClangDeclStmt *self); + ZIG_EXTERN_C unsigned ZigClangAPFloat_convertToHexString(const struct ZigClangAPFloat *self, char *DST, unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM); From 99f0b28d3946a1110df235bb8d3b1918afc08df8 Mon Sep 17 00:00:00 2001 From: hryx Date: Sun, 26 May 2019 16:51:25 -0700 Subject: [PATCH 02/35] var decl: mut_token, create child scope --- src-self-hosted/clang.zig | 1 + src-self-hosted/translate_c.zig | 40 +++++++++++++++++++++------------ src/zig_clang.cpp | 5 +++++ src/zig_clang.h | 2 ++ 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index bb87589c0..c44f047f4 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -509,6 +509,7 @@ pub extern fn ZigClangAPSInt_getRawData(self: ?*const struct_ZigClangAPSInt) [*c pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_uint; pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr; pub extern fn ZigClangASTUnit_delete(arg0: ?*struct_ZigClangASTUnit) void; +pub extern fn ZigClangVarDecl_getType(self: ?*const struct_ZigClangVarDecl) struct_ZigClangQualType; pub extern fn ZigClangFunctionDecl_getType(self: *const ZigClangFunctionDecl) struct_ZigClangQualType; pub extern fn ZigClangFunctionDecl_getLocation(self: *const ZigClangFunctionDecl) struct_ZigClangSourceLocation; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 6b70dfacf..a3552cd18 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -369,9 +369,11 @@ fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompo }; } -fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) !TransResult { +fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDeclStmt) !TransResult { const c = rp.c; - const block_scope = findBlockScope(scope); + const block_scope = findBlockScope(parent_scope); + var scope = parent_scope; + var it = ZigClangDeclStmt_decl_begin(stmt); const end_it = ZigClangDeclStmt_decl_end(stmt); while (it != end_it) : (it += 1) { @@ -385,23 +387,33 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) // else // try appendToken(c, .Keyword_threadlocal, "threadlocal"); const thread_local_token: ?ast.TokenIndex = null; - // TODO: - // const mut_token = if (ZigClangQualType_isConstQualified(qual_type)) - // try appendToken(c, .Keyword_const, "const") - // else - // try appendToken(c, .Keyword_var, "var"); - const mut_token = try appendToken(c, .Keyword_var, "var"); - const name_token = blk: { - const name = try c.str(ZigClangDecl_getName_bytes_begin( - @ptrCast(*const ZigClangDecl, var_decl), - )); - break :blk try appendToken(c, .Identifier, name); + const qual_type = ZigClangVarDecl_getType(var_decl); + const mut_token = if (ZigClangQualType_isConstQualified(qual_type)) + try appendToken(c, .Keyword_const, "const") + else + try appendToken(c, .Keyword_var, "var"); + const name_type = struct { + str: []const u8, + token: ast.TokenIndex, }; + const c_name = try c.str(ZigClangDecl_getName_bytes_begin( + @ptrCast(*const ZigClangDecl, var_decl), + )); + const name_token = try appendToken(c, .Identifier, c_name); const eq_token = try appendToken(c, .Equal, "="); - // TODO: init_node + // TODO: + // const init_node = ZigClangVarDecl_getInit(); const init_node: ?*ast.Node = null; const semicolon_token = try appendToken(c, .Semicolon, ";"); + const var_scope = try c.a().create(Scope.Var); + var_scope.* = Scope.Var{ + .base = Scope{ .id = .Var, .parent = parent_scope }, + .c_name = c_name, + .zig_name = c_name, // TODO: getWantedName + }; + scope = &var_scope.base; + const node = try rp.c.a().create(ast.Node.VarDecl); node.* = ast.Node.VarDecl{ .base = ast.Node{ .id = .VarDecl }, diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 9fca49e77..1933725b1 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1821,6 +1821,11 @@ void ZigClangASTUnit_delete(struct ZigClangASTUnit *self) { delete reinterpret_cast(self); } +struct ZigClangQualType ZigClangVarDecl_getType(const struct ZigClangVarDecl *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getType()); +} + enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBuiltinType *self) { auto casted = reinterpret_cast(self); return (ZigClangBuiltinTypeKind)casted->getKind(); diff --git a/src/zig_clang.h b/src/zig_clang.h index 7698de5aa..2312c975d 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -753,6 +753,8 @@ ZIG_EXTERN_C struct ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **ar ZIG_EXTERN_C void ZigClangASTUnit_delete(struct ZigClangASTUnit *); ZIG_EXTERN_C void ZigClangErrorMsg_delete(struct Stage2ErrorMsg *ptr, size_t len); +ZIG_EXTERN_C struct ZigClangQualType ZigClangVarDecl_getType(const struct ZigClangVarDecl *); + ZIG_EXTERN_C struct ZigClangASTContext *ZigClangASTUnit_getASTContext(struct ZigClangASTUnit *); ZIG_EXTERN_C struct ZigClangSourceManager *ZigClangASTUnit_getSourceManager(struct ZigClangASTUnit *); ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(struct ZigClangASTUnit *, void *context, From c79b8aeaef860528da645b956f21c8d95d05880d Mon Sep 17 00:00:00 2001 From: hryx Date: Sun, 26 May 2019 17:05:49 -0700 Subject: [PATCH 03/35] var decl: threadlocal --- src-self-hosted/clang.zig | 7 +++++++ src-self-hosted/translate_c.zig | 10 ++++------ src/zig_clang.cpp | 5 +++++ src/zig_clang.h | 8 ++++++++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index c44f047f4..fd5c09dd1 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -870,3 +870,10 @@ 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_getTLSKind(self: ?*const struct_ZigClangVarDecl) ZigClangVarDecl_TLSKind; +pub const ZigClangVarDecl_TLSKind = extern enum { + None, + Static, + Dynamic, +}; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index a3552cd18..77a0589fe 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -381,12 +381,10 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe .Var => { const var_decl = @ptrCast(*const ZigClangVarDecl, it.*); - // TODO: - // const thread_local_token = if (ZigClangVarDecl_getTLSKind() == .None) - // null - // else - // try appendToken(c, .Keyword_threadlocal, "threadlocal"); - const thread_local_token: ?ast.TokenIndex = null; + const thread_local_token = if (ZigClangVarDecl_getTLSKind(var_decl) == .None) + null + else + try appendToken(c, .Keyword_threadlocal, "threadlocal"); const qual_type = ZigClangVarDecl_getType(var_decl); const mut_token = if (ZigClangQualType_isConstQualified(qual_type)) try appendToken(c, .Keyword_const, "const") diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 1933725b1..e86dbed27 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1459,6 +1459,11 @@ const char *ZigClangDecl_getDeclKindName(const struct ZigClangDecl *self) { return casted->getDeclKindName(); } +enum ZigClangVarDecl_TLSKind ZigClangVarDecl_getTLSKind(const ZigClangVarDecl *self) { + auto casted = reinterpret_cast(self); + return (ZigClangVarDecl_TLSKind)casted->getTLSKind(); +} + ZigClangSourceLocation ZigClangRecordDecl_getLocation(const ZigClangRecordDecl *zig_record_decl) { const clang::RecordDecl *record_decl = reinterpret_cast(zig_record_decl); return bitcast(record_decl->getLocation()); diff --git a/src/zig_clang.h b/src/zig_clang.h index 2312c975d..fd3a732cb 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -733,6 +733,12 @@ enum ZigClangStringLiteral_StringKind { ZigClangStringLiteral_StringKind_UTF32, }; +enum ZigClangVarDecl_TLSKind { + ZigClangVarDecl_TLSKind_None, + ZigClangVarDecl_TLSKind_Static, + ZigClangVarDecl_TLSKind_Dynamic, +}; + ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const struct ZigClangSourceManager *, struct ZigClangSourceLocation Loc); ZIG_EXTERN_C const char *ZigClangSourceManager_getFilename(const struct ZigClangSourceManager *, @@ -792,6 +798,8 @@ ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const struct ZigClangD ZIG_EXTERN_C enum ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *decl); ZIG_EXTERN_C const char *ZigClangDecl_getDeclKindName(const struct ZigClangDecl *decl); +ZIG_EXTERN_C enum ZigClangVarDecl_TLSKind ZigClangVarDecl_getTLSKind(const struct ZigClangVarDecl *var_decl); + ZIG_EXTERN_C bool ZigClangSourceLocation_eq(struct ZigClangSourceLocation a, struct ZigClangSourceLocation b); ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const struct ZigClangTypedefType *); From 1a8f8c6262e68ece9dedd875b9a20b619f73035f Mon Sep 17 00:00:00 2001 From: hryx Date: Sun, 26 May 2019 17:36:47 -0700 Subject: [PATCH 04/35] var decl: init node --- src-self-hosted/clang.zig | 3 ++- src-self-hosted/translate_c.zig | 21 ++++++++++++++++----- src/zig_clang.cpp | 15 ++++++++++----- src/zig_clang.h | 4 ++-- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index fd5c09dd1..888d45999 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -509,7 +509,6 @@ pub extern fn ZigClangAPSInt_getRawData(self: ?*const struct_ZigClangAPSInt) [*c pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_uint; pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr; pub extern fn ZigClangASTUnit_delete(arg0: ?*struct_ZigClangASTUnit) void; -pub extern fn ZigClangVarDecl_getType(self: ?*const struct_ZigClangVarDecl) struct_ZigClangQualType; pub extern fn ZigClangFunctionDecl_getType(self: *const ZigClangFunctionDecl) struct_ZigClangQualType; pub extern fn ZigClangFunctionDecl_getLocation(self: *const ZigClangFunctionDecl) struct_ZigClangSourceLocation; @@ -871,6 +870,8 @@ 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_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; pub const ZigClangVarDecl_TLSKind = extern enum { None, diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 77a0589fe..efdeaa3af 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -398,11 +398,6 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe @ptrCast(*const ZigClangDecl, var_decl), )); const name_token = try appendToken(c, .Identifier, c_name); - const eq_token = try appendToken(c, .Equal, "="); - // TODO: - // const init_node = ZigClangVarDecl_getInit(); - const init_node: ?*ast.Node = null; - const semicolon_token = try appendToken(c, .Semicolon, ";"); const var_scope = try c.a().create(Scope.Var); var_scope.* = Scope.Var{ @@ -412,6 +407,13 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe }; scope = &var_scope.base; + const eq_token = try appendToken(c, .Equal, "="); + const init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr| + (try transExpr(rp, scope, expr)).node + else + null; + const semicolon_token = try appendToken(c, .Semicolon, ";"); + const node = try rp.c.a().create(ast.Node.VarDecl); node.* = ast.Node.VarDecl{ .base = ast.Node{ .id = .VarDecl }, @@ -450,6 +452,15 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe }; } +fn transExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangExpr) !TransResult { + return revertAndWarn( + rp, + error.UnsupportedTranslation, + ZigClangExpr_getBeginLoc(expr), + "TODO implement translation of Expr", + ); +} + fn findBlockScope(inner: *Scope) *Scope.Block { var scope = inner; while (true) : (scope = scope.parent orelse unreachable) { diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index e86dbed27..9b725710a 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1459,11 +1459,6 @@ const char *ZigClangDecl_getDeclKindName(const struct ZigClangDecl *self) { return casted->getDeclKindName(); } -enum ZigClangVarDecl_TLSKind ZigClangVarDecl_getTLSKind(const ZigClangVarDecl *self) { - auto casted = reinterpret_cast(self); - return (ZigClangVarDecl_TLSKind)casted->getTLSKind(); -} - ZigClangSourceLocation ZigClangRecordDecl_getLocation(const ZigClangRecordDecl *zig_record_decl) { const clang::RecordDecl *record_decl = reinterpret_cast(zig_record_decl); return bitcast(record_decl->getLocation()); @@ -1831,6 +1826,16 @@ struct ZigClangQualType ZigClangVarDecl_getType(const struct ZigClangVarDecl *se return bitcast(casted->getType()); } +const struct ZigClangExpr *ZigClangVarDecl_getInit(const struct ZigClangVarDecl *self) { + auto casted = reinterpret_cast(self); + return reinterpret_cast(casted->getInit()); +} + +enum ZigClangVarDecl_TLSKind ZigClangVarDecl_getTLSKind(const ZigClangVarDecl *self) { + auto casted = reinterpret_cast(self); + return (ZigClangVarDecl_TLSKind)casted->getTLSKind(); +} + enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBuiltinType *self) { auto casted = reinterpret_cast(self); return (ZigClangBuiltinTypeKind)casted->getKind(); diff --git a/src/zig_clang.h b/src/zig_clang.h index fd3a732cb..1c71f2eb9 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -759,8 +759,6 @@ ZIG_EXTERN_C struct ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **ar ZIG_EXTERN_C void ZigClangASTUnit_delete(struct ZigClangASTUnit *); ZIG_EXTERN_C void ZigClangErrorMsg_delete(struct Stage2ErrorMsg *ptr, size_t len); -ZIG_EXTERN_C struct ZigClangQualType ZigClangVarDecl_getType(const struct ZigClangVarDecl *); - ZIG_EXTERN_C struct ZigClangASTContext *ZigClangASTUnit_getASTContext(struct ZigClangASTUnit *); ZIG_EXTERN_C struct ZigClangSourceManager *ZigClangASTUnit_getSourceManager(struct ZigClangASTUnit *); ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(struct ZigClangASTUnit *, void *context, @@ -798,6 +796,8 @@ ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const struct ZigClangD ZIG_EXTERN_C enum ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *decl); ZIG_EXTERN_C const char *ZigClangDecl_getDeclKindName(const struct ZigClangDecl *decl); +ZIG_EXTERN_C struct ZigClangQualType ZigClangVarDecl_getType(const struct ZigClangVarDecl *); +ZIG_EXTERN_C const struct ZigClangExpr *ZigClangVarDecl_getInit(const struct ZigClangVarDecl *var_decl); ZIG_EXTERN_C enum ZigClangVarDecl_TLSKind ZigClangVarDecl_getTLSKind(const struct ZigClangVarDecl *var_decl); ZIG_EXTERN_C bool ZigClangSourceLocation_eq(struct ZigClangSourceLocation a, struct ZigClangSourceLocation b); From 9c437f90327880a195f1090f726118a8f6742bc6 Mon Sep 17 00:00:00 2001 From: hryx Date: Sun, 26 May 2019 19:14:50 -0700 Subject: [PATCH 05/35] var decl: ImplicitCastExpr --- src-self-hosted/clang.zig | 2 ++ src-self-hosted/translate_c.zig | 36 ++++++++++++++++++++++++--------- src/zig_clang.cpp | 5 +++++ src/zig_clang.h | 3 +++ 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 888d45999..e1b7c526b 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -878,3 +878,5 @@ pub const ZigClangVarDecl_TLSKind = extern enum { Static, Dynamic, }; + +pub extern fn ZigClangImplicitCastExpr_getCastKind(*const ZigClangImplicitCastExpr) ZigClangCK; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index efdeaa3af..50663537e 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -324,6 +324,7 @@ fn transStmt( switch (sc) { .CompoundStmtClass => return transCompoundStmt(rp, scope, @ptrCast(*const ZigClangCompoundStmt, stmt)), .DeclStmtClass => return transDeclStmt(rp, scope, @ptrCast(*const ZigClangDeclStmt, stmt)), + .ImplicitCastExprClass => return transImplicitCastExpr(rp, scope, @ptrCast(*const ZigClangImplicitCastExpr, stmt)), else => { return revertAndWarn( rp, @@ -409,7 +410,7 @@ 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)).node + (try transExpr(rp, scope, expr, .used, .r_value)).node else null; const semicolon_token = try appendToken(c, .Semicolon, ";"); @@ -423,7 +424,7 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe .name_token = name_token, .eq_token = eq_token, .mut_token = mut_token, - .comptime_token = null, // TODO IsConstexpr ? + .comptime_token = null, .extern_export_token = null, // TODO ?TokenIndex, .lib_name = null, // TODO ?*Node, .type_node = null, // TODO ?*Node, @@ -452,13 +453,30 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe }; } -fn transExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangExpr) !TransResult { - return revertAndWarn( - rp, - error.UnsupportedTranslation, - ZigClangExpr_getBeginLoc(expr), - "TODO implement translation of Expr", - ); +fn transImplicitCastExpr( + rp: RestorePoint, + scope: *Scope, + expr: *const ZigClangImplicitCastExpr, +) !TransResult { + switch (ZigClangImplicitCastExpr_getCastKind(@ptrCast(*const ZigClangImplicitCastExpr, expr))) { + else => |kind| return revertAndWarn( + rp, + error.UnsupportedTranslation, + ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, expr)), + "TODO implement translation of CastKind {}", + @tagName(kind), + ), + } +} + +fn transExpr( + rp: RestorePoint, + scope: *Scope, + expr: *const ZigClangExpr, + used: ResultUsed, + lrvalue: LRValue, +) TransError!TransResult { + return transStmt(rp, scope, @ptrCast(*const ZigClangStmt, expr), used, lrvalue); } fn findBlockScope(inner: *Scope) *Scope.Block { diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 9b725710a..6077878b2 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1919,3 +1919,8 @@ const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName( const clang::StringLiteral *result = casted->getFunctionName(); return reinterpret_cast(result); } + +enum ZigClangCK ZigClangImplicitCastExpr_getCastKind(const struct ZigClangImplicitCastExpr *self) { + auto casted = reinterpret_cast(self); + return (ZigClangCK)casted->getCastKind(); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index 1c71f2eb9..d6d193223 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -869,4 +869,7 @@ ZIG_EXTERN_C const char *ZigClangStringLiteral_getString_bytes_begin_size(const ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName( const struct ZigClangPredefinedExpr *self); + +ZIG_EXTERN_C enum ZigClangCK ZigClangImplicitCastExpr_getCastKind(const struct ZigClangImplicitCastExpr *); + #endif From 3bbee1ba2e758d4bb5ea7d03b27133ffd6e4e9e2 Mon Sep 17 00:00:00 2001 From: hryx Date: Mon, 27 May 2019 14:38:09 -0700 Subject: [PATCH 06/35] expr: BitCast for ImplicitCastExpr --- src-self-hosted/clang.zig | 4 ++++ src-self-hosted/translate_c.zig | 39 ++++++++++++++++++++++++++++++++- src/zig_clang.cpp | 17 +++++++++++++- src/zig_clang.h | 4 ++++ 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index e1b7c526b..ea8f3a6cc 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -879,4 +879,8 @@ pub const ZigClangVarDecl_TLSKind = extern enum { Dynamic, }; +pub extern fn ZigClangImplicitCastExpr_getBeginLoc(*const ZigClangImplicitCastExpr) ZigClangSourceLocation; pub extern fn ZigClangImplicitCastExpr_getCastKind(*const ZigClangImplicitCastExpr) ZigClangCK; +pub extern fn ZigClangImplicitCastExpr_getSubExpr(*const ZigClangImplicitCastExpr) *const ZigClangExpr; + +pub extern fn ZigClangArrayType_getElementType(*const ZigClangArrayType) ZigClangQualType; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 50663537e..757f07153 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -107,6 +107,7 @@ const Context = struct { decl_table: DeclTable, global_scope: *Scope.Root, mode: Mode, + clang_context: *ZigClangASTContext, fn a(c: *Context) *std.mem.Allocator { return &c.tree.arena_allocator.allocator; @@ -183,6 +184,7 @@ pub fn translate( .decl_table = DeclTable.init(arena), .global_scope = try arena.create(Scope.Root), .mode = mode, + .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?, }; context.global_scope.* = Scope.Root{ .base = Scope{ @@ -458,7 +460,14 @@ fn transImplicitCastExpr( scope: *Scope, expr: *const ZigClangImplicitCastExpr, ) !TransResult { - switch (ZigClangImplicitCastExpr_getCastKind(@ptrCast(*const ZigClangImplicitCastExpr, expr))) { + const c = rp.c; + switch (ZigClangImplicitCastExpr_getCastKind(expr)) { + .BitCast => { + const node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, expr), .used, .r_value); + const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr)); + const src_type = getExprQualType(c, ZigClangImplicitCastExpr_getSubExpr(expr)); + return try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, node.node); + }, else => |kind| return revertAndWarn( rp, error.UnsupportedTranslation, @@ -469,6 +478,17 @@ fn transImplicitCastExpr( } } +fn transCCast( + rp: RestorePoint, + scope: *Scope, + loc: ZigClangSourceLocation, + dst_type: ZigClangQualType, + src_type: ZigClangQualType, + target_node: *ast.Node, +) !TransResult { + return revertAndWarn(rp, error.UnsupportedTranslation, loc, "TODO implement translation of C cast"); +} + fn transExpr( rp: RestorePoint, scope: *Scope, @@ -499,6 +519,23 @@ fn qualTypeCanon(qt: ZigClangQualType) *const ZigClangType { return ZigClangQualType_getTypePtr(canon); } +fn getExprQualType(c: *Context, expr: *const ZigClangExpr) ZigClangQualType { + blk: { + // If this is a C `char *`, turn it into a `const char *` + if (ZigClangExpr_getStmtClass(expr) != .ImplicitCastExprClass) break :blk; + const cast_expr = @ptrCast(*const ZigClangImplicitCastExpr, expr); + if (ZigClangImplicitCastExpr_getCastKind(cast_expr) != .ArrayToPointerDecay) break :blk; + const sub_expr = ZigClangImplicitCastExpr_getSubExpr(cast_expr); + if (ZigClangExpr_getStmtClass(sub_expr) != .StringLiteralClass) break :blk; + const array_qt = ZigClangExpr_getType(sub_expr); + const array_type = @ptrCast(*const ZigClangArrayType, ZigClangQualType_getTypePtr(array_qt)); + var pointee_qt = ZigClangArrayType_getElementType(array_type); + ZigClangQualType_addConst(&pointee_qt); + return ZigClangASTContext_getPointerType(c.clang_context, pointee_qt); + } + return ZigClangExpr_getType(expr); +} + const RestorePoint = struct { c: *Context, token_index: ast.TokenIndex, diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 6077878b2..2edfda8ef 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1920,7 +1920,22 @@ const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName( return reinterpret_cast(result); } +ZigClangSourceLocation ZigClangImplicitCastExpr_getBeginLoc(const struct ZigClangImplicitCastExpr *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getBeginLoc()); +} + enum ZigClangCK ZigClangImplicitCastExpr_getCastKind(const struct ZigClangImplicitCastExpr *self) { - auto casted = reinterpret_cast(self); + auto casted = reinterpret_cast(self); return (ZigClangCK)casted->getCastKind(); } + +const struct ZigClangExpr *ZigClangImplicitCastExpr_getSubExpr(const struct ZigClangImplicitCastExpr *self) { + auto casted = reinterpret_cast(self); + return reinterpret_cast(casted->getSubExpr()); +} + +struct ZigClangQualType ZigClangArrayType_getElementType(const struct ZigClangArrayType *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getElementType()); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index d6d193223..0afe30c47 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -870,6 +870,10 @@ ZIG_EXTERN_C const char *ZigClangStringLiteral_getString_bytes_begin_size(const ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName( const struct ZigClangPredefinedExpr *self); +ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangImplicitCastExpr_getBeginLoc(const struct ZigClangImplicitCastExpr *); ZIG_EXTERN_C enum ZigClangCK ZigClangImplicitCastExpr_getCastKind(const struct ZigClangImplicitCastExpr *); +ZIG_EXTERN_C const struct ZigClangExpr *ZigClangImplicitCastExpr_getSubExpr(const struct ZigClangImplicitCastExpr *); + +ZIG_EXTERN_C struct ZigClangQualType ZigClangArrayType_getElementType(const struct ZigClangArrayType *); #endif From 2aa1c5da5dded6b1b346c3a1b57443f2c459ebe9 Mon Sep 17 00:00:00 2001 From: hryx Date: Mon, 27 May 2019 15:58:21 -0700 Subject: [PATCH 07/35] Remove unused local struct type --- src-self-hosted/translate_c.zig | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 757f07153..fe5022c0c 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -393,10 +393,6 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe try appendToken(c, .Keyword_const, "const") else try appendToken(c, .Keyword_var, "var"); - const name_type = struct { - str: []const u8, - token: ast.TokenIndex, - }; const c_name = try c.str(ZigClangDecl_getName_bytes_begin( @ptrCast(*const ZigClangDecl, var_decl), )); @@ -417,7 +413,7 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe null; const semicolon_token = try appendToken(c, .Semicolon, ";"); - const node = try rp.c.a().create(ast.Node.VarDecl); + const node = try c.a().create(ast.Node.VarDecl); node.* = ast.Node.VarDecl{ .base = ast.Node{ .id = .VarDecl }, .doc_comments = null, From 22299869baaa4e65c3dae48b292b1bd8bd4b1c58 Mon Sep 17 00:00:00 2001 From: hryx Date: Mon, 27 May 2019 17:54:40 -0700 Subject: [PATCH 08/35] Prevent infinite recursion --- src-self-hosted/translate_c.zig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 3b60e6575..e33013e1c 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -459,9 +459,10 @@ fn transImplicitCastExpr( const c = rp.c; switch (ZigClangImplicitCastExpr_getCastKind(expr)) { .BitCast => { - const node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, expr), .used, .r_value); + const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr); + const node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value); const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr)); - const src_type = getExprQualType(c, ZigClangImplicitCastExpr_getSubExpr(expr)); + const src_type = getExprQualType(c, sub_expr); return try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, node.node); }, else => |kind| return revertAndWarn( From e07888e54c251b6c493ea911cf65aa46eccba67d Mon Sep 17 00:00:00 2001 From: hryx Date: Mon, 27 May 2019 18:18:27 -0700 Subject: [PATCH 09/35] expr: FunctionToPointerDecay & ArrayToPointerDecay for ImplicitCastExpr --- src-self-hosted/translate_c.zig | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index e33013e1c..2ccd4eca6 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -457,14 +457,22 @@ fn transImplicitCastExpr( expr: *const ZigClangImplicitCastExpr, ) !TransResult { const c = rp.c; + const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr); switch (ZigClangImplicitCastExpr_getCastKind(expr)) { .BitCast => { - const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr); const node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value); const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr)); const src_type = getExprQualType(c, sub_expr); return try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, node.node); }, + .FunctionToPointerDecay, .ArrayToPointerDecay => { + return maybeSuppressResult( + rp, + scope, + .used, + try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value), + ); + }, else => |kind| return revertAndWarn( rp, error.UnsupportedTranslation, @@ -503,6 +511,30 @@ fn findBlockScope(inner: *Scope) *Scope.Block { } } +fn maybeSuppressResult( + rp: RestorePoint, + scope: *Scope, + used: ResultUsed, + result: TransResult, +) !TransResult { + if (used == .used) return result; + const lhs = try appendIdentifier(rp.c, "_"); + const op_token = try appendToken(rp.c, .Equal, "="); + const op_node = try rp.c.a().create(ast.Node.InfixOp); + op_node.* = ast.Node.InfixOp{ + .base = ast.Node{ .id = .InfixOp }, + .op_token = op_token, + .lhs = lhs, + .op = .Assign, + .rhs = result.node, + }; + return TransResult{ + .node = &op_node.base, + .child_scope = scope, + .node_scope = scope, + }; +} + fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void { try c.tree.root_node.decls.push(decl_node); } From b558d0996a8a18475f91483d3e3962502422a315 Mon Sep 17 00:00:00 2001 From: hryx Date: Mon, 27 May 2019 19:20:23 -0700 Subject: [PATCH 10/35] expr: DeclRefExpr --- src-self-hosted/clang.zig | 2 ++ src-self-hosted/translate_c.zig | 31 +++++++++++++++++++++++++++++++ src/zig_clang.cpp | 5 +++++ src/zig_clang.h | 2 ++ 4 files changed, 40 insertions(+) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index ea8f3a6cc..d1fe5153b 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -884,3 +884,5 @@ 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 ZigClangDeclRefExpr_getDecl(*const ZigClangDeclRefExpr) *const ZigClangValueDecl; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 2ccd4eca6..ffb325d19 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -107,6 +107,7 @@ const Context = struct { decl_table: DeclTable, global_scope: *Scope.Root, mode: Mode, + ptr_params: std.BufSet, clang_context: *ZigClangASTContext, fn a(c: *Context) *std.mem.Allocator { @@ -184,6 +185,7 @@ pub fn translate( .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).?, }; context.global_scope.* = Scope.Root{ @@ -326,6 +328,7 @@ fn transStmt( switch (sc) { .CompoundStmtClass => return transCompoundStmt(rp, scope, @ptrCast(*const ZigClangCompoundStmt, stmt)), .DeclStmtClass => return transDeclStmt(rp, scope, @ptrCast(*const ZigClangDeclStmt, stmt)), + .DeclRefExprClass => return transDeclRefExpr(rp, scope, @ptrCast(*const ZigClangDeclRefExpr, stmt), lrvalue), .ImplicitCastExprClass => return transImplicitCastExpr(rp, scope, @ptrCast(*const ZigClangImplicitCastExpr, stmt)), else => { return revertAndWarn( @@ -451,6 +454,24 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe }; } +fn transDeclRefExpr( + rp: RestorePoint, + scope: *Scope, + expr: *const ZigClangDeclRefExpr, + lrvalue: LRValue, +) !TransResult { + const value_decl = ZigClangDeclRefExpr_getDecl(expr); + const c_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, value_decl))); + const zig_name = transLookupZigIdentifier(scope, c_name); + if (lrvalue == .l_value) try rp.c.ptr_params.put(zig_name); + const node = try appendIdentifier(rp.c, zig_name); + return TransResult{ + .node = node, + .node_scope = scope, + .child_scope = scope, + }; +} + fn transImplicitCastExpr( rp: RestorePoint, scope: *Scope, @@ -511,6 +532,16 @@ fn findBlockScope(inner: *Scope) *Scope.Block { } } +fn transLookupZigIdentifier(inner: *Scope, c_name: []const u8) []const u8 { + var scope = inner; + while (true) : (scope = scope.parent orelse return c_name) { + if (scope.id == .Var) { + const var_scope = @ptrCast(*const Scope.Var, scope); + if (std.mem.eql(u8, var_scope.c_name, c_name)) return var_scope.zig_name; + } + } +} + fn maybeSuppressResult( rp: RestorePoint, scope: *Scope, diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 2edfda8ef..251c50ae7 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1939,3 +1939,8 @@ struct ZigClangQualType ZigClangArrayType_getElementType(const struct ZigClangAr auto casted = reinterpret_cast(self); return bitcast(casted->getElementType()); } + +const struct ZigClangValueDecl *ZigClangDeclRefExpr_getDecl(const struct ZigClangDeclRefExpr *self) { + auto casted = reinterpret_cast(self); + return reinterpret_cast(casted->getDecl()); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index 0afe30c47..086fd7a02 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -876,4 +876,6 @@ ZIG_EXTERN_C const struct ZigClangExpr *ZigClangImplicitCastExpr_getSubExpr(cons ZIG_EXTERN_C struct ZigClangQualType ZigClangArrayType_getElementType(const struct ZigClangArrayType *); +ZIG_EXTERN_C const struct ZigClangValueDecl *ZigClangDeclRefExpr_getDecl(const struct ZigClangDeclRefExpr *); + #endif From e632c2ade3d9ea2cfaa201b20f523d315d9c47fd Mon Sep 17 00:00:00 2001 From: hryx Date: Mon, 27 May 2019 23:55:48 -0700 Subject: [PATCH 11/35] (broken) port a bunch of stuff from stage1 translate-c --- src-self-hosted/clang.zig | 1 + src-self-hosted/translate_c.zig | 218 +++++++++++++++++++++++++++++++- 2 files changed, 212 insertions(+), 7 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index d1fe5153b..108204d40 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -486,6 +486,7 @@ pub extern fn ZigClangQualType_isConstQualified(arg0: struct_ZigClangQualType) b pub extern fn ZigClangQualType_isVolatileQualified(arg0: struct_ZigClangQualType) bool; pub extern fn ZigClangQualType_isRestrictQualified(arg0: struct_ZigClangQualType) bool; pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass; +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) [*]const u8; pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index ffb325d19..017b86145 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -20,7 +20,7 @@ pub const ClangErrMsg = Stage2ErrorMsg; pub const Error = error{OutOfMemory}; const TypeError = Error || error{UnsupportedType}; -const TransError = Error || error{UnsupportedTranslation}; +const TransError = TypeError || error{UnsupportedTranslation}; const DeclTable = std.HashMap(usize, void, addrHash, addrEql); @@ -199,7 +199,7 @@ pub fn translate( return context.err; } - _ = try appendToken(&context, .Eof, ""); + tree.root_node.eof_token = try appendToken(&context, .Eof, ""); tree.source = source_buffer.toOwnedSlice(); if (false) { std.debug.warn("debug source:\n{}\n==EOF==\ntokens:\n", tree.source); @@ -299,7 +299,9 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { const body_stmt = ZigClangFunctionDecl_getBody(fn_decl); const result = transStmt(rp, scope, body_stmt, .unused, .r_value) catch |err| switch (err) { error.OutOfMemory => |e| return e, - error.UnsupportedTranslation => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function"), + error.UnsupportedTranslation, + error.UnsupportedType, + => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function"), }; assert(result.node.id == ast.Node.Id.Block); proto_node.body_node = result.node; @@ -484,7 +486,11 @@ fn transImplicitCastExpr( const node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value); const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr)); const src_type = getExprQualType(c, sub_expr); - return try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, node.node); + return TransResult{ + .node = try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, node.node), + .node_scope = scope, + .child_scope = scope, + }; }, .FunctionToPointerDecay, .ArrayToPointerDecay => { return maybeSuppressResult( @@ -510,9 +516,27 @@ fn transCCast( loc: ZigClangSourceLocation, dst_type: ZigClangQualType, src_type: ZigClangQualType, - target_node: *ast.Node, -) !TransResult { - return revertAndWarn(rp, error.UnsupportedTranslation, loc, "TODO implement translation of C cast"); + expr: *ast.Node, +) !*ast.Node { + if (ZigClangType_isVoidType(qualTypeCanon(dst_type))) return expr; + if (ZigClangQualType_eq(dst_type, src_type)) return expr; + if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type)) + return transCPtrCast(rp, loc, dst_type, src_type, expr); + if (cIsUnsignedInteger(dst_type) and qualTypeIsPtr(src_type)) { + const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "ptrToInt"); + try builtin_node.params.push(expr); + return &(try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc), &builtin_node.base)).base; + } + if (cIsUnsignedInteger(src_type) and qualTypeIsPtr(dst_type)) { + const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "intToPtr"); + try builtin_node.params.push(try transQualType(rp, dst_type, loc)); + try builtin_node.params.push(expr); + return &builtin_node.base; + } + // TODO: maybe widen to increase size + // TODO: maybe bitcast to change sign + // TODO: maybe truncate to reduce size + return &(try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc), expr)).base; } fn transExpr( @@ -542,6 +566,38 @@ fn transLookupZigIdentifier(inner: *Scope, c_name: []const u8) []const u8 { } } +fn transCPtrCast( + rp: RestorePoint, + loc: ZigClangSourceLocation, + dst_type: ZigClangQualType, + src_type: ZigClangQualType, + expr: *ast.Node, +) !*ast.Node { + const ty = ZigClangQualType_getTypePtr(dst_type); + const child_type = ZigClangType_getPointeeType(ty); + const dst_type_node = try transType(rp, ty, loc); + const child_type_node = try transQualType(rp, child_type, loc); + + // Implicit downcasting from higher to lower alignment values is forbidden, + // use @alignCast to side-step this problem + const ptrcast_node = try transCreateNodeBuiltinFnCall(rp.c, "ptrCast"); + try ptrcast_node.params.push(dst_type_node); + + if (ZigClangType_isVoidType(qualTypeCanon(child_type))) { + // void has 1-byte alignment, so @alignCast is not needed + try ptrcast_node.params.push(expr); + } else { + const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "alignOf"); + try alignof_node.params.push(child_type_node); + const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "alignCast"); + try aligncast_node.params.push(&alignof_node.base); + try aligncast_node.params.push(expr); + try ptrcast_node.params.push(&aligncast_node.base); + } + + return &ptrcast_node.base; +} + fn maybeSuppressResult( rp: RestorePoint, scope: *Scope, @@ -574,6 +630,24 @@ fn transQualType(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSou return transType(rp, ZigClangQualType_getTypePtr(qt), source_loc); } +fn qualTypeIsPtr(qt: ZigClangQualType) bool { + return ZigClangType_getTypeClass(qualTypeCanon(qt)) == .Pointer; +} + +fn qualTypeChildIsFnProto(qt: ZigClangQualType) bool { + const ty = ZigClangQualType_getTypePtr(qt); + if (ZigClangType_getTypeClass(ty) == .Paren) { + const paren_type = @ptrCast(*const ZigClangParenType, ty); + const inner_type = ZigClangParenType_getInnerType(ty); + return ZigClangQualType_getTypeClass(inner_type) == .FunctionProto; + } + if (ZigClangType_getTypeClass(ty) == .Attributed) { + const attr_type = @ptrCast(*const ZigClangAttributedType, ty); + return qualTypeChildIsFnProto(bitcast(ZigClangAttributedType_getEquivalentType(attr_type))); + } + return false; +} + fn qualTypeCanon(qt: ZigClangQualType) *const ZigClangType { const canon = ZigClangQualType_getCanonicalType(qt); return ZigClangQualType_getTypePtr(canon); @@ -596,6 +670,113 @@ fn getExprQualType(c: *Context, expr: *const ZigClangExpr) ZigClangQualType { return ZigClangExpr_getType(expr); } +fn typeIsOpaque(c: *Context, ty: *const ZigClangType, loc: ZigClangSourceLocation) bool { + switch (ZigClangType_getTypeClass(ty)) { + .Builtin => { + const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty); + return ZigClangBuiltinType_getKind(builtin_ty) == .Void; + }, + .Record => { + const record_ty = @ptrCast(*const ZigClangRecordType, ty); + const record_decl = ZigClangRecordType_getDecl(record_ty); + return (ZigClangRecordDecl_getDefinition(record_decl) == null); + }, + .Elaborated => { + const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty); + const qt = ZigClangElaboratedType_getNamedType(elaborated_ty); + return typeIsOpaque(c, ZigClangQualType_getTypePtr(qt), loc); + }, + .Typedef => { + const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty); + const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); + const underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl); + return typeIsOpaque(c, ZigClangQualType_getTypePtr(underlying_type), loc); + }, + else => return false, + } +} + +fn cIsUnsignedInteger(qt: ZigClangQualType) bool { + const c_type = qualTypeCanon(qt); + if (ZigClangType_getTypeClass(c_type) != .Builtin) return false; + const builtin_ty = @ptrCast(*const ZigClangBuiltinType, c_type); + return switch (ZigClangBuiltinType_getKind(builtin_ty)) { + .Char_U, + .UChar, + .Char_S, + .UShort, + .UInt, + .ULong, + .ULongLong, + .UInt128, + .WChar_U, + => true, + else => false, + }; +} + +fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.BuiltinCall { + const node = try c.a().create(ast.Node.BuiltinCall); + node.* = ast.Node.BuiltinCall{ + .base = ast.Node{ .id = .BuiltinCall }, + .builtin_token = try appendToken(c, .Builtin, name), + .params = ast.Node.BuiltinCall.ParamList.init(c.a()), + .rparen_token = undefined, // TODO TokenIndex, + }; + return node; +} + +fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node, first_arg: *ast.Node) !*ast.Node.SuffixOp { + const node = try c.a().create(ast.Node.SuffixOp); + node.* = ast.Node.SuffixOp{ + .base = ast.Node{ .id = .SuffixOp }, + .lhs = fn_expr, + .op = ast.Node.SuffixOp.Op{ + .Call = ast.Node.SuffixOp.Op.Call{ + .params = ast.Node.SuffixOp.Op.Call.ParamList.init(c.a()), + .async_attr = null, + }, + }, + .rtoken = undefined, // TODO TokenIndex + }; + return node; +} + +fn transCreateNodePrefixOp(c: *Context, op: ast.Node.PrefixOp.Op, rhs: *ast.Node) !*ast.Node { + const node = try c.a().create(ast.Node.PrefixOp); + node.* = ast.Node.PrefixOp{ + .base = ast.Node{ .id = .PrefixOp }, + .op_token = undefined, // TODO TokenIndex, + .op = op, + .rhs = rhs, + }; + return &node.base; +} + +fn transCreateNodePtrType( + c: *Context, + is_const: bool, + is_volatile: bool, + rhs: *ast.Node, + op_tok_id: std.zig.Token.Id, +) !*ast.Node { + const node = try c.a().create(ast.Node.PrefixOp); + node.* = ast.Node.PrefixOp{ + .base = ast.Node{ .id = .PrefixOp }, + .op_token = try appendToken(c, op_tok_id, ""), // TODO TokenIndex, + .op = ast.Node.PrefixOp.Op{ + .PtrType = ast.Node.PrefixOp.PtrInfo{ + .allowzero_token = null, + .align_info = null, + .const_token = if (is_const) try appendToken(c, .Keyword_const, "const") else null, + .volatile_token = if (is_volatile) try appendToken(c, .Keyword_volatile, "volatile") else null, + }, + }, + .rhs = rhs, + }; + return &node.base; +} + const RestorePoint = struct { c: *Context, token_index: ast.TokenIndex, @@ -642,6 +823,29 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type"), } }, + .Pointer => { + const child_qt = ZigClangType_getPointeeType(ty); + const child_node = try transQualType(rp, child_qt, source_loc); + if (qualTypeChildIsFnProto(child_qt)) + return transCreateNodePrefixOp(rp.c, .OptionalType, child_node); + if (typeIsOpaque(rp.c, ZigClangQualType_getTypePtr(child_qt), source_loc)) { + const pointer_node = try transCreateNodePtrType( + rp.c, + ZigClangQualType_isConstQualified(child_qt), + ZigClangQualType_isVolatileQualified(child_qt), + child_node, + .Asterisk, + ); + return transCreateNodePrefixOp(rp.c, .OptionalType, pointer_node); + } + return transCreateNodePtrType( + rp.c, + ZigClangQualType_isConstQualified(child_qt), + ZigClangQualType_isVolatileQualified(child_qt), + child_node, + .BracketStarCBracket, + ); + }, .FunctionProto => { const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); const fn_proto = try transFnProto(rp, fn_proto_ty, source_loc, null); From 3e14f86f9e703a4d189aab5e2f27c1029927c9e9 Mon Sep 17 00:00:00 2001 From: hryx Date: Wed, 29 May 2019 15:33:44 -0700 Subject: [PATCH 12/35] Implement missing clang functions from last commit --- src-self-hosted/clang.zig | 7 +++++++ src-self-hosted/translate_c.zig | 4 ++-- src/zig_clang.cpp | 20 ++++++++++++++++++++ src/zig_clang.h | 7 +++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 108204d40..4bc027dfa 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -479,6 +479,7 @@ pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: str pub extern fn ZigClangTypedefType_getDecl(arg0: ?*const struct_ZigClangTypedefType) ?*const struct_ZigClangTypedefNameDecl; pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(arg0: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType; pub extern fn ZigClangQualType_getCanonicalType(arg0: struct_ZigClangQualType) struct_ZigClangQualType; +pub extern fn ZigClangQualType_getTypeClass(self: struct_ZigClangQualType) ZigClangTypeClass; pub extern fn ZigClangQualType_getTypePtr(self: struct_ZigClangQualType) *const struct_ZigClangType; pub extern fn ZigClangQualType_addConst(arg0: [*c]struct_ZigClangQualType) void; pub extern fn ZigClangQualType_eq(arg0: struct_ZigClangQualType, arg1: struct_ZigClangQualType) bool; @@ -887,3 +888,9 @@ pub extern fn ZigClangImplicitCastExpr_getSubExpr(*const ZigClangImplicitCastExp pub extern fn ZigClangArrayType_getElementType(*const ZigClangArrayType) ZigClangQualType; pub extern fn ZigClangDeclRefExpr_getDecl(*const ZigClangDeclRefExpr) *const ZigClangValueDecl; + +pub extern fn ZigClangParenType_getInnerType(*const ZigClangParenType) ZigClangQualType; + +pub extern fn ZigClangElaboratedType_getNamedType(*const ZigClangElaboratedType) ZigClangQualType; + +pub extern fn ZigClangAttributedType_getEquivalentType(*const ZigClangAttributedType) ZigClangQualType; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 017b86145..a7818de67 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -638,12 +638,12 @@ fn qualTypeChildIsFnProto(qt: ZigClangQualType) bool { const ty = ZigClangQualType_getTypePtr(qt); if (ZigClangType_getTypeClass(ty) == .Paren) { const paren_type = @ptrCast(*const ZigClangParenType, ty); - const inner_type = ZigClangParenType_getInnerType(ty); + const inner_type = ZigClangParenType_getInnerType(paren_type); return ZigClangQualType_getTypeClass(inner_type) == .FunctionProto; } if (ZigClangType_getTypeClass(ty) == .Attributed) { const attr_type = @ptrCast(*const ZigClangAttributedType, ty); - return qualTypeChildIsFnProto(bitcast(ZigClangAttributedType_getEquivalentType(attr_type))); + return qualTypeChildIsFnProto(ZigClangAttributedType_getEquivalentType(attr_type)); } return false; } diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 251c50ae7..a4c5dfe05 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1546,6 +1546,11 @@ const ZigClangType *ZigClangQualType_getTypePtr(ZigClangQualType self) { return reinterpret_cast(ty); } +ZigClangTypeClass ZigClangQualType_getTypeClass(ZigClangQualType self) { + clang::QualType ty = bitcast(self); + return (ZigClangTypeClass)(ty->getTypeClass()); +} + void ZigClangQualType_addConst(ZigClangQualType *self) { reinterpret_cast(self)->addConst(); } @@ -1944,3 +1949,18 @@ const struct ZigClangValueDecl *ZigClangDeclRefExpr_getDecl(const struct ZigClan auto casted = reinterpret_cast(self); return reinterpret_cast(casted->getDecl()); } + +struct ZigClangQualType ZigClangParenType_getInnerType(const struct ZigClangParenType *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getInnerType()); +} + +struct ZigClangQualType ZigClangAttributedType_getEquivalentType(const struct ZigClangAttributedType *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getEquivalentType()); +} + +struct ZigClangQualType ZigClangElaboratedType_getNamedType(const struct ZigClangElaboratedType *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getNamedType()); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index 086fd7a02..21cc25eb2 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -807,6 +807,7 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangTypedefNameDecl_getUnderlyingType(c ZIG_EXTERN_C struct ZigClangQualType ZigClangQualType_getCanonicalType(struct ZigClangQualType); ZIG_EXTERN_C const struct ZigClangType *ZigClangQualType_getTypePtr(struct ZigClangQualType); +ZIG_EXTERN_C enum ZigClangTypeClass ZigClangQualType_getTypeClass(struct ZigClangQualType); ZIG_EXTERN_C void ZigClangQualType_addConst(struct ZigClangQualType *); ZIG_EXTERN_C bool ZigClangQualType_eq(struct ZigClangQualType, struct ZigClangQualType); ZIG_EXTERN_C bool ZigClangQualType_isConstQualified(struct ZigClangQualType); @@ -878,4 +879,10 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangArrayType_getElementType(const stru ZIG_EXTERN_C const struct ZigClangValueDecl *ZigClangDeclRefExpr_getDecl(const struct ZigClangDeclRefExpr *); +ZIG_EXTERN_C struct ZigClangQualType ZigClangParenType_getInnerType(const struct ZigClangParenType *); + +ZIG_EXTERN_C struct ZigClangQualType ZigClangAttributedType_getEquivalentType(const struct ZigClangAttributedType *); + +ZIG_EXTERN_C struct ZigClangQualType ZigClangElaboratedType_getNamedType(const struct ZigClangElaboratedType *); + #endif From 1f82c7ba2243bb16a5036a22d34e9762302303de Mon Sep 17 00:00:00 2001 From: hryx Date: Sat, 8 Jun 2019 15:54:15 -0700 Subject: [PATCH 13/35] transCStyleCastExpr --- src-self-hosted/clang.zig | 4 ++++ src-self-hosted/translate_c.zig | 39 +++++++++++++++++++++++++-------- src/zig_clang.cpp | 15 +++++++++++++ src/zig_clang.h | 4 ++++ 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 4bc027dfa..c8faf1e56 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -894,3 +894,7 @@ pub extern fn ZigClangParenType_getInnerType(*const ZigClangParenType) ZigClangQ pub extern fn ZigClangElaboratedType_getNamedType(*const ZigClangElaboratedType) ZigClangQualType; pub extern fn ZigClangAttributedType_getEquivalentType(*const ZigClangAttributedType) ZigClangQualType; + +pub extern fn ZigClangCStyleCastExpr_getBeginLoc(*const ZigClangCStyleCastExpr) ZigClangSourceLocation; +pub extern fn ZigClangCStyleCastExpr_getSubExpr(*const ZigClangCStyleCastExpr) *const ZigClangExpr; +pub extern fn ZigClangCStyleCastExpr_getType(*const ZigClangCStyleCastExpr) ZigClangQualType; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index a7818de67..f9f5d52a5 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -329,9 +329,10 @@ fn transStmt( const sc = ZigClangStmt_getStmtClass(stmt); switch (sc) { .CompoundStmtClass => return transCompoundStmt(rp, scope, @ptrCast(*const ZigClangCompoundStmt, stmt)), + .CStyleCastExprClass => return transCStyleCastExprClass(rp, scope, @ptrCast(*const ZigClangCStyleCastExpr, stmt), result_used, lrvalue), .DeclStmtClass => return transDeclStmt(rp, scope, @ptrCast(*const ZigClangDeclStmt, stmt)), .DeclRefExprClass => return transDeclRefExpr(rp, scope, @ptrCast(*const ZigClangDeclRefExpr, stmt), lrvalue), - .ImplicitCastExprClass => return transImplicitCastExpr(rp, scope, @ptrCast(*const ZigClangImplicitCastExpr, stmt)), + .ImplicitCastExprClass => return transImplicitCastExpr(rp, scope, @ptrCast(*const ZigClangImplicitCastExpr, stmt), result_used), else => { return revertAndWarn( rp, @@ -377,6 +378,30 @@ fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompo }; } +fn transCStyleCastExprClass( + rp: RestorePoint, + scope: *Scope, + stmt: *const ZigClangCStyleCastExpr, + result_used: ResultUsed, + lrvalue: LRValue, +) !TransResult { + const sub_expr = ZigClangCStyleCastExpr_getSubExpr(stmt); + const cast_node = (try transCCast( + rp, + scope, + ZigClangCStyleCastExpr_getBeginLoc(stmt), + ZigClangCStyleCastExpr_getType(stmt), + ZigClangExpr_getType(sub_expr), + (try transExpr(rp, scope, sub_expr, .used, lrvalue)).node, + )); + const cast_res = TransResult{ + .node = cast_node, + .child_scope = scope, + .node_scope = scope, + }; + return maybeSuppressResult(rp, scope, result_used, cast_res); +} + fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDeclStmt) !TransResult { const c = rp.c; const block_scope = findBlockScope(parent_scope); @@ -478,27 +503,23 @@ fn transImplicitCastExpr( rp: RestorePoint, scope: *Scope, expr: *const ZigClangImplicitCastExpr, + result_used: ResultUsed, ) !TransResult { const c = rp.c; const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr); + const sub_expr_node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value); switch (ZigClangImplicitCastExpr_getCastKind(expr)) { .BitCast => { - const node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value); const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr)); const src_type = getExprQualType(c, sub_expr); return TransResult{ - .node = try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, node.node), + .node = try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node.node), .node_scope = scope, .child_scope = scope, }; }, .FunctionToPointerDecay, .ArrayToPointerDecay => { - return maybeSuppressResult( - rp, - scope, - .used, - try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value), - ); + return maybeSuppressResult(rp, scope, result_used, sub_expr_node); }, else => |kind| return revertAndWarn( rp, diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index a4c5dfe05..6283f7b67 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1964,3 +1964,18 @@ struct ZigClangQualType ZigClangElaboratedType_getNamedType(const struct ZigClan auto casted = reinterpret_cast(self); return bitcast(casted->getNamedType()); } + +struct ZigClangSourceLocation ZigClangCStyleCastExpr_getBeginLoc(const struct ZigClangCStyleCastExpr *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getBeginLoc()); +} + +const struct ZigClangExpr *ZigClangCStyleCastExpr_getSubExpr(const struct ZigClangCStyleCastExpr *self) { + auto casted = reinterpret_cast(self); + return reinterpret_cast(casted->getSubExpr()); +} + +struct ZigClangQualType ZigClangCStyleCastExpr_getType(const struct ZigClangCStyleCastExpr *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getType()); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index 21cc25eb2..bfaa5867a 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -885,4 +885,8 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangAttributedType_getEquivalentType(co ZIG_EXTERN_C struct ZigClangQualType ZigClangElaboratedType_getNamedType(const struct ZigClangElaboratedType *); +ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangCStyleCastExpr_getBeginLoc(const struct ZigClangCStyleCastExpr *); +ZIG_EXTERN_C const struct ZigClangExpr *ZigClangCStyleCastExpr_getSubExpr(const struct ZigClangCStyleCastExpr *); +ZIG_EXTERN_C struct ZigClangQualType ZigClangCStyleCastExpr_getType(const struct ZigClangCStyleCastExpr *); + #endif From 1692a76d28740637b8b303ecbc05dca0fb0218b6 Mon Sep 17 00:00:00 2001 From: hryx Date: Sat, 8 Jun 2019 15:57:43 -0700 Subject: [PATCH 14/35] transImplictCastExpr: LValueToRValue --- src-self-hosted/translate_c.zig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index f9f5d52a5..459f90ad9 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -521,6 +521,9 @@ fn transImplicitCastExpr( .FunctionToPointerDecay, .ArrayToPointerDecay => { return maybeSuppressResult(rp, scope, result_used, sub_expr_node); }, + .LValueToRValue => { + return transExpr(rp, scope, sub_expr, .used, .r_value); + }, else => |kind| return revertAndWarn( rp, error.UnsupportedTranslation, From ed5b8335b564cc4372b12e1c1a1b459aa348a90d Mon Sep 17 00:00:00 2001 From: hryx Date: Sat, 8 Jun 2019 16:09:25 -0700 Subject: [PATCH 15/35] (broken) translate Paren type --- src-self-hosted/translate_c.zig | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 459f90ad9..7e1c6571e 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -847,6 +847,15 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type"), } }, + .FunctionProto => { + const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); + const fn_proto = try transFnProto(rp, fn_proto_ty, source_loc, null); + return &fn_proto.base; + }, + .Paren => { + const paren_ty = @ptrCast(*const ZigClangParenType, ty); + return transQualType(rp, ZigClangParenType_getInnerType(paren_ty), source_loc); + }, .Pointer => { const child_qt = ZigClangType_getPointeeType(ty); const child_node = try transQualType(rp, child_qt, source_loc); @@ -870,11 +879,6 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour .BracketStarCBracket, ); }, - .FunctionProto => { - const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); - const fn_proto = try transFnProto(rp, fn_proto_ty, source_loc, null); - return &fn_proto.base; - }, else => { const type_name = rp.c.str(ZigClangType_getTypeClassName(ty)); return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported type: '{}'", type_name); From 586c36dd1d37d06bdf84fcf867165b8861825cb8 Mon Sep 17 00:00:00 2001 From: hryx Date: Sat, 8 Jun 2019 17:02:00 -0700 Subject: [PATCH 16/35] Restore fn decls removed during conflict --- src-self-hosted/clang.zig | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 20a815cb7..222932476 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -723,6 +723,7 @@ pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: str 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; pub extern fn ZigClangQualType_getTypePtr(self: struct_ZigClangQualType) *const struct_ZigClangType; pub extern fn ZigClangQualType_addConst(self: [*c]struct_ZigClangQualType) void; pub extern fn ZigClangQualType_eq(self: struct_ZigClangQualType, arg1: struct_ZigClangQualType) bool; @@ -730,6 +731,7 @@ pub extern fn ZigClangQualType_isConstQualified(self: struct_ZigClangQualType) b pub extern fn ZigClangQualType_isVolatileQualified(self: struct_ZigClangQualType) bool; pub extern fn ZigClangQualType_isRestrictQualified(self: struct_ZigClangQualType) bool; pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass; +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) [*]const u8; pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation; @@ -894,3 +896,35 @@ pub const ZigClangCompoundStmt_const_body_iterator = [*c]const *struct_ZigClangS pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator; pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator; + +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_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; +pub const ZigClangVarDecl_TLSKind = extern enum { + None, + Static, + Dynamic, +}; + +pub extern fn ZigClangImplicitCastExpr_getBeginLoc(*const ZigClangImplicitCastExpr) ZigClangSourceLocation; +pub extern fn ZigClangImplicitCastExpr_getCastKind(*const ZigClangImplicitCastExpr) ZigClangCK; +pub extern fn ZigClangImplicitCastExpr_getSubExpr(*const ZigClangImplicitCastExpr) *const ZigClangExpr; + +pub extern fn ZigClangArrayType_getElementType(*const ZigClangArrayType) ZigClangQualType; + +pub extern fn ZigClangDeclRefExpr_getDecl(*const ZigClangDeclRefExpr) *const ZigClangValueDecl; + +pub extern fn ZigClangParenType_getInnerType(*const ZigClangParenType) ZigClangQualType; + +pub extern fn ZigClangElaboratedType_getNamedType(*const ZigClangElaboratedType) ZigClangQualType; + +pub extern fn ZigClangAttributedType_getEquivalentType(*const ZigClangAttributedType) ZigClangQualType; + +pub extern fn ZigClangCStyleCastExpr_getBeginLoc(*const ZigClangCStyleCastExpr) ZigClangSourceLocation; +pub extern fn ZigClangCStyleCastExpr_getSubExpr(*const ZigClangCStyleCastExpr) *const ZigClangExpr; +pub extern fn ZigClangCStyleCastExpr_getType(*const ZigClangCStyleCastExpr) ZigClangQualType; From 84e479d94f9998331bdd73665274684cf3d0ad48 Mon Sep 17 00:00:00 2001 From: hryx Date: Sun, 9 Jun 2019 23:35:48 -0700 Subject: [PATCH 17/35] (broken) local var decls, integer literals (part) --- src-self-hosted/clang.zig | 32 ++++++++++++- src-self-hosted/translate_c.zig | 79 ++++++++++++++++++++++++++------- src/zig_clang.cpp | 38 ++++++++++++++++ src/zig_clang.h | 30 +++++++++++++ 4 files changed, 163 insertions(+), 16 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 222932476..e640e3ead 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -1,4 +1,3 @@ -pub const struct_ZigClangAPValue = @OpaqueType(); pub const struct_ZigClangAPSInt = @OpaqueType(); pub const struct_ZigClangAPFloat = @OpaqueType(); pub const struct_ZigClangASTContext = @OpaqueType(); @@ -928,3 +927,34 @@ pub extern fn ZigClangAttributedType_getEquivalentType(*const ZigClangAttributed pub extern fn ZigClangCStyleCastExpr_getBeginLoc(*const ZigClangCStyleCastExpr) ZigClangSourceLocation; pub extern fn ZigClangCStyleCastExpr_getSubExpr(*const ZigClangCStyleCastExpr) *const ZigClangExpr; pub extern fn ZigClangCStyleCastExpr_getType(*const ZigClangCStyleCastExpr) ZigClangQualType; + +pub const ZigClangExprEvalResult = struct_ZigClangExprEvalResult; +pub const struct_ZigClangExprEvalResult = extern struct { + HasSideEffects: bool, + HasUndefinedBehavior: bool, + SmallVectorImpl: ?*c_void, + Val: ZigClangAPValue, +}; + +pub const struct_ZigClangAPValue = extern struct { + Kind: ZigClangAPValue_ValueKind, + Data: [68]u8, // TODO: is there a way to statically assert that this matches the .h? +}; + +pub const ZigClangAPValue_ValueKind = extern enum { + ZigClangAPValue_ValueKind_Uninitialized, + ZigClangAPValue_ValueKind_Int, + ZigClangAPValue_ValueKind_Float, + ZigClangAPValue_ValueKind_ComplexInt, + ZigClangAPValue_ValueKind_ComplexFloat, + ZigClangAPValue_ValueKind_LValue, + ZigClangAPValue_ValueKind_Vector, + ZigClangAPValue_ValueKind_Array, + ZigClangAPValue_ValueKind_Struct, + ZigClangAPValue_ValueKind_Union, + ZigClangAPValue_ValueKind_MemberPointer, + ZigClangAPValue_ValueKind_AddrLabelDiff, +}; + +pub extern fn ZigClangIntegerLiteral_EvaluateAsInt(*const ZigClangIntegerLiteral, *ZigClangExprEvalResult, *const ZigClangASTContext) bool; +pub extern fn ZigClangIntegerLiteral_getBeginLoc(*const ZigClangIntegerLiteral) ZigClangSourceLocation; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 6d64a28f1..7e05df4f5 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -333,6 +333,7 @@ fn transStmt( .DeclStmtClass => return transDeclStmt(rp, scope, @ptrCast(*const ZigClangDeclStmt, stmt)), .DeclRefExprClass => return transDeclRefExpr(rp, scope, @ptrCast(*const ZigClangDeclRefExpr, stmt), lrvalue), .ImplicitCastExprClass => return transImplicitCastExpr(rp, scope, @ptrCast(*const ZigClangImplicitCastExpr, stmt), result_used), + .IntegerLiteralClass => return transIntegerLiteral(rp, scope, @ptrCast(*const ZigClangIntegerLiteral, stmt), result_used), else => { return revertAndWarn( rp, @@ -534,6 +535,26 @@ fn transImplicitCastExpr( } } +fn transIntegerLiteral( + rp: RestorePoint, + scope: *Scope, + expr: *const ZigClangIntegerLiteral, + result_used: ResultUsed, +) !TransResult { + var eval_result: ZigClangExprEvalResult = undefined; + if (!ZigClangIntegerLiteral_EvaluateAsInt(expr, &eval_result, rp.c.clang_context)) { + const loc = ZigClangIntegerLiteral_getBeginLoc(expr); + return revertAndWarn(rp, error.UnsupportedTranslation, loc, "invalid integer literal"); + } + const node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val)); + const res = TransResult{ + .node = node, + .child_scope = scope, + .node_scope = scope, + }; + return maybeSuppressResult(rp, scope, result_used, res); +} + fn transCCast( rp: RestorePoint, scope: *Scope, @@ -547,14 +568,17 @@ fn transCCast( if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type)) return transCPtrCast(rp, loc, dst_type, src_type, expr); if (cIsUnsignedInteger(dst_type) and qualTypeIsPtr(src_type)) { - const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "ptrToInt"); + const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt"); try builtin_node.params.push(expr); + builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); return &(try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc), &builtin_node.base)).base; } if (cIsUnsignedInteger(src_type) and qualTypeIsPtr(dst_type)) { - const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "intToPtr"); + const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr"); try builtin_node.params.push(try transQualType(rp, dst_type, loc)); + _ = try appendToken(rp.c, .Comma, ","); try builtin_node.params.push(expr); + builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); return &builtin_node.base; } // TODO: maybe widen to increase size @@ -599,25 +623,28 @@ fn transCPtrCast( ) !*ast.Node { const ty = ZigClangQualType_getTypePtr(dst_type); const child_type = ZigClangType_getPointeeType(ty); - const dst_type_node = try transType(rp, ty, loc); - const child_type_node = try transQualType(rp, child_type, loc); // Implicit downcasting from higher to lower alignment values is forbidden, // use @alignCast to side-step this problem - const ptrcast_node = try transCreateNodeBuiltinFnCall(rp.c, "ptrCast"); + const ptrcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrCast"); + const dst_type_node = try transType(rp, ty, loc); try ptrcast_node.params.push(dst_type_node); + _ = try appendToken(rp.c, .Comma, ","); if (ZigClangType_isVoidType(qualTypeCanon(child_type))) { // void has 1-byte alignment, so @alignCast is not needed try ptrcast_node.params.push(expr); } else { - const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "alignOf"); + const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf"); + const child_type_node = try transQualType(rp, child_type, loc); try alignof_node.params.push(child_type_node); - const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "alignCast"); + const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast"); try aligncast_node.params.push(&alignof_node.base); + _ = try appendToken(rp.c, .Comma, ","); try aligncast_node.params.push(expr); try ptrcast_node.params.push(&aligncast_node.base); } + ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); return &ptrcast_node.base; } @@ -740,17 +767,20 @@ fn cIsUnsignedInteger(qt: ZigClangQualType) bool { } fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.BuiltinCall { + const builtin_token = try appendToken(c, .Builtin, name); + _ = try appendToken(c, .LParen, "("); const node = try c.a().create(ast.Node.BuiltinCall); node.* = ast.Node.BuiltinCall{ .base = ast.Node{ .id = .BuiltinCall }, - .builtin_token = try appendToken(c, .Builtin, name), + .builtin_token = builtin_token, .params = ast.Node.BuiltinCall.ParamList.init(c.a()), - .rparen_token = undefined, // TODO TokenIndex, + .rparen_token = undefined, // set after appending args }; return node; } fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node, first_arg: *ast.Node) !*ast.Node.SuffixOp { + _ = try appendToken(c, .LParen, "("); const node = try c.a().create(ast.Node.SuffixOp); node.* = ast.Node.SuffixOp{ .base = ast.Node{ .id = .SuffixOp }, @@ -761,16 +791,23 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node, first_arg: *ast.Node) .async_attr = null, }, }, - .rtoken = undefined, // TODO TokenIndex + .rtoken = try appendToken(c, .RParen, ")"), }; + try node.op.Call.params.push(first_arg); return node; } -fn transCreateNodePrefixOp(c: *Context, op: ast.Node.PrefixOp.Op, rhs: *ast.Node) !*ast.Node { +fn transCreateNodePrefixOp( + c: *Context, + op: ast.Node.PrefixOp.Op, + rhs: *ast.Node, + op_tok_id: std.zig.Token.Id, + bytes: []const u8, +) !*ast.Node { const node = try c.a().create(ast.Node.PrefixOp); node.* = ast.Node.PrefixOp{ .base = ast.Node{ .id = .PrefixOp }, - .op_token = undefined, // TODO TokenIndex, + .op_token = try appendToken(c, op_tok_id, bytes), .op = op, .rhs = rhs, }; @@ -783,11 +820,12 @@ fn transCreateNodePtrType( is_volatile: bool, rhs: *ast.Node, op_tok_id: std.zig.Token.Id, + bytes: []const u8, ) !*ast.Node { const node = try c.a().create(ast.Node.PrefixOp); node.* = ast.Node.PrefixOp{ .base = ast.Node{ .id = .PrefixOp }, - .op_token = try appendToken(c, op_tok_id, ""), // TODO TokenIndex, + .op_token = try appendToken(c, op_tok_id, bytes), .op = ast.Node.PrefixOp.Op{ .PtrType = ast.Node.PrefixOp.PtrInfo{ .allowzero_token = null, @@ -801,6 +839,15 @@ fn transCreateNodePtrType( return &node.base; } +fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node { + const node = try c.a().create(ast.Node.IntegerLiteral); + node.* = ast.Node.IntegerLiteral{ + .base = ast.Node{ .id = .IntegerLiteral }, + .token = try appendToken(c, .IntegerLiteral, "3333333"), // TODO + }; + return &node.base; +} + const RestorePoint = struct { c: *Context, token_index: ast.TokenIndex, @@ -860,7 +907,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour const child_qt = ZigClangType_getPointeeType(ty); const child_node = try transQualType(rp, child_qt, source_loc); if (qualTypeChildIsFnProto(child_qt)) - return transCreateNodePrefixOp(rp.c, .OptionalType, child_node); + return transCreateNodePrefixOp(rp.c, .OptionalType, child_node, .QuestionMark, "?"); if (typeIsOpaque(rp.c, ZigClangQualType_getTypePtr(child_qt), source_loc)) { const pointer_node = try transCreateNodePtrType( rp.c, @@ -868,8 +915,9 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour ZigClangQualType_isVolatileQualified(child_qt), child_node, .Asterisk, + "*", ); - return transCreateNodePrefixOp(rp.c, .OptionalType, pointer_node); + return transCreateNodePrefixOp(rp.c, .OptionalType, pointer_node, .QuestionMark, "?"); } return transCreateNodePtrType( rp.c, @@ -877,6 +925,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour ZigClangQualType_isVolatileQualified(child_qt), child_node, .BracketStarCBracket, + "[*c]", ); }, else => { diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 6283f7b67..99b55dc59 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #if __GNUC__ >= 8 @@ -1287,6 +1288,20 @@ static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_UTF16 == clang::StringLiteral::UTF16, ""); static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_UTF32 == clang::StringLiteral::UTF32, ""); +static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Uninitialized == clang::APValue::ValueKind::Uninitialized, ""); +static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Int == clang::APValue::ValueKind::Int, ""); +static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Float == clang::APValue::ValueKind::Float, ""); +static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_ComplexInt == clang::APValue::ValueKind::ComplexInt, ""); +static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_ComplexFloat == clang::APValue::ValueKind::ComplexFloat, ""); +static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_LValue == clang::APValue::ValueKind::LValue, ""); +static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Vector == clang::APValue::ValueKind::Vector, ""); +static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Array == clang::APValue::ValueKind::Array, ""); +static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Struct == clang::APValue::ValueKind::Struct, ""); +static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Union == clang::APValue::ValueKind::Union, ""); +static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_MemberPointer == clang::APValue::ValueKind::MemberPointer, ""); +static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_AddrLabelDiff == clang::APValue::ValueKind::AddrLabelDiff, ""); + +static_assert(sizeof(ZigClangAPValue) == sizeof(clang::APValue), ""); static_assert(sizeof(ZigClangSourceLocation) == sizeof(clang::SourceLocation), ""); static ZigClangSourceLocation bitcast(clang::SourceLocation src) { @@ -1312,6 +1327,13 @@ static clang::QualType bitcast(ZigClangQualType src) { return dest; } +static_assert(sizeof(ZigClangExprEvalResult) == sizeof(clang::Expr::EvalResult), ""); +static ZigClangExprEvalResult bitcast(clang::Expr::EvalResult src) { + ZigClangExprEvalResult dest; + memcpy(&dest, static_cast(&src), sizeof(ZigClangExprEvalResult)); + return dest; +} + static_assert(sizeof(ZigClangAPValueLValueBase) == sizeof(clang::APValue::LValueBase), ""); static ZigClangAPValueLValueBase bitcast(clang::APValue::LValueBase src) { ZigClangAPValueLValueBase dest; @@ -1979,3 +2001,19 @@ struct ZigClangQualType ZigClangCStyleCastExpr_getType(const struct ZigClangCSty auto casted = reinterpret_cast(self); return bitcast(casted->getType()); } + +bool ZigClangIntegerLiteral_EvaluateAsInt(const struct ZigClangIntegerLiteral *self, struct ZigClangExprEvalResult *result, const struct ZigClangASTContext *ctx) { + auto casted_self = reinterpret_cast(self); + auto casted_ctx = reinterpret_cast(ctx); + clang::Expr::EvalResult eval_result; + if (!casted_self->EvaluateAsInt(eval_result, *casted_ctx)) { + return false; + } + *result = bitcast(eval_result); + return true; +} + +struct ZigClangSourceLocation ZigClangIntegerLiteral_getBeginLoc(const struct ZigClangIntegerLiteral *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getBeginLoc()); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index bfaa5867a..6efdca89d 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -30,6 +30,33 @@ struct ZigClangAPValueLValueBase { unsigned Version; }; +enum ZigClangAPValue_ValueKind { + ZigClangAPValue_ValueKind_Uninitialized, + ZigClangAPValue_ValueKind_Int, + ZigClangAPValue_ValueKind_Float, + ZigClangAPValue_ValueKind_ComplexInt, + ZigClangAPValue_ValueKind_ComplexFloat, + ZigClangAPValue_ValueKind_LValue, + ZigClangAPValue_ValueKind_Vector, + ZigClangAPValue_ValueKind_Array, + ZigClangAPValue_ValueKind_Struct, + ZigClangAPValue_ValueKind_Union, + ZigClangAPValue_ValueKind_MemberPointer, + ZigClangAPValue_ValueKind_AddrLabelDiff +}; + +struct ZigClangAPValue { + enum ZigClangAPValue_ValueKind Kind; + char Data[68]; // experimentally-derived size of clang::APValue::DataType +}; + +struct ZigClangExprEvalResult { + bool HasSideEffects; + bool HasUndefinedBehavior; + void *SmallVectorImpl; + ZigClangAPValue Val; +}; + struct ZigClangAPValue; struct ZigClangAPSInt; struct ZigClangAPFloat; @@ -889,4 +916,7 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangCStyleCastExpr_getBeginLoc(co ZIG_EXTERN_C const struct ZigClangExpr *ZigClangCStyleCastExpr_getSubExpr(const struct ZigClangCStyleCastExpr *); ZIG_EXTERN_C struct ZigClangQualType ZigClangCStyleCastExpr_getType(const struct ZigClangCStyleCastExpr *); +ZIG_EXTERN_C bool ZigClangIntegerLiteral_EvaluateAsInt(const struct ZigClangIntegerLiteral *, struct ZigClangExprEvalResult *, const struct ZigClangASTContext *); +ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangIntegerLiteral_getBeginLoc(const struct ZigClangIntegerLiteral *); + #endif From 0f545e5a2b664d340fe33fe0a8fbc44956485e18 Mon Sep 17 00:00:00 2001 From: hryx Date: Mon, 10 Jun 2019 23:06:54 -0700 Subject: [PATCH 18/35] transReturnStmt --- src-self-hosted/clang.zig | 2 ++ src-self-hosted/translate_c.zig | 31 +++++++++++++++++++++++++++++++ src/zig_clang.cpp | 5 +++++ src/zig_clang.h | 2 ++ 4 files changed, 40 insertions(+) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index e640e3ead..de3c538c4 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -958,3 +958,5 @@ pub const ZigClangAPValue_ValueKind = extern enum { pub extern fn ZigClangIntegerLiteral_EvaluateAsInt(*const ZigClangIntegerLiteral, *ZigClangExprEvalResult, *const ZigClangASTContext) bool; pub extern fn ZigClangIntegerLiteral_getBeginLoc(*const ZigClangIntegerLiteral) ZigClangSourceLocation; + +pub extern fn ZigClangReturnStmt_getRetValue(*const ZigClangReturnStmt) ?*const ZigClangExpr; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 7e05df4f5..7de834b4f 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -334,6 +334,7 @@ fn transStmt( .DeclRefExprClass => return transDeclRefExpr(rp, scope, @ptrCast(*const ZigClangDeclRefExpr, stmt), lrvalue), .ImplicitCastExprClass => return transImplicitCastExpr(rp, scope, @ptrCast(*const ZigClangImplicitCastExpr, stmt), result_used), .IntegerLiteralClass => return transIntegerLiteral(rp, scope, @ptrCast(*const ZigClangIntegerLiteral, stmt), result_used), + .ReturnStmtClass => return transReturnStmt(rp, scope, @ptrCast(*const ZigClangReturnStmt, stmt)), else => { return revertAndWarn( rp, @@ -555,6 +556,24 @@ fn transIntegerLiteral( return maybeSuppressResult(rp, scope, result_used, res); } +fn transReturnStmt( + rp: RestorePoint, + scope: *Scope, + expr: *const ZigClangReturnStmt, +) !TransResult { + const node = try transCreateNodeReturnExpr(rp.c); + if (ZigClangReturnStmt_getRetValue(expr)) |val_expr| { + const ret_node = node.cast(ast.Node.ControlFlowExpression).?; + ret_node.rhs = (try transExpr(rp, scope, val_expr, .used, .r_value)).node; + } + _ = try appendToken(rp.c, .Semicolon, ";"); + return TransResult{ + .node = node, + .child_scope = scope, + .node_scope = scope, + }; +} + fn transCCast( rp: RestorePoint, scope: *Scope, @@ -848,6 +867,18 @@ fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node { return &node.base; } +fn transCreateNodeReturnExpr(c: *Context) !*ast.Node { + const ltoken = try appendToken(c, .Keyword_return, "return"); + const node = try c.a().create(ast.Node.ControlFlowExpression); + node.* = ast.Node.ControlFlowExpression{ + .base = ast.Node{ .id = .ControlFlowExpression }, + .ltoken = ltoken, + .kind = .Return, + .rhs = null, + }; + return &node.base; +} + const RestorePoint = struct { c: *Context, token_index: ast.TokenIndex, diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 99b55dc59..0d6361bac 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -2017,3 +2017,8 @@ struct ZigClangSourceLocation ZigClangIntegerLiteral_getBeginLoc(const struct Zi auto casted = reinterpret_cast(self); return bitcast(casted->getBeginLoc()); } + +const struct ZigClangExpr *ZigClangReturnStmt_getRetValue(const struct ZigClangReturnStmt *self) { + auto casted = reinterpret_cast(self); + return reinterpret_cast(casted->getRetValue()); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index 6efdca89d..6f691371b 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -919,4 +919,6 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangCStyleCastExpr_getType(const struct ZIG_EXTERN_C bool ZigClangIntegerLiteral_EvaluateAsInt(const struct ZigClangIntegerLiteral *, struct ZigClangExprEvalResult *, const struct ZigClangASTContext *); ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangIntegerLiteral_getBeginLoc(const struct ZigClangIntegerLiteral *); +ZIG_EXTERN_C const struct ZigClangExpr *ZigClangReturnStmt_getRetValue(const struct ZigClangReturnStmt *); + #endif From 6325ffc3f1e5f61caab6d554a760c1b5d061b0d4 Mon Sep 17 00:00:00 2001 From: hryx Date: Sat, 22 Jun 2019 17:29:10 -0700 Subject: [PATCH 19/35] Assign undefined literal (instead of null) when no init value --- src-self-hosted/translate_c.zig | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 7de834b4f..4d339fe25 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -357,7 +357,7 @@ fn transCompoundStmtInline( const end_it = ZigClangCompoundStmt_body_end(stmt); var scope = parent_scope; while (it != end_it) : (it += 1) { - const result = try transStmt(rp, scope, it.*, .unused, .r_value); + const result = try transStmt(rp, parent_scope, it.*, .unused, .r_value); scope = result.child_scope; try block_node.statements.push(result.node); } @@ -438,11 +438,22 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe }; scope = &var_scope.base; + const colon_token = try appendToken(c, .Colon, ":"); + const loc = ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt)); + const type_node = try transQualType(rp, qual_type, loc); + 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 - null; + 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; + }; const semicolon_token = try appendToken(c, .Semicolon, ";"); const node = try c.a().create(ast.Node.VarDecl); @@ -457,7 +468,7 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe .comptime_token = null, .extern_export_token = null, // TODO ?TokenIndex, .lib_name = null, // TODO ?*Node, - .type_node = null, // TODO ?*Node, + .type_node = type_node, .align_node = null, // TODO ?*Node, .section_node = null, // TODO ?*Node, .init_node = init_node, From 4ae95d7ffc6ce6b011d5e5c6ff747cd3a1aa59bb Mon Sep 17 00:00:00 2001 From: hryx Date: Sat, 22 Jun 2019 17:29:36 -0700 Subject: [PATCH 20/35] Translate assignment BinaryOperator statements --- src-self-hosted/clang.zig | 5 ++ src-self-hosted/translate_c.zig | 98 +++++++++++++++++++++++++++++++++ src/zig_clang.cpp | 20 +++++++ src/zig_clang.h | 5 ++ 4 files changed, 128 insertions(+) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index de3c538c4..d48c57c0a 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -960,3 +960,8 @@ pub extern fn ZigClangIntegerLiteral_EvaluateAsInt(*const ZigClangIntegerLiteral pub extern fn ZigClangIntegerLiteral_getBeginLoc(*const ZigClangIntegerLiteral) ZigClangSourceLocation; pub extern fn ZigClangReturnStmt_getRetValue(*const ZigClangReturnStmt) ?*const ZigClangExpr; + +pub extern fn ZigClangBinaryOperator_getOpcode(*const ZigClangBinaryOperator) ZigClangBO; +pub extern fn ZigClangBinaryOperator_getBeginLoc(*const ZigClangBinaryOperator) ZigClangSourceLocation; +pub extern fn ZigClangBinaryOperator_getLHS(*const ZigClangBinaryOperator) *const ZigClangExpr; +pub extern fn ZigClangBinaryOperator_getRHS(*const ZigClangBinaryOperator) *const ZigClangExpr; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 4d339fe25..467316645 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -328,6 +328,7 @@ fn transStmt( ) !TransResult { const sc = ZigClangStmt_getStmtClass(stmt); switch (sc) { + .BinaryOperatorClass => return transBinaryOperator(rp, scope, @ptrCast(*const ZigClangBinaryOperator, stmt), result_used), .CompoundStmtClass => return transCompoundStmt(rp, scope, @ptrCast(*const ZigClangCompoundStmt, stmt)), .CStyleCastExprClass => return transCStyleCastExprClass(rp, scope, @ptrCast(*const ZigClangCStyleCastExpr, stmt), result_used, lrvalue), .DeclStmtClass => return transDeclStmt(rp, scope, @ptrCast(*const ZigClangDeclStmt, stmt)), @@ -347,6 +348,66 @@ fn transStmt( } } +fn transBinaryOperator( + rp: RestorePoint, + scope: *Scope, + stmt: *const ZigClangBinaryOperator, + result_used: ResultUsed, +) TransError!TransResult { + const op = ZigClangBinaryOperator_getOpcode(stmt); + switch (op) { + .PtrMemD, .PtrMemI, .Cmp => return revertAndWarn( + rp, + error.UnsupportedTranslation, + ZigClangBinaryOperator_getBeginLoc(stmt), + "TODO: handle more C binary operators: {}", + op, + ), + .Assign => return TransResult{ + .node = &(try transCreateNodeAssign(rp, scope, result_used, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt))).base, + .child_scope = scope, + .node_scope = scope, + }, + .Mul, + .Div, + .Rem, + .Sub, + .Add, + .Shl, + .Shr, + .LT, + .GT, + .LE, + .GE, + .EQ, + .NE, + .And, + .Xor, + .Or, + .LAnd, + .LOr, + .Comma, + => return revertAndWarn( + rp, + error.UnsupportedTranslation, + ZigClangBinaryOperator_getBeginLoc(stmt), + "TODO: handle more C binary operators: {}", + op, + ), + .MulAssign, + .DivAssign, + .RemAssign, + .AddAssign, + .SubAssign, + .ShlAssign, + .ShrAssign, + .AndAssign, + .XorAssign, + .OrAssign, + => unreachable, + } +} + fn transCompoundStmtInline( rp: RestorePoint, parent_scope: *Scope, @@ -796,6 +857,43 @@ fn cIsUnsignedInteger(qt: ZigClangQualType) bool { }; } +fn transCreateNodeAssign( + rp: RestorePoint, + scope: *Scope, + result_used: ResultUsed, + lhs: *const ZigClangExpr, + rhs: *const ZigClangExpr, +) !*ast.Node.InfixOp { + // common case + // c: lhs = rhs + // zig: lhs = rhs + if (result_used == .unused) { + const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value); + const eq_token = try appendToken(rp.c, .Equal, "="); + const rhs_node = try transExpr(rp, scope, rhs, .used, .r_value); + _ = try appendToken(rp.c, .Semicolon, ";"); + + const node = try rp.c.a().create(ast.Node.InfixOp); + node.* = ast.Node.InfixOp{ + .base = ast.Node{ .id = .InfixOp }, + .op_token = eq_token, + .lhs = lhs_node.node, + .op = .Assign, + .rhs = rhs_node.node, + }; + return node; + } + + // worst case + // c: lhs = rhs + // zig: (x: { + // zig: const _tmp = rhs; + // zig: lhs = _tmp; + // zig: break :x _tmp + // zig: }) + return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangExpr_getBeginLoc(lhs), "TODO: worst case assign op expr"); +} + fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.BuiltinCall { const builtin_token = try appendToken(c, .Builtin, name); _ = try appendToken(c, .LParen, "("); diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 0d6361bac..fd675effb 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -2022,3 +2022,23 @@ const struct ZigClangExpr *ZigClangReturnStmt_getRetValue(const struct ZigClangR auto casted = reinterpret_cast(self); return reinterpret_cast(casted->getRetValue()); } + +enum ZigClangBO ZigClangBinaryOperator_getOpcode(const struct ZigClangBinaryOperator *self) { + auto casted = reinterpret_cast(self); + return (ZigClangBO)casted->getOpcode(); +} + +struct ZigClangSourceLocation ZigClangBinaryOperator_getBeginLoc(const struct ZigClangBinaryOperator *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getBeginLoc()); +} + +const struct ZigClangExpr *ZigClangBinaryOperator_getLHS(const struct ZigClangBinaryOperator *self) { + auto casted = reinterpret_cast(self); + return reinterpret_cast(casted->getLHS()); +} + +const struct ZigClangExpr *ZigClangBinaryOperator_getRHS(const struct ZigClangBinaryOperator *self) { + auto casted = reinterpret_cast(self); + return reinterpret_cast(casted->getRHS()); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index 6f691371b..99d742d4e 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -921,4 +921,9 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangIntegerLiteral_getBeginLoc(co ZIG_EXTERN_C const struct ZigClangExpr *ZigClangReturnStmt_getRetValue(const struct ZigClangReturnStmt *); +ZIG_EXTERN_C enum ZigClangBO ZigClangBinaryOperator_getOpcode(const struct ZigClangBinaryOperator *); +ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangBinaryOperator_getBeginLoc(const struct ZigClangBinaryOperator *); +ZIG_EXTERN_C const struct ZigClangExpr *ZigClangBinaryOperator_getLHS(const struct ZigClangBinaryOperator *); +ZIG_EXTERN_C const struct ZigClangExpr *ZigClangBinaryOperator_getRHS(const struct ZigClangBinaryOperator *); + #endif From 4c8b460fec7dff1f56605ca1c9bd9b76599952d8 Mon Sep 17 00:00:00 2001 From: hryx Date: Sat, 22 Jun 2019 22:30:15 -0700 Subject: [PATCH 21/35] Fix recursive self-referential block --- src-self-hosted/translate_c.zig | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 467316645..ec6460e4f 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -420,7 +420,9 @@ fn transCompoundStmtInline( while (it != end_it) : (it += 1) { const result = try transStmt(rp, parent_scope, it.*, .unused, .r_value); scope = result.child_scope; - try block_node.statements.push(result.node); + std.debug.warn("id: {}\n", result.node.id); + if (result.node != &block_node.base) + try block_node.statements.push(result.node); } return TransResult{ .node = &block_node.base, @@ -493,7 +495,7 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe const var_scope = try c.a().create(Scope.Var); var_scope.* = Scope.Var{ - .base = Scope{ .id = .Var, .parent = parent_scope }, + .base = Scope{ .id = .Var, .parent = scope }, .c_name = c_name, .zig_name = c_name, // TODO: getWantedName }; @@ -527,11 +529,11 @@ fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDe .eq_token = eq_token, .mut_token = mut_token, .comptime_token = null, - .extern_export_token = null, // TODO ?TokenIndex, - .lib_name = null, // TODO ?*Node, + .extern_export_token = null, + .lib_name = null, .type_node = type_node, .align_node = null, // TODO ?*Node, - .section_node = null, // TODO ?*Node, + .section_node = null, .init_node = init_node, .semicolon_token = semicolon_token, }; From 1c86a191da400bd47a5044a5b84cf9a05b15066b Mon Sep 17 00:00:00 2001 From: hryx Date: Sun, 23 Jun 2019 01:03:28 -0700 Subject: [PATCH 22/35] Fix order of tokens; omit 'pub' for fn types --- src-self-hosted/translate_c.zig | 68 +++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index ec6460e4f..d85f20b92 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -271,7 +271,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { const proto_node = switch (ZigClangType_getTypeClass(fn_type)) { .FunctionProto => blk: { const fn_proto_type = @ptrCast(*const ZigClangFunctionProtoType, fn_type); - break :blk transFnProto(rp, fn_proto_type, fn_decl_loc, decl_ctx) catch |err| switch (err) { + break :blk transFnProto(rp, fn_proto_type, fn_decl_loc, decl_ctx, true) catch |err| switch (err) { error.UnsupportedType => { return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function"); }, @@ -280,7 +280,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { }, .FunctionNoProto => blk: { const fn_no_proto_type = @ptrCast(*const ZigClangFunctionType, fn_type); - break :blk transFnNoProto(rp, fn_no_proto_type, fn_decl_loc, decl_ctx) catch |err| switch (err) { + break :blk transFnNoProto(rp, fn_no_proto_type, fn_decl_loc, decl_ctx, true) catch |err| switch (err) { error.UnsupportedType => { return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function"); }, @@ -420,7 +420,6 @@ fn transCompoundStmtInline( while (it != end_it) : (it += 1) { const result = try transStmt(rp, parent_scope, it.*, .unused, .r_value); scope = result.child_scope; - std.debug.warn("id: {}\n", result.node.id); if (result.node != &block_node.base) try block_node.statements.push(result.node); } @@ -661,10 +660,13 @@ fn transCCast( if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type)) return transCPtrCast(rp, loc, dst_type, src_type, expr); if (cIsUnsignedInteger(dst_type) and qualTypeIsPtr(src_type)) { + const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc)); const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt"); try builtin_node.params.push(expr); builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); - return &(try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc), &builtin_node.base)).base; + try cast_node.op.Call.params.push(&builtin_node.base); + cast_node.rtoken = try appendToken(rp.c, .RParen, ")"); + return &cast_node.base; } if (cIsUnsignedInteger(src_type) and qualTypeIsPtr(dst_type)) { const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr"); @@ -677,7 +679,10 @@ fn transCCast( // TODO: maybe widen to increase size // TODO: maybe bitcast to change sign // TODO: maybe truncate to reduce size - return &(try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc), expr)).base; + const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc)); + try cast_node.op.Call.params.push(expr); + cast_node.rtoken = try appendToken(rp.c, .RParen, ")"); + return &cast_node.base; } fn transExpr( @@ -728,13 +733,15 @@ fn transCPtrCast( // void has 1-byte alignment, so @alignCast is not needed try ptrcast_node.params.push(expr); } else { + const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast"); const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf"); const child_type_node = try transQualType(rp, child_type, loc); try alignof_node.params.push(child_type_node); - const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast"); + alignof_node.rparen_token = try appendToken(rp.c, .RParen, ")"); try aligncast_node.params.push(&alignof_node.base); _ = try appendToken(rp.c, .Comma, ","); try aligncast_node.params.push(expr); + aligncast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); try ptrcast_node.params.push(&aligncast_node.base); } ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); @@ -909,7 +916,7 @@ fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.Builti return node; } -fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node, first_arg: *ast.Node) !*ast.Node.SuffixOp { +fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp { _ = try appendToken(c, .LParen, "("); const node = try c.a().create(ast.Node.SuffixOp); node.* = ast.Node.SuffixOp{ @@ -921,37 +928,34 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node, first_arg: *ast.Node) .async_attr = null, }, }, - .rtoken = try appendToken(c, .RParen, ")"), + .rtoken = undefined, // set after appending args }; - try node.op.Call.params.push(first_arg); return node; } fn transCreateNodePrefixOp( c: *Context, op: ast.Node.PrefixOp.Op, - rhs: *ast.Node, op_tok_id: std.zig.Token.Id, bytes: []const u8, -) !*ast.Node { +) !*ast.Node.PrefixOp { const node = try c.a().create(ast.Node.PrefixOp); node.* = ast.Node.PrefixOp{ .base = ast.Node{ .id = .PrefixOp }, .op_token = try appendToken(c, op_tok_id, bytes), .op = op, - .rhs = rhs, + .rhs = undefined, // translate and set afterward }; - return &node.base; + return node; } fn transCreateNodePtrType( c: *Context, is_const: bool, is_volatile: bool, - rhs: *ast.Node, op_tok_id: std.zig.Token.Id, bytes: []const u8, -) !*ast.Node { +) !*ast.Node.PrefixOp { const node = try c.a().create(ast.Node.PrefixOp); node.* = ast.Node.PrefixOp{ .base = ast.Node{ .id = .PrefixOp }, @@ -964,9 +968,9 @@ fn transCreateNodePtrType( .volatile_token = if (is_volatile) try appendToken(c, .Keyword_volatile, "volatile") else null, }, }, - .rhs = rhs, + .rhs = undefined, // translate and set afterward }; - return &node.base; + return node; } fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node { @@ -1038,7 +1042,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour }, .FunctionProto => { const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty); - const fn_proto = try transFnProto(rp, fn_proto_ty, source_loc, null); + const fn_proto = try transFnProto(rp, fn_proto_ty, source_loc, null, false); return &fn_proto.base; }, .Paren => { @@ -1047,28 +1051,33 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour }, .Pointer => { const child_qt = ZigClangType_getPointeeType(ty); - const child_node = try transQualType(rp, child_qt, source_loc); - if (qualTypeChildIsFnProto(child_qt)) - return transCreateNodePrefixOp(rp.c, .OptionalType, child_node, .QuestionMark, "?"); + if (qualTypeChildIsFnProto(child_qt)) { + const optional_node = try transCreateNodePrefixOp(rp.c, .OptionalType, .QuestionMark, "?"); + optional_node.rhs = try transQualType(rp, child_qt, source_loc); + return &optional_node.base; + } if (typeIsOpaque(rp.c, ZigClangQualType_getTypePtr(child_qt), source_loc)) { + const optional_node = try transCreateNodePrefixOp(rp.c, .OptionalType, .QuestionMark, "?"); const pointer_node = try transCreateNodePtrType( rp.c, ZigClangQualType_isConstQualified(child_qt), ZigClangQualType_isVolatileQualified(child_qt), - child_node, .Asterisk, "*", ); - return transCreateNodePrefixOp(rp.c, .OptionalType, pointer_node, .QuestionMark, "?"); + optional_node.rhs = &pointer_node.base; + pointer_node.rhs = try transQualType(rp, child_qt, source_loc); + return &optional_node.base; } - return transCreateNodePtrType( + const pointer_node = try transCreateNodePtrType( rp.c, ZigClangQualType_isConstQualified(child_qt), ZigClangQualType_isVolatileQualified(child_qt), - child_node, .BracketStarCBracket, "[*c]", ); + pointer_node.rhs = try transQualType(rp, child_qt, source_loc); + return &pointer_node.base; }, else => { const type_name = rp.c.str(ZigClangType_getTypeClassName(ty)); @@ -1103,6 +1112,7 @@ fn transFnProto( fn_proto_ty: *const ZigClangFunctionProtoType, source_loc: ZigClangSourceLocation, fn_decl_context: ?FnDeclContext, + is_pub: bool, ) !*ast.Node.FnProto { const fn_ty = @ptrCast(*const ZigClangFunctionType, fn_proto_ty); const cc = try transCC(rp, fn_ty, source_loc); @@ -1113,7 +1123,7 @@ fn transFnProto( return revertAndWarn(rp, error.UnsupportedType, source_loc, "TODO: implement parameters for FunctionProto in transType"); } - return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc); + return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub); } fn transFnNoProto( @@ -1121,10 +1131,11 @@ fn transFnNoProto( fn_ty: *const ZigClangFunctionType, source_loc: ZigClangSourceLocation, fn_decl_context: ?FnDeclContext, + is_pub: bool, ) !*ast.Node.FnProto { const cc = try transCC(rp, fn_ty, source_loc); const is_var_args = if (fn_decl_context) |ctx| !ctx.is_export else true; - return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc); + return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub); } fn finishTransFnProto( @@ -1134,6 +1145,7 @@ fn finishTransFnProto( fn_decl_context: ?FnDeclContext, is_var_args: bool, cc: CallingConvention, + is_pub: bool, ) !*ast.Node.FnProto { const is_export = if (fn_decl_context) |ctx| ctx.is_export else false; @@ -1141,7 +1153,7 @@ fn finishTransFnProto( // TODO check for align attribute // pub extern fn name(...) T - const pub_tok = try appendToken(rp.c, .Keyword_pub, "pub"); + const pub_tok = if (is_pub) try appendToken(rp.c, .Keyword_pub, "pub") else null; const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null; const extern_export_inline_tok = if (is_export) try appendToken(rp.c, .Keyword_export, "export") From 226a23d97730b5ee0b14d51abb4999e679259ac3 Mon Sep 17 00:00:00 2001 From: hryx Date: Sun, 23 Jun 2019 12:46:17 -0700 Subject: [PATCH 23/35] stage1: always render space after `fn` like stage2 --- src/ast_render.cpp | 3 +-- test/translate_c.zig | 18 +++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/ast_render.cpp b/src/ast_render.cpp index d93efe219..92508c220 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -444,9 +444,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { const char *extern_str = extern_string(node->data.fn_proto.is_extern); const char *export_str = export_string(node->data.fn_proto.is_export); const char *inline_str = inline_string(node->data.fn_proto.is_inline); - fprintf(ar->f, "%s%s%s%sfn", pub_str, inline_str, export_str, extern_str); + fprintf(ar->f, "%s%s%s%sfn ", pub_str, inline_str, export_str, extern_str); if (node->data.fn_proto.name != nullptr) { - fprintf(ar->f, " "); print_symbol(ar, node->data.fn_proto.name); } fprintf(ar->f, "("); diff --git a/test/translate_c.zig b/test/translate_c.zig index 930442f29..785f3d459 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -57,7 +57,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\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, c_ulong(@ptrToInt(func_ptr))); + \\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, c_ulong(@ptrToInt(func_ptr))); \\} ); @@ -357,7 +357,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\}; , \\pub const struct_Foo = extern struct { - \\ derp: ?extern fn([*c]struct_Foo) void, + \\ derp: ?extern fn ([*c]struct_Foo) void, \\}; , \\pub const Foo = struct_Foo; @@ -440,13 +440,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\extern char (*fn_ptr2)(int, float); \\#define bar fn_ptr2 , - \\pub extern var fn_ptr: ?extern fn() void; + \\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 extern var fn_ptr2: ?extern fn (c_int, f32) u8; , \\pub inline fn bar(arg0: c_int, arg1: f32) u8 { \\ return fn_ptr2.?(arg0, arg1); @@ -462,7 +462,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { cases.add("__cdecl doesn't mess up function pointers", \\void foo(void (__cdecl *fn_ptr)(void)); , - \\pub extern fn foo(fn_ptr: ?extern fn() void) void; + \\pub extern fn foo(fn_ptr: ?extern fn () void) void; ); cases.add("comment after integer literal", @@ -1209,8 +1209,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ return 0; \\} \\pub export fn bar() void { - \\ var f: ?extern fn() void = foo; - \\ var b: ?extern fn() c_int = baz; + \\ var f: ?extern fn () void = foo; + \\ var b: ?extern fn () c_int = baz; \\ f.?(); \\ f.?(); \\ foo(); @@ -1345,9 +1345,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { , \\pub const GLbitfield = c_uint; , - \\pub const PFNGLCLEARPROC = ?extern fn(GLbitfield) void; + \\pub const PFNGLCLEARPROC = ?extern fn (GLbitfield) void; , - \\pub const OpenGLProc = ?extern fn() void; + \\pub const OpenGLProc = ?extern fn () void; , \\pub const union_OpenGLProcs = extern union { \\ ptr: [1]OpenGLProc, From b2e06c3bf41669e02f07525bb483efedf2d77b95 Mon Sep 17 00:00:00 2001 From: hryx Date: Sun, 23 Jun 2019 14:32:45 -0700 Subject: [PATCH 24/35] Observe translate mode in stage2 --- src-self-hosted/translate_c.zig | 5 +++-- test/translate_c.zig | 40 ++++++++++++++++----------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index d85f20b92..bce68f886 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -261,7 +261,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, + .None => has_body and c.mode != .import, .Extern, .Static => false, .PrivateExtern => return failDecl(c, fn_decl_loc, fn_name, "unsupported storage class: private extern"), .Auto => unreachable, // Not legal on functions @@ -1148,6 +1148,7 @@ fn finishTransFnProto( is_pub: bool, ) !*ast.Node.FnProto { const is_export = if (fn_decl_context) |ctx| ctx.is_export else false; + const is_extern = if (fn_decl_context) |ctx| !ctx.has_body else true; // TODO check for always_inline attribute // TODO check for align attribute @@ -1157,7 +1158,7 @@ fn finishTransFnProto( const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null; const extern_export_inline_tok = if (is_export) try appendToken(rp.c, .Keyword_export, "export") - else if (cc == .C) + else if (cc == .C and is_extern) try appendToken(rp.c, .Keyword_extern, "extern") else null; diff --git a/test/translate_c.zig b/test/translate_c.zig index 785f3d459..9785189ce 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -19,25 +19,25 @@ pub fn addCases(cases: *tests.TranslateCContext) void { ); /////////////// Cases that pass for only stage2 //////////////// - 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("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("simple function definition", + // \\void foo(void) {} + // \\static void bar(void) {} + // , + // \\pub export fn foo() void {} + // \\pub extern fn bar() void {} + // ); /////////////// Cases for only stage1 which are TODO items for stage2 //////////////// @@ -47,7 +47,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub const REDISMODULE_READ = 1 << 0; ); - cases.add("casting pointers to ints and ints to pointers", + cases.add_both("casting pointers to ints and ints to pointers", \\void foo(void); \\void bar(void) { \\ void *func_ptr = foo; @@ -233,7 +233,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64) void; ); - cases.add("noreturn attribute", + cases.add_both("noreturn attribute", \\void foo(void) __attribute__((noreturn)); , \\pub extern fn foo() noreturn; From 69b90e0681bb42980eeb8364e50686a1f9702eb5 Mon Sep 17 00:00:00 2001 From: hryx Date: Sun, 23 Jun 2019 15:06:16 -0700 Subject: [PATCH 25/35] transStringLiteral --- src-self-hosted/clang.zig | 3 +++ src-self-hosted/translate_c.zig | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index d48c57c0a..1aa4cbfd6 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -965,3 +965,6 @@ pub extern fn ZigClangBinaryOperator_getOpcode(*const ZigClangBinaryOperator) Zi pub extern fn ZigClangBinaryOperator_getBeginLoc(*const ZigClangBinaryOperator) ZigClangSourceLocation; pub extern fn ZigClangBinaryOperator_getLHS(*const ZigClangBinaryOperator) *const ZigClangExpr; pub extern fn ZigClangBinaryOperator_getRHS(*const ZigClangBinaryOperator) *const ZigClangExpr; + +pub extern fn ZigClangStringLiteral_getKind(*const ZigClangStringLiteral) ZigClangStringLiteral_StringKind; +pub extern fn ZigClangStringLiteral_getString_bytes_begin_size(*const ZigClangStringLiteral, *usize) [*c]const u8; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index bce68f886..376515c96 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -336,6 +336,7 @@ fn transStmt( .ImplicitCastExprClass => return transImplicitCastExpr(rp, scope, @ptrCast(*const ZigClangImplicitCastExpr, stmt), result_used), .IntegerLiteralClass => return transIntegerLiteral(rp, scope, @ptrCast(*const ZigClangIntegerLiteral, stmt), result_used), .ReturnStmtClass => return transReturnStmt(rp, scope, @ptrCast(*const ZigClangReturnStmt, stmt)), + .StringLiteralClass => return transStringLiteral(rp, scope, @ptrCast(*const ZigClangStringLiteral, stmt), result_used), else => { return revertAndWarn( rp, @@ -647,6 +648,41 @@ fn transReturnStmt( }; } +fn transStringLiteral( + rp: RestorePoint, + scope: *Scope, + stmt: *const ZigClangStringLiteral, + result_used: ResultUsed, +) !TransResult { + const kind = ZigClangStringLiteral_getKind(stmt); + switch (kind) { + .Ascii, .UTF8 => { + var len: usize = undefined; + const cstr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &len); + const zstr = try rp.c.str(cstr); + const token = try appendToken(rp.c, .StringLiteral, zstr); + const node = try rp.c.a().create(ast.Node.StringLiteral); + node.* = ast.Node.StringLiteral{ + .base = ast.Node{ .id = .StringLiteral }, + .token = token, + }; + const res = TransResult{ + .node = &node.base, + .child_scope = scope, + .node_scope = scope, + }; + return maybeSuppressResult(rp, scope, result_used, res); + }, + .UTF16, .UTF32, .Wide => return revertAndWarn( + rp, + error.UnsupportedTranslation, + ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt)), + "TODO: support string literal kind {}", + kind, + ), + } +} + fn transCCast( rp: RestorePoint, scope: *Scope, From f845994839697315aba7c4d4ce80d04d0d7b8ab0 Mon Sep 17 00:00:00 2001 From: hryx Date: Sun, 23 Jun 2019 17:17:21 -0700 Subject: [PATCH 26/35] transBinaryOperator: Add, Sub --- src-self-hosted/clang.zig | 1 + src-self-hosted/translate_c.zig | 51 +++++++++++++++++++++++++++++++-- src/zig_clang.cpp | 5 ++++ src/zig_clang.h | 1 + 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 1aa4cbfd6..e2608e653 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -965,6 +965,7 @@ pub extern fn ZigClangBinaryOperator_getOpcode(*const ZigClangBinaryOperator) Zi pub extern fn ZigClangBinaryOperator_getBeginLoc(*const ZigClangBinaryOperator) ZigClangSourceLocation; pub extern fn ZigClangBinaryOperator_getLHS(*const ZigClangBinaryOperator) *const ZigClangExpr; pub extern fn ZigClangBinaryOperator_getRHS(*const ZigClangBinaryOperator) *const ZigClangExpr; +pub extern fn ZigClangBinaryOperator_getType(*const ZigClangBinaryOperator) ZigClangQualType; pub extern fn ZigClangStringLiteral_getKind(*const ZigClangStringLiteral) ZigClangStringLiteral_StringKind; pub extern fn ZigClangStringLiteral_getString_bytes_begin_size(*const ZigClangStringLiteral, *usize) [*c]const u8; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 376515c96..47914d9e9 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -356,6 +356,7 @@ fn transBinaryOperator( result_used: ResultUsed, ) TransError!TransResult { const op = ZigClangBinaryOperator_getOpcode(stmt); + const qt = ZigClangBinaryOperator_getType(stmt); switch (op) { .PtrMemD, .PtrMemI, .Cmp => return revertAndWarn( rp, @@ -369,11 +370,31 @@ fn transBinaryOperator( .child_scope = scope, .node_scope = scope, }, + .Add => { + const node = if (cIsUnsignedInteger(qt)) + try transCreateNodeInfixOp(rp, scope, stmt, .AddWrap, .PlusPercent, "+%") + else + try transCreateNodeInfixOp(rp, scope, stmt, .Add, .Plus, "+"); + return maybeSuppressResult(rp, scope, result_used, TransResult{ + .node = &node.base, + .child_scope = scope, + .node_scope = scope, + }); + }, + .Sub => { + const node = if (cIsUnsignedInteger(qt)) + try transCreateNodeInfixOp(rp, scope, stmt, .SubWrap, .MinusPercent, "-%") + else + try transCreateNodeInfixOp(rp, scope, stmt, .Sub, .Minus, "-"); + return maybeSuppressResult(rp, scope, result_used, TransResult{ + .node = &node.base, + .child_scope = scope, + .node_scope = scope, + }); + }, .Mul, .Div, .Rem, - .Sub, - .Add, .Shl, .Shr, .LT, @@ -660,7 +681,7 @@ fn transStringLiteral( var len: usize = undefined; const cstr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &len); const zstr = try rp.c.str(cstr); - const token = try appendToken(rp.c, .StringLiteral, zstr); + const token = try appendTokenFmt(rp.c, .StringLiteral, "c\"{}\"", zstr); // TODO: escape string const node = try rp.c.a().create(ast.Node.StringLiteral); node.* = ast.Node.StringLiteral{ .base = ast.Node{ .id = .StringLiteral }, @@ -792,6 +813,8 @@ fn maybeSuppressResult( result: TransResult, ) !TransResult { if (used == .used) return result; + // NOTE: This is backwards, but the semicolon must immediately follow the node. + _ = try appendToken(rp.c, .Semicolon, ";"); const lhs = try appendIdentifier(rp.c, "_"); const op_token = try appendToken(rp.c, .Equal, "="); const op_node = try rp.c.a().create(ast.Node.InfixOp); @@ -985,6 +1008,28 @@ fn transCreateNodePrefixOp( return node; } +fn transCreateNodeInfixOp( + rp: RestorePoint, + scope: *Scope, + stmt: *const ZigClangBinaryOperator, + op: ast.Node.InfixOp.Op, + op_tok_id: std.zig.Token.Id, + bytes: []const u8, +) !*ast.Node.InfixOp { + const lhs = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value); + const op_token = try appendToken(rp.c, op_tok_id, bytes); + const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); + const node = try rp.c.a().create(ast.Node.InfixOp); + node.* = ast.Node.InfixOp{ + .base = ast.Node{ .id = .InfixOp }, + .op_token = op_token, + .lhs = lhs.node, + .op = op, + .rhs = rhs.node, + }; + return node; +} + fn transCreateNodePtrType( c: *Context, is_const: bool, diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index fd675effb..7c87f3112 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -2042,3 +2042,8 @@ const struct ZigClangExpr *ZigClangBinaryOperator_getRHS(const struct ZigClangBi auto casted = reinterpret_cast(self); return reinterpret_cast(casted->getRHS()); } + +struct ZigClangQualType ZigClangBinaryOperator_getType(const struct ZigClangBinaryOperator *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getType()); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index 99d742d4e..ffa2291d9 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -925,5 +925,6 @@ ZIG_EXTERN_C enum ZigClangBO ZigClangBinaryOperator_getOpcode(const struct ZigCl ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangBinaryOperator_getBeginLoc(const struct ZigClangBinaryOperator *); ZIG_EXTERN_C const struct ZigClangExpr *ZigClangBinaryOperator_getLHS(const struct ZigClangBinaryOperator *); ZIG_EXTERN_C const struct ZigClangExpr *ZigClangBinaryOperator_getRHS(const struct ZigClangBinaryOperator *); +ZIG_EXTERN_C struct ZigClangQualType ZigClangBinaryOperator_getType(const struct ZigClangBinaryOperator *); #endif From 84353515817929d694efd22e528e00e8de3d41a1 Mon Sep 17 00:00:00 2001 From: hryx Date: Mon, 24 Jun 2019 22:37:19 -0700 Subject: [PATCH 27/35] Escape C string literals --- src-self-hosted/translate_c.zig | 47 ++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 47914d9e9..be8e7bd66 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -678,10 +678,20 @@ fn transStringLiteral( const kind = ZigClangStringLiteral_getKind(stmt); switch (kind) { .Ascii, .UTF8 => { - var len: usize = undefined; - const cstr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &len); + var clen: usize = undefined; + const cstr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &clen); const zstr = try rp.c.str(cstr); - const token = try appendTokenFmt(rp.c, .StringLiteral, "c\"{}\"", zstr); // TODO: escape string + + var len: usize = 0; + for (zstr) |c| len += escapeChar(c).len; + + const buf = try rp.c.a().alloc(u8, len + "c\"\"".len); + buf[0] = 'c'; + buf[1] = '"'; + writeEscapedString(buf[2..], zstr); + buf[buf.len - 1] = '"'; + + const token = try appendToken(rp.c, .StringLiteral, buf); const node = try rp.c.a().create(ast.Node.StringLiteral); node.* = ast.Node.StringLiteral{ .base = ast.Node{ .id = .StringLiteral }, @@ -704,6 +714,37 @@ fn transStringLiteral( } } +fn escapedStringLen(s: []const u8) usize { + var len: usize = 0; + for (s) |c| len += escapeChar(c).len; + return len; +} + +fn writeEscapedString(buf: []u8, s: []const u8) void { + var i: usize = 0; + for (s) |c| { + const escaped = escapeChar(c); + std.mem.copy(u8, buf[i..], escaped); + i += escaped.len; + } +} + +fn escapeChar(c: u8) []const u8 { + // TODO: https://github.com/ziglang/zig/issues/2749 + switch (c) { + // Printable ASCII except for ' " \ + ' ', '!', '#'...'&', '('...'[', ']'...'~' => return ([_]u8{c})[0..], + '\'', '\"', '\\' => return ([_]u8{ '\\', c })[0..], + '\n' => return "\\n"[0..], + '\r' => return "\\r"[0..], + '\t' => return "\\t"[0..], + else => { + var buf: [4]u8 = undefined; + return std.fmt.bufPrint(buf[0..], "\\x{x2}", c) catch unreachable; + }, + } +} + fn transCCast( rp: RestorePoint, scope: *Scope, From b4bd52cc515e698a0bcf64653d829efeb2e0b4cb Mon Sep 17 00:00:00 2001 From: hryx Date: Thu, 27 Jun 2019 21:02:48 -0700 Subject: [PATCH 28/35] Create and render big.Int from IntegerLiteral; group BinaryOperator --- src-self-hosted/translate_c.zig | 40 +++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index be8e7bd66..a8ce601d5 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -372,22 +372,22 @@ fn transBinaryOperator( }, .Add => { const node = if (cIsUnsignedInteger(qt)) - try transCreateNodeInfixOp(rp, scope, stmt, .AddWrap, .PlusPercent, "+%") + try transCreateNodeInfixOp(rp, scope, stmt, .AddWrap, .PlusPercent, "+%", true) else - try transCreateNodeInfixOp(rp, scope, stmt, .Add, .Plus, "+"); + try transCreateNodeInfixOp(rp, scope, stmt, .Add, .Plus, "+", true); return maybeSuppressResult(rp, scope, result_used, TransResult{ - .node = &node.base, + .node = node, .child_scope = scope, .node_scope = scope, }); }, .Sub => { const node = if (cIsUnsignedInteger(qt)) - try transCreateNodeInfixOp(rp, scope, stmt, .SubWrap, .MinusPercent, "-%") + try transCreateNodeInfixOp(rp, scope, stmt, .SubWrap, .MinusPercent, "-%", true) else - try transCreateNodeInfixOp(rp, scope, stmt, .Sub, .Minus, "-"); + try transCreateNodeInfixOp(rp, scope, stmt, .Sub, .Minus, "-", true); return maybeSuppressResult(rp, scope, result_used, TransResult{ - .node = &node.base, + .node = node, .child_scope = scope, .node_scope = scope, }); @@ -1056,7 +1056,9 @@ fn transCreateNodeInfixOp( op: ast.Node.InfixOp.Op, op_tok_id: std.zig.Token.Id, bytes: []const u8, -) !*ast.Node.InfixOp { + grouped: bool, +) !*ast.Node { + const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined; const lhs = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value); const op_token = try appendToken(rp.c, op_tok_id, bytes); const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); @@ -1068,7 +1070,16 @@ fn transCreateNodeInfixOp( .op = op, .rhs = rhs.node, }; - return node; + if (!grouped) return &node.base; + const rparen = try appendToken(rp.c, .RParen, ")"); + const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression); + grouped_expr.* = ast.Node.GroupedExpression{ + .base = ast.Node{ .id = .GroupedExpression }, + .lparen = lparen, + .expr = &node.base, + .rparen = rparen, + }; + return &grouped_expr.base; } fn transCreateNodePtrType( @@ -1096,10 +1107,21 @@ fn transCreateNodePtrType( } fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node { + const num_limbs = ZigClangAPSInt_getNumWords(int.?); + var big = try std.math.big.Int.initCapacity(c.a(), num_limbs); + defer big.deinit(); + const data = ZigClangAPSInt_getRawData(int.?); + var i: usize = 0; + while (i < num_limbs) : (i += 1) big.limbs[i] = data[i]; + const str = big.toString(c.a(), 10) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + else => unreachable, + }; + const token = try appendToken(c, .IntegerLiteral, str); const node = try c.a().create(ast.Node.IntegerLiteral); node.* = ast.Node.IntegerLiteral{ .base = ast.Node{ .id = .IntegerLiteral }, - .token = try appendToken(c, .IntegerLiteral, "3333333"), // TODO + .token = token, }; return &node.base; } From 3e0ff32bd84102e4ea892bfdab6cd20daab83897 Mon Sep 17 00:00:00 2001 From: hryx Date: Thu, 27 Jun 2019 21:17:27 -0700 Subject: [PATCH 29/35] Separate with space instead of LF to prevent rendering excessive indentation --- src-self-hosted/translate_c.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index a8ce601d5..28b75237c 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -1452,7 +1452,7 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, .start = start_index, .end = end_index, }; - try c.source_buffer.appendByte('\n'); + try c.source_buffer.appendByte(' '); return token_index; } From 646268875e04250609d7e355af1618077c4a290f Mon Sep 17 00:00:00 2001 From: hryx Date: Thu, 27 Jun 2019 22:16:31 -0700 Subject: [PATCH 30/35] Use new width format option --- src-self-hosted/translate_c.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 28b75237c..efab42845 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -740,7 +740,7 @@ fn escapeChar(c: u8) []const u8 { '\t' => return "\\t"[0..], else => { var buf: [4]u8 = undefined; - return std.fmt.bufPrint(buf[0..], "\\x{x2}", c) catch unreachable; + return std.fmt.bufPrint(buf[0..], "\\x{x:2}", c) catch unreachable; }, } } From cc74bf51366c71ba997eb3015f2b687a3a18fd57 Mon Sep 17 00:00:00 2001 From: hryx Date: Thu, 27 Jun 2019 23:12:33 -0700 Subject: [PATCH 31/35] Translate IntegralCast; add stage2 test coverage --- src-self-hosted/translate_c.zig | 9 +++++ test/translate_c.zig | 61 ++++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index efab42845..d6b72f3dd 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -615,6 +615,15 @@ fn transImplicitCastExpr( .child_scope = scope, }; }, + .IntegralCast => { + const dest_type = ZigClangExpr_getType(@ptrCast(*const ZigClangExpr, expr)); + const src_type = ZigClangExpr_getType(sub_expr); + return TransResult{ + .node = try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node.node), + .node_scope = scope, + .child_scope = scope, + }; + }, .FunctionToPointerDecay, .ArrayToPointerDecay => { return maybeSuppressResult(rp, scope, result_used, sub_expr_node); }, diff --git a/test/translate_c.zig b/test/translate_c.zig index 9785189ce..d7f8cba0e 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -18,7 +18,46 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub extern fn bar() c_int; ); + cases.add_both("simple var decls", + \\void foo(void) { + \\ int a; + \\ char b = 123; + \\ const int c; + \\ const unsigned d = 440; + \\} + , + \\pub fn foo() void { + \\ var a: c_int = undefined; + \\ var b: u8 = u8(123); + \\ const c: c_int = undefined; + \\ const d: c_uint = c_uint(440); + \\} + ); + + cases.add_both("ignore result, explicit function arguments", + \\void foo(void) { + \\ int a; + \\ 1; + \\ "hey"; + \\ 1 + 1; + \\ 1 - 1; + \\ a = 1; + \\} + , + \\pub fn foo() void { + \\ var a: c_int = undefined; + \\ _ = 1; + \\ _ = c"hey"; + \\ _ = (1 + 1); + \\ _ = (1 - 1); + \\ a = 1; + \\} + ); + /////////////// 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) {} @@ -39,8 +78,28 @@ pub fn addCases(cases: *tests.TranslateCContext) void { // \\pub extern fn bar() void {} // ); + cases.add_2("parameterless function prototypes", + \\void a() {} + \\void b(void) {} + \\void c(); + \\void d(void); + , + \\pub fn a(...) void {} + \\pub fn b() void {} + \\pub extern fn c(...) void; + \\pub extern fn d() void; + ); + /////////////// Cases for only stage1 which are TODO items for stage2 //////////////// + cases.add_both("simple function definition", + \\void foo(void) {} + \\static void bar(void) {} + , + \\pub fn foo() void {} + \\pub fn bar() void {} + ); + cases.add("macro with left shift", \\#define REDISMODULE_READ (1<<0) , @@ -132,7 +191,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} ); - cases.add("ignore result", + cases.add("ignore result, no function arguments", \\void foo() { \\ int a; \\ 1; From 102bf5200cfd82c1df6d503059e70c37b4925361 Mon Sep 17 00:00:00 2001 From: hryx Date: Fri, 28 Jun 2019 17:40:20 -0700 Subject: [PATCH 32/35] Fix string literal: not null-terminated (thanks @mikdusan) --- src-self-hosted/translate_c.zig | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index d6b72f3dd..574e395d1 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -687,17 +687,17 @@ fn transStringLiteral( const kind = ZigClangStringLiteral_getKind(stmt); switch (kind) { .Ascii, .UTF8 => { - var clen: usize = undefined; - const cstr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &clen); - const zstr = try rp.c.str(cstr); + var len: usize = undefined; + const bytes_ptr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &len); + const str = bytes_ptr[0..len]; - var len: usize = 0; - for (zstr) |c| len += escapeChar(c).len; + len = 0; + for (str) |c| len += escapeChar(c).len; const buf = try rp.c.a().alloc(u8, len + "c\"\"".len); buf[0] = 'c'; buf[1] = '"'; - writeEscapedString(buf[2..], zstr); + writeEscapedString(buf[2..], str); buf[buf.len - 1] = '"'; const token = try appendToken(rp.c, .StringLiteral, buf); From 247e567422a0efde2ed1f2cbf1b16f217f2b61d9 Mon Sep 17 00:00:00 2001 From: hryx Date: Fri, 28 Jun 2019 18:01:41 -0700 Subject: [PATCH 33/35] Don't return a slice pointing to a deceased stack address --- src-self-hosted/translate_c.zig | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 574e395d1..b18397ede 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -691,8 +691,9 @@ fn transStringLiteral( const bytes_ptr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &len); const str = bytes_ptr[0..len]; + var char_buf: [4]u8 = undefined; len = 0; - for (str) |c| len += escapeChar(c).len; + for (str) |c| len += escapeChar(c, &char_buf).len; const buf = try rp.c.a().alloc(u8, len + "c\"\"".len); buf[0] = 'c'; @@ -725,33 +726,35 @@ fn transStringLiteral( fn escapedStringLen(s: []const u8) usize { var len: usize = 0; - for (s) |c| len += escapeChar(c).len; + var char_buf: [4]u8 = undefined; + for (s) |c| len += escapeChar(c, &char_buf).len; return len; } fn writeEscapedString(buf: []u8, s: []const u8) void { + var char_buf: [4]u8 = undefined; var i: usize = 0; for (s) |c| { - const escaped = escapeChar(c); + const escaped = escapeChar(c, &char_buf); std.mem.copy(u8, buf[i..], escaped); i += escaped.len; } } -fn escapeChar(c: u8) []const u8 { +// Returns either a string literal or a slice of `buf`. +fn escapeChar(c: u8, char_buf: *[4]u8) []const u8 { // TODO: https://github.com/ziglang/zig/issues/2749 - switch (c) { + const escaped = switch (c) { // Printable ASCII except for ' " \ - ' ', '!', '#'...'&', '('...'[', ']'...'~' => return ([_]u8{c})[0..], - '\'', '\"', '\\' => return ([_]u8{ '\\', c })[0..], + ' ', '!', '#'...'&', '('...'[', ']'...'~' => ([_]u8{c})[0..], + '\'', '\"', '\\' => ([_]u8{ '\\', c })[0..], '\n' => return "\\n"[0..], '\r' => return "\\r"[0..], '\t' => return "\\t"[0..], - else => { - var buf: [4]u8 = undefined; - return std.fmt.bufPrint(buf[0..], "\\x{x:2}", c) catch unreachable; - }, - } + else => return std.fmt.bufPrint(char_buf[0..], "\\x{x:2}", c) catch unreachable, + }; + std.mem.copy(u8, char_buf, escaped); + return char_buf[0..escaped.len]; } fn transCCast( From 0e38f7215bede51b2ad3b8574e8b472c279d3db4 Mon Sep 17 00:00:00 2001 From: hryx Date: Sat, 29 Jun 2019 14:34:00 -0700 Subject: [PATCH 34/35] Define different struct size for APValue on Windows (thanks @Sahnvour) --- src-self-hosted/clang.zig | 4 +++- src/zig_clang.h | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index e2608e653..db76185ab 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -1,3 +1,5 @@ +const builtin = @import("builtin"); + pub const struct_ZigClangAPSInt = @OpaqueType(); pub const struct_ZigClangAPFloat = @OpaqueType(); pub const struct_ZigClangASTContext = @OpaqueType(); @@ -938,7 +940,7 @@ pub const struct_ZigClangExprEvalResult = extern struct { pub const struct_ZigClangAPValue = extern struct { Kind: ZigClangAPValue_ValueKind, - Data: [68]u8, // TODO: is there a way to statically assert that this matches the .h? + Data: if (builtin.os == .windows) [52]u8 else [68]u8, }; pub const ZigClangAPValue_ValueKind = extern enum { diff --git a/src/zig_clang.h b/src/zig_clang.h index ffa2291d9..183aaef68 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -47,7 +47,12 @@ enum ZigClangAPValue_ValueKind { struct ZigClangAPValue { enum ZigClangAPValue_ValueKind Kind; - char Data[68]; // experimentally-derived size of clang::APValue::DataType + // experimentally-derived size of clang::APValue::DataType +#ifdef _WIN32 + char Data[52]; +#else + char Data[68]; +#endif }; struct ZigClangExprEvalResult { From 776423bbf72312e756eb661b616f0e1bb805f568 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 15 Jul 2019 23:44:44 -0400 Subject: [PATCH 35/35] fix result location alignment in ir_render_call --- src/codegen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 94e2a98b2..234b28219 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3837,7 +3837,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr return result_loc; } else if (handle_is_ptr(src_return_type)) { LLVMValueRef store_instr = LLVMBuildStore(g->builder, result, result_loc); - LLVMSetAlignment(store_instr, LLVMGetAlignment(result_loc)); + LLVMSetAlignment(store_instr, get_ptr_align(g, instruction->result_loc->value.type)); return result_loc; } else { return result;