Skip to content

Commit a7f99c8

Browse files
committed
self-hosted translate-c: iterate over top level decls
See #1964
1 parent 01365be commit a7f99c8

File tree

5 files changed

+404
-22
lines changed

5 files changed

+404
-22
lines changed

src-self-hosted/clang.zig

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ pub extern fn ZigClangSourceManager_getCharacterData(arg0: ?*const struct_ZigCla
813813
pub extern fn ZigClangASTContext_getPointerType(arg0: ?*const struct_ZigClangASTContext, T: struct_ZigClangQualType) struct_ZigClangQualType;
814814
pub extern fn ZigClangASTUnit_getASTContext(arg0: ?*struct_ZigClangASTUnit) ?*struct_ZigClangASTContext;
815815
pub extern fn ZigClangASTUnit_getSourceManager(arg0: ?*struct_ZigClangASTUnit) ?*struct_ZigClangSourceManager;
816-
pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(arg0: ?*struct_ZigClangASTUnit, context: ?*c_void, Fn: ?extern fn (?*c_void, ?*const struct_ZigClangDecl) bool) bool;
816+
pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTUnit, context: ?*c_void, Fn: ?extern fn (?*c_void, *const struct_ZigClangDecl) bool) bool;
817817
pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) ?*const struct_ZigClangRecordDecl;
818818
pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) ?*const struct_ZigClangEnumDecl;
819819
pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl;
@@ -967,3 +967,83 @@ pub extern fn ZigClangLoadFromCommandLine(
967967
errors_len: *usize,
968968
resources_path: [*c]const u8,
969969
) ?*ZigClangASTUnit;
970+
971+
972+
pub extern fn ZigClangDecl_getKind(decl: *const ZigClangDecl) ZigClangDeclKind;
973+
974+
pub const ZigClangDeclKind = extern enum {
975+
AccessSpec,
976+
Block,
977+
Captured,
978+
ClassScopeFunctionSpecialization,
979+
Empty,
980+
Export,
981+
ExternCContext,
982+
FileScopeAsm,
983+
Friend,
984+
FriendTemplate,
985+
Import,
986+
LinkageSpec,
987+
Label,
988+
Namespace,
989+
NamespaceAlias,
990+
ObjCCompatibleAlias,
991+
ObjCCategory,
992+
ObjCCategoryImpl,
993+
ObjCImplementation,
994+
ObjCInterface,
995+
ObjCProtocol,
996+
ObjCMethod,
997+
ObjCProperty,
998+
BuiltinTemplate,
999+
ClassTemplate,
1000+
FunctionTemplate,
1001+
TypeAliasTemplate,
1002+
VarTemplate,
1003+
TemplateTemplateParm,
1004+
Enum,
1005+
Record,
1006+
CXXRecord,
1007+
ClassTemplateSpecialization,
1008+
ClassTemplatePartialSpecialization,
1009+
TemplateTypeParm,
1010+
ObjCTypeParam,
1011+
TypeAlias,
1012+
Typedef,
1013+
UnresolvedUsingTypename,
1014+
Using,
1015+
UsingDirective,
1016+
UsingPack,
1017+
UsingShadow,
1018+
ConstructorUsingShadow,
1019+
Binding,
1020+
Field,
1021+
ObjCAtDefsField,
1022+
ObjCIvar,
1023+
Function,
1024+
CXXDeductionGuide,
1025+
CXXMethod,
1026+
CXXConstructor,
1027+
CXXConversion,
1028+
CXXDestructor,
1029+
MSProperty,
1030+
NonTypeTemplateParm,
1031+
Var,
1032+
Decomposition,
1033+
ImplicitParam,
1034+
OMPCapturedExpr,
1035+
ParmVar,
1036+
VarTemplateSpecialization,
1037+
VarTemplatePartialSpecialization,
1038+
EnumConstant,
1039+
IndirectField,
1040+
OMPDeclareReduction,
1041+
UnresolvedUsingValue,
1042+
OMPRequires,
1043+
OMPThreadPrivate,
1044+
ObjCPropertyImpl,
1045+
PragmaComment,
1046+
PragmaDetectMismatch,
1047+
StaticAssert,
1048+
TranslationUnit,
1049+
};

src-self-hosted/translate_c.zig

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// This is the userland implementation of translate-c which will be used by both stage1
2-
// and stage2. Currently it's not used by anything, as it's not feature complete.
2+
// and stage2. Currently the only way it is used is with `zig translate-c-2`.
33

44
const std = @import("std");
55
const ast = std.zig.ast;
@@ -13,6 +13,16 @@ pub const Mode = enum {
1313

1414
pub const ClangErrMsg = Stage2ErrorMsg;
1515

16+
pub const Error = error {
17+
OutOfMemory,
18+
};
19+
20+
const Context = struct {
21+
tree: *ast.Tree,
22+
source_buffer: *std.Buffer,
23+
err: Error,
24+
};
25+
1626
pub fn translate(
1727
backing_allocator: *std.mem.Allocator,
1828
args_begin: [*]?[*]const u8,
@@ -57,23 +67,65 @@ pub fn translate(
5767

5868
var source_buffer = try std.Buffer.initSize(arena, 0);
5969

60-
try appendToken(tree, &source_buffer, "// TODO: implement more than just an empty source file", .LineComment);
70+
var context = Context{
71+
.tree = tree,
72+
.source_buffer = &source_buffer,
73+
.err = undefined,
74+
};
75+
76+
if (!ZigClangASTUnit_visitLocalTopLevelDecls(ast_unit, &context, declVisitorC)) {
77+
return context.err;
78+
}
6179

62-
try appendToken(tree, &source_buffer, "", .Eof);
80+
try appendToken(&context, .Eof, "");
6381
tree.source = source_buffer.toOwnedSlice();
6482
return tree;
6583
}
6684

67-
fn appendToken(tree: *ast.Tree, source_buffer: *std.Buffer, src_text: []const u8, token_id: Token.Id) !void {
68-
const start_index = source_buffer.len();
69-
try source_buffer.append(src_text);
70-
const end_index = source_buffer.len();
71-
const new_token = try tree.tokens.addOne();
85+
extern fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) bool {
86+
const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context));
87+
declVisitor(c, decl) catch |err| {
88+
c.err = err;
89+
return false;
90+
};
91+
return true;
92+
}
93+
94+
fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
95+
switch (ZigClangDecl_getKind(decl)) {
96+
.Function => {
97+
try appendToken(c, .LineComment, "// TODO translate function decl");
98+
},
99+
.Typedef => {
100+
try appendToken(c, .LineComment, "// TODO translate typedef");
101+
},
102+
.Enum => {
103+
try appendToken(c, .LineComment, "// TODO translate enum");
104+
},
105+
.Record => {
106+
try appendToken(c, .LineComment, "// TODO translate struct");
107+
},
108+
.Var => {
109+
try appendToken(c, .LineComment, "// TODO translate variable");
110+
},
111+
else => {
112+
// TODO emit_warning(c, bitcast(decl->getLocation()), "ignoring %s decl", decl->getDeclKindName());
113+
try appendToken(c, .LineComment, "// TODO translate unknown decl");
114+
},
115+
}
116+
}
117+
118+
fn appendToken(c: *Context, token_id: Token.Id, src_text: []const u8) !void {
119+
const start_index = c.source_buffer.len();
120+
try c.source_buffer.append(src_text);
121+
const end_index = c.source_buffer.len();
122+
const new_token = try c.tree.tokens.addOne();
72123
new_token.* = Token{
73124
.id = token_id,
74125
.start = start_index,
75126
.end = end_index,
76127
};
128+
try c.source_buffer.appendByte('\n');
77129
}
78130

79131
pub fn freeErrors(errors: []ClangErrMsg) void {

src/translate_c.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4554,28 +4554,27 @@ static void visit_var_decl(Context *c, const clang::VarDecl *var_decl) {
45544554
return;
45554555
}
45564556

4557-
static bool decl_visitor(void *context, const ZigClangDecl *zdecl) {
4558-
const clang::Decl *decl = reinterpret_cast<const clang::Decl *>(zdecl);
4557+
static bool decl_visitor(void *context, const ZigClangDecl *decl) {
45594558
Context *c = (Context*)context;
45604559

4561-
switch (decl->getKind()) {
4562-
case clang::Decl::Function:
4563-
visit_fn_decl(c, static_cast<const clang::FunctionDecl*>(decl));
4560+
switch (ZigClangDecl_getKind(decl)) {
4561+
case ZigClangDeclFunction:
4562+
visit_fn_decl(c, reinterpret_cast<const clang::FunctionDecl*>(decl));
45644563
break;
4565-
case clang::Decl::Typedef:
4564+
case ZigClangDeclTypedef:
45664565
resolve_typedef_decl(c, reinterpret_cast<const ZigClangTypedefNameDecl *>(decl));
45674566
break;
4568-
case clang::Decl::Enum:
4567+
case ZigClangDeclEnum:
45694568
resolve_enum_decl(c, reinterpret_cast<const ZigClangEnumDecl *>(decl));
45704569
break;
4571-
case clang::Decl::Record:
4572-
resolve_record_decl(c, (const ZigClangRecordDecl *)(decl));
4570+
case ZigClangDeclRecord:
4571+
resolve_record_decl(c, reinterpret_cast<const ZigClangRecordDecl *>(decl));
45734572
break;
4574-
case clang::Decl::Var:
4575-
visit_var_decl(c, static_cast<const clang::VarDecl *>(decl));
4573+
case ZigClangDeclVar:
4574+
visit_var_decl(c, reinterpret_cast<const clang::VarDecl *>(decl));
45764575
break;
45774576
default:
4578-
emit_warning(c, bitcast(decl->getLocation()), "ignoring %s decl", decl->getDeclKindName());
4577+
emit_warning(c, ZigClangDecl_getLocation(decl), "ignoring %s decl", ZigClangDecl_getDeclKindName(decl));
45794578
}
45804579

45814580
return true;

0 commit comments

Comments
 (0)