| ... | @@ -229,7 +229,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void { | ... | @@ -229,7 +229,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void { |
| 229 | try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for structs", .{}); | 229 | try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for structs", .{}); |
| 230 | }, | 230 | }, |
| 231 | .Var => { | 231 | .Var => { |
| 232 | try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for variables", .{}); | 232 | return visitVarDecl(c, @ptrCast(*const ZigClangVarDecl, decl)); |
| 233 | }, | 233 | }, |
| 234 | else => { | 234 | else => { |
| 235 | const decl_name = try c.str(ZigClangDecl_getDeclKindName(decl)); | 235 | const decl_name = try c.str(ZigClangDecl_getDeclKindName(decl)); |
| ... | @@ -302,6 +302,59 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { | ... | @@ -302,6 +302,59 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 302 | return addTopLevelDecl(c, fn_name, &proto_node.base); | 302 | return addTopLevelDecl(c, fn_name, &proto_node.base); |
| 303 | } | 303 | } |
| 304 | | 304 | |
| | 305 | fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void { |
| | 306 | if (try c.decl_table.put(@ptrToInt(var_decl), {})) |_| return; // Avoid processing this decl twice |
| | 307 | const rp = makeRestorePoint(c); |
| | 308 | var scope = &c.global_scope.base; |
| | 309 | const var_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, var_decl))); |
| | 310 | const var_decl_loc = ZigClangVarDecl_getLocation(var_decl); |
| | 311 | |
| | 312 | switch (ZigClangVarDecl_getTLSKind(var_decl)) { |
| | 313 | .None => {}, |
| | 314 | .Static => return failDecl(c, var_decl_loc, var_name, "static thread local storage not supported", .{}), |
| | 315 | .Dynamic => return failDecl(c, var_decl_loc, var_name, "dynamic thread local storag not supported", .{}), |
| | 316 | } |
| | 317 | |
| | 318 | const qual_type = ZigClangVarDecl_getType(var_decl); |
| | 319 | const is_extern = ZigClangVarDecl_hasExternalStorage(var_decl); |
| | 320 | const is_static = ZigClangVarDecl_isFileVarDecl(var_decl); |
| | 321 | const is_const = ZigClangQualType_isConstQualified(qual_type); |
| | 322 | |
| | 323 | var var_node = try transCreateNodeVarDecl(c, true, is_extern, is_const, var_name); |
| | 324 | |
| | 325 | const type_node = transQualType(rp, qual_type, var_decl_loc) catch |err| switch (err) { |
| | 326 | error.UnsupportedType => { |
| | 327 | return failDecl(c, var_decl_loc, var_name, "unable to resolve variable type", .{}); |
| | 328 | }, |
| | 329 | error.OutOfMemory => |e| return e, |
| | 330 | }; |
| | 331 | |
| | 332 | if (is_static and !is_extern) { |
| | 333 | const eq_tok = try appendToken(c, .Equal, "="); |
| | 334 | const init_node = if (ZigClangVarDecl_hasInit(var_decl)) blk: { |
| | 335 | const ap_value = ZigClangVarDecl_evaluateValue(var_decl) orelse |
| | 336 | return failDecl(c, var_decl_loc, var_name, "unable to evaluate initializer", .{}); |
| | 337 | break :blk transApValue(rp, ap_value, qual_type, var_decl_loc) catch |err| switch (err) { |
| | 338 | error.UnsupportedTranslation, |
| | 339 | error.UnsupportedType, => { |
| | 340 | return failDecl(c, var_decl_loc, var_name, "unable to evaluate initializer", .{}); |
| | 341 | }, |
| | 342 | error.OutOfMemory => |e| return e, |
| | 343 | }; |
| | 344 | } else |
| | 345 | try transCreateNodeUndefinedLiteral(c); |
| | 346 | var_node.eq_token = eq_tok; |
| | 347 | var_node.init_node = init_node; |
| | 348 | } |
| | 349 | |
| | 350 | if (!is_extern) { |
| | 351 | return failDecl(c, var_decl_loc, var_name, "non-extern, non-static variable not supported", .{}); |
| | 352 | } |
| | 353 | |
| | 354 | var_node.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); |
| | 355 | return addTopLevelDecl(c, var_name, &var_node.base); |
| | 356 | } |
| | 357 | |
| 305 | const ResultUsed = enum { | 358 | const ResultUsed = enum { |
| 306 | used, | 359 | used, |
| 307 | unused, | 360 | unused, |
| ... | @@ -1225,6 +1278,61 @@ fn transCreateNodeReturnExpr(c: *Context) !*ast.Node { | ... | @@ -1225,6 +1278,61 @@ fn transCreateNodeReturnExpr(c: *Context) !*ast.Node { |
| 1225 | return &node.base; | 1278 | return &node.base; |
| 1226 | } | 1279 | } |
| 1227 | | 1280 | |
| | 1281 | fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node { |
| | 1282 | const token = try appendToken(c, .Keyword_undefined, "undefined"); |
| | 1283 | const node = try c.a().create(ast.Node.UndefinedLiteral); |
| | 1284 | node.* = ast.Node.UndefinedLiteral{ |
| | 1285 | .base = ast.Node{ .id = .UndefinedLiteral }, |
| | 1286 | .token = token, |
| | 1287 | }; |
| | 1288 | return &node.base; |
| | 1289 | } |
| | 1290 | |
| | 1291 | fn transCreateNodeVarDecl( |
| | 1292 | c: *Context, |
| | 1293 | is_pub: bool, |
| | 1294 | is_extern: bool, |
| | 1295 | is_const: bool, |
| | 1296 | var_name: []const u8, |
| | 1297 | ) !*ast.Node.VarDecl { |
| | 1298 | const visb_tok = if (is_pub) |
| | 1299 | try appendToken(c, .Keyword_pub, "pub") |
| | 1300 | else |
| | 1301 | null; |
| | 1302 | |
| | 1303 | const extern_tok = if (is_extern) |
| | 1304 | try appendToken(c, .Keyword_extern, "extern") |
| | 1305 | else |
| | 1306 | null; |
| | 1307 | |
| | 1308 | const mut_tok = if (is_const) |
| | 1309 | try appendToken(c, .Keyword_const, "const") |
| | 1310 | else |
| | 1311 | try appendToken(c, .Keyword_var, "var"); |
| | 1312 | |
| | 1313 | const name_tok = try appendToken(c, .Identifier, var_name); |
| | 1314 | |
| | 1315 | const node = try c.a().create(ast.Node.VarDecl); |
| | 1316 | node.* = ast.Node.VarDecl{ |
| | 1317 | .base = ast.Node{ .id = .VarDecl }, |
| | 1318 | .doc_comments = null, |
| | 1319 | .visib_token = visb_tok, |
| | 1320 | .thread_local_token = null, |
| | 1321 | .name_token = name_tok, |
| | 1322 | .eq_token = undefined, // set by caller |
| | 1323 | .mut_token = mut_tok, |
| | 1324 | .comptime_token = null, |
| | 1325 | .extern_export_token = extern_tok, |
| | 1326 | .lib_name = null, |
| | 1327 | .type_node = null, |
| | 1328 | .align_node = null, |
| | 1329 | .section_node = null, |
| | 1330 | .init_node = null, |
| | 1331 | .semicolon_token = undefined, // set by caller |
| | 1332 | }; |
| | 1333 | return node; |
| | 1334 | } |
| | 1335 | |
| 1228 | const RestorePoint = struct { | 1336 | const RestorePoint = struct { |
| 1229 | c: *Context, | 1337 | c: *Context, |
| 1230 | token_index: ast.TokenIndex, | 1338 | token_index: ast.TokenIndex, |
| ... | @@ -1315,6 +1423,16 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour | ... | @@ -1315,6 +1423,16 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 1315 | } | 1423 | } |
| 1316 | } | 1424 | } |
| 1317 | | 1425 | |
| | 1426 | fn transApValue(rp: RestorePoint, ap_value: *const ZigClangAPValue, qual_type: ZigClangQualType, source_loc: ZigClangSourceLocation) TransError!*ast.Node { |
| | 1427 | return revertAndWarn( |
| | 1428 | rp, |
| | 1429 | error.UnsupportedTranslation, |
| | 1430 | source_loc, |
| | 1431 | "TODO implement translation of ap value", |
| | 1432 | .{}, |
| | 1433 | ); |
| | 1434 | } |
| | 1435 | |
| 1318 | const FnDeclContext = struct { | 1436 | const FnDeclContext = struct { |
| 1319 | fn_name: []const u8, | 1437 | fn_name: []const u8, |
| 1320 | has_body: bool, | 1438 | has_body: bool, |