aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src-self-hosted/translate_c.zig453
-rw-r--r--src/zig_clang.cpp93
-rw-r--r--src/zig_clang.h36
3 files changed, 577 insertions, 5 deletions
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index b7ced4a89f..6d64a28f1f 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);
@@ -107,6 +107,8 @@ 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 {
return &c.tree.arena_allocator.allocator;
@@ -183,6 +185,8 @@ 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{
.base = Scope{
@@ -195,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);
@@ -295,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;
@@ -323,6 +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), result_used),
else => {
return revertAndWarn(
rp,
@@ -368,6 +378,274 @@ 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);
+ var scope = parent_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.*);
+
+ 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")
+ else
+ try appendToken(c, .Keyword_var, "var");
+ 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 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 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;
+ const semicolon_token = try appendToken(c, .Semicolon, ";");
+
+ const node = try 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,
+ .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 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,
+ 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 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, sub_expr_node.node),
+ .node_scope = scope,
+ .child_scope = scope,
+ };
+ },
+ .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,
+ ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, expr)),
+ "TODO implement translation of CastKind {}",
+ @tagName(kind),
+ ),
+ }
+}
+
+fn transCCast(
+ rp: RestorePoint,
+ scope: *Scope,
+ loc: ZigClangSourceLocation,
+ dst_type: ZigClangQualType,
+ src_type: ZigClangQualType,
+ 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(
+ 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 {
+ var scope = inner;
+ while (true) : (scope = scope.parent orelse unreachable) {
+ if (scope.id == .Block) return @fieldParentPtr(Scope.Block, "base", scope);
+ }
+}
+
+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 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,
+ 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);
}
@@ -376,11 +654,153 @@ 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(paren_type);
+ return ZigClangQualType_getTypeClass(inner_type) == .FunctionProto;
+ }
+ if (ZigClangType_getTypeClass(ty) == .Attributed) {
+ const attr_type = @ptrCast(*const ZigClangAttributedType, ty);
+ return qualTypeChildIsFnProto(ZigClangAttributedType_getEquivalentType(attr_type));
+ }
+ return false;
+}
+
fn qualTypeCanon(qt: ZigClangQualType) *const ZigClangType {
const canon = ZigClangQualType_getCanonicalType(qt);
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);
+}
+
+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,
@@ -432,6 +852,33 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
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);
+ 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,
+ );
+ },
else => {
const type_name = rp.c.str(ZigClangType_getTypeClassName(ty));
return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported type: '{}'", type_name);
diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp
index 28062ea69f..6283f7b67d 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<void *>(&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<ZigClangSourceManager *>(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<clang::ASTUnit *>(self)->visitLocalTopLevelDecls(context,
@@ -1540,6 +1546,11 @@ const ZigClangType *ZigClangQualType_getTypePtr(ZigClangQualType self) {
return reinterpret_cast<const ZigClangType *>(ty);
}
+ZigClangTypeClass ZigClangQualType_getTypeClass(ZigClangQualType self) {
+ clang::QualType ty = bitcast(self);
+ return (ZigClangTypeClass)(ty->getTypeClass());
+}
+
void ZigClangQualType_addConst(ZigClangQualType *self) {
reinterpret_cast<clang::QualType *>(self)->addConst();
}
@@ -1815,6 +1826,21 @@ void ZigClangASTUnit_delete(struct ZigClangASTUnit *self) {
delete reinterpret_cast<clang::ASTUnit *>(self);
}
+struct ZigClangQualType ZigClangVarDecl_getType(const struct ZigClangVarDecl *self) {
+ auto casted = reinterpret_cast<const clang::VarDecl *>(self);
+ return bitcast(casted->getType());
+}
+
+const struct ZigClangExpr *ZigClangVarDecl_getInit(const struct ZigClangVarDecl *self) {
+ auto casted = reinterpret_cast<const clang::VarDecl *>(self);
+ return reinterpret_cast<const ZigClangExpr *>(casted->getInit());
+}
+
+enum ZigClangVarDecl_TLSKind ZigClangVarDecl_getTLSKind(const ZigClangVarDecl *self) {
+ auto casted = reinterpret_cast<const clang::VarDecl *>(self);
+ return (ZigClangVarDecl_TLSKind)casted->getTLSKind();
+}
+
enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBuiltinType *self) {
auto casted = reinterpret_cast<const clang::BuiltinType *>(self);
return (ZigClangBuiltinTypeKind)casted->getKind();
@@ -1862,6 +1888,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<const clang::DeclStmt *>(self);
+ return bitcast(casted->decl_begin());
+}
+
+ZigClangDeclStmt_const_decl_iterator ZigClangDeclStmt_decl_end(const struct ZigClangDeclStmt *self) {
+ auto casted = reinterpret_cast<const clang::DeclStmt *>(self);
+ return bitcast(casted->decl_end());
+}
+
unsigned ZigClangAPFloat_convertToHexString(const ZigClangAPFloat *self, char *DST,
unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM)
{
@@ -1888,3 +1924,58 @@ const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName(
const clang::StringLiteral *result = casted->getFunctionName();
return reinterpret_cast<const struct ZigClangStringLiteral *>(result);
}
+
+ZigClangSourceLocation ZigClangImplicitCastExpr_getBeginLoc(const struct ZigClangImplicitCastExpr *self) {
+ auto casted = reinterpret_cast<const clang::ImplicitCastExpr *>(self);
+ return bitcast(casted->getBeginLoc());
+}
+
+enum ZigClangCK ZigClangImplicitCastExpr_getCastKind(const struct ZigClangImplicitCastExpr *self) {
+ auto casted = reinterpret_cast<const clang::ImplicitCastExpr *>(self);
+ return (ZigClangCK)casted->getCastKind();
+}
+
+const struct ZigClangExpr *ZigClangImplicitCastExpr_getSubExpr(const struct ZigClangImplicitCastExpr *self) {
+ auto casted = reinterpret_cast<const clang::ImplicitCastExpr *>(self);
+ return reinterpret_cast<const struct ZigClangExpr *>(casted->getSubExpr());
+}
+
+struct ZigClangQualType ZigClangArrayType_getElementType(const struct ZigClangArrayType *self) {
+ auto casted = reinterpret_cast<const clang::ArrayType *>(self);
+ return bitcast(casted->getElementType());
+}
+
+const struct ZigClangValueDecl *ZigClangDeclRefExpr_getDecl(const struct ZigClangDeclRefExpr *self) {
+ auto casted = reinterpret_cast<const clang::DeclRefExpr *>(self);
+ return reinterpret_cast<const struct ZigClangValueDecl *>(casted->getDecl());
+}
+
+struct ZigClangQualType ZigClangParenType_getInnerType(const struct ZigClangParenType *self) {
+ auto casted = reinterpret_cast<const clang::ParenType *>(self);
+ return bitcast(casted->getInnerType());
+}
+
+struct ZigClangQualType ZigClangAttributedType_getEquivalentType(const struct ZigClangAttributedType *self) {
+ auto casted = reinterpret_cast<const clang::AttributedType *>(self);
+ return bitcast(casted->getEquivalentType());
+}
+
+struct ZigClangQualType ZigClangElaboratedType_getNamedType(const struct ZigClangElaboratedType *self) {
+ auto casted = reinterpret_cast<const clang::ElaboratedType *>(self);
+ return bitcast(casted->getNamedType());
+}
+
+struct ZigClangSourceLocation ZigClangCStyleCastExpr_getBeginLoc(const struct ZigClangCStyleCastExpr *self) {
+ auto casted = reinterpret_cast<const clang::CStyleCastExpr *>(self);
+ return bitcast(casted->getBeginLoc());
+}
+
+const struct ZigClangExpr *ZigClangCStyleCastExpr_getSubExpr(const struct ZigClangCStyleCastExpr *self) {
+ auto casted = reinterpret_cast<const clang::CStyleCastExpr *>(self);
+ return reinterpret_cast<const struct ZigClangExpr *>(casted->getSubExpr());
+}
+
+struct ZigClangQualType ZigClangCStyleCastExpr_getType(const struct ZigClangCStyleCastExpr *self) {
+ auto casted = reinterpret_cast<const clang::CStyleCastExpr *>(self);
+ return bitcast(casted->getType());
+}
diff --git a/src/zig_clang.h b/src/zig_clang.h
index 1bdf34fc2f..bfaa5867a4 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,
@@ -732,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 *,
@@ -754,7 +761,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);
@@ -789,6 +796,10 @@ 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);
ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const struct ZigClangTypedefType *);
@@ -796,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);
@@ -846,6 +858,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);
@@ -855,4 +870,23 @@ 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 *);
+
+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 *);
+
+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