| ... | ... | @@ -229,7 +229,7 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void { |
| 229 | 229 | try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for structs", .{}); |
| 230 | 230 | }, |
| 231 | 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 | 234 | else => { |
| 235 | 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 | 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 | 358 | const ResultUsed = enum { |
| 306 | 359 | used, |
| 307 | 360 | unused, |
| ... | ... | @@ -1225,6 +1278,61 @@ fn transCreateNodeReturnExpr(c: *Context) !*ast.Node { |
| 1225 | 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 | 1336 | const RestorePoint = struct { |
| 1229 | 1337 | c: *Context, |
| 1230 | 1338 | token_index: ast.TokenIndex, |
| ... | ... | @@ -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 | 1436 | const FnDeclContext = struct { |
| 1319 | 1437 | fn_name: []const u8, |
| 1320 | 1438 | has_body: bool, |