| author | |
| committer | |
| log | 95a37373e9f576854956c2909cc128b5b6388ec6 |
| tree | 647f62398f1afbc0546d223b05203e6c69372ba2 |
| parent | 3c43eeceab70f78939401b68811f152a7f29b191 |
| parent | bf4bfe54ac13512d7553a7be83ae19e908e9c294 |
| signature |
Add opaque syntax that allows declarations27 files changed, 371 insertions(+), 211 deletions(-)
doc/docgen.zig+1| ... | ... | @@ -808,6 +808,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: anytype, source_token: |
| 808 | 808 | .Keyword_noalias, |
| 809 | 809 | .Keyword_noinline, |
| 810 | 810 | .Keyword_nosuspend, |
| 811 | .Keyword_opaque, | |
| 811 | 812 | .Keyword_or, |
| 812 | 813 | .Keyword_orelse, |
| 813 | 814 | .Keyword_packed, |
doc/langref.html.in+11-9| ... | ... | @@ -1988,7 +1988,7 @@ test "null terminated array" { |
| 1988 | 1988 | <li>Supports slice syntax: {#syntax#}ptr[start..end]{#endsyntax#}</li> |
| 1989 | 1989 | <li>Supports pointer arithmetic: {#syntax#}ptr + x{#endsyntax#}, {#syntax#}ptr - x{#endsyntax#}</li> |
| 1990 | 1990 | <li>{#syntax#}T{#endsyntax#} must have a known size, which means that it cannot be |
| 1991 | {#syntax#}c_void{#endsyntax#} or any other {#link|opaque type|Opaque Types#}.</li> | |
| 1991 | {#syntax#}c_void{#endsyntax#} or any other {#link|opaque type|opaque#}.</li> | |
| 1992 | 1992 | </ul> |
| 1993 | 1993 | </li> |
| 1994 | 1994 | </ul> |
| ... | ... | @@ -5545,7 +5545,7 @@ test "turn HashMap into a set with void" { |
| 5545 | 5545 | </p> |
| 5546 | 5546 | <p> |
| 5547 | 5547 | {#syntax#}void{#endsyntax#} is distinct from {#syntax#}c_void{#endsyntax#}, which is defined like this: |
| 5548 | {#syntax#}pub const c_void = @Type(.Opaque);{#endsyntax#}. | |
| 5548 | {#syntax#}pub const c_void = opaque {};{#endsyntax#}. | |
| 5549 | 5549 | {#syntax#}void{#endsyntax#} has a known size of 0 bytes, and {#syntax#}c_void{#endsyntax#} has an unknown, but non-zero, size. |
| 5550 | 5550 | </p> |
| 5551 | 5551 | <p> |
| ... | ... | @@ -8471,7 +8471,7 @@ test "integer truncation" { |
| 8471 | 8471 | <li>{#link|Error Set Type#}</li> |
| 8472 | 8472 | <li>{#link|Error Union Type#}</li> |
| 8473 | 8473 | <li>{#link|Vectors#}</li> |
| 8474 | <li>{#link|Opaque Types#}</li> | |
| 8474 | <li>{#link|opaque#}</li> | |
| 8475 | 8475 | <li>{#link|@Frame#}</li> |
| 8476 | 8476 | <li>{#syntax#}anyframe{#endsyntax#}</li> |
| 8477 | 8477 | <li>{#link|struct#}</li> |
| ... | ... | @@ -8547,17 +8547,18 @@ fn foo(comptime T: type, ptr: *T) T { |
| 8547 | 8547 | {#header_close#} |
| 8548 | 8548 | {#header_close#} |
| 8549 | 8549 | |
| 8550 | {#header_open|Opaque Types#} | |
| 8550 | {#header_open|opaque#} | |
| 8551 | 8551 | <p> |
| 8552 | {#syntax#}@Type(.Opaque){#endsyntax#} creates a new type with an unknown (but non-zero) size and alignment. | |
| 8552 | {#syntax#}opaque {}{#endsyntax#} declares a new type with an unknown (but non-zero) size and alignment. | |
| 8553 | It can have declarations like structs, unions, or enums. | |
| 8553 | 8554 | </p> |
| 8554 | 8555 | <p> |
| 8555 | 8556 | This is typically used for type safety when interacting with C code that does not expose struct details. |
| 8556 | 8557 | Example: |
| 8557 | 8558 | </p> |
| 8558 | 8559 | {#code_begin|test_err|expected type '*Derp', found '*Wat'#} |
| 8559 | const Derp = @Type(.Opaque); | |
| 8560 | const Wat = @Type(.Opaque); | |
| 8560 | const Derp = opaque {}; | |
| 8561 | const Wat = opaque {}; | |
| 8561 | 8562 | |
| 8562 | 8563 | extern fn bar(d: *Derp) void; |
| 8563 | 8564 | fn foo(w: *Wat) callconv(.C) void { |
| ... | ... | @@ -11193,7 +11194,7 @@ PtrTypeStart |
| 11193 | 11194 | ContainerDeclAuto &lt;- ContainerDeclType LBRACE ContainerMembers RBRACE |
| 11194 | 11195 | |
| 11195 | 11196 | ContainerDeclType |
| 11196 | &lt;- (KEYWORD_struct / KEYWORD_enum) (LPAREN Expr RPAREN)? | |
| 11197 | &lt;- (KEYWORD_struct / KEYWORD_enum / KEYWORD_opaque) (LPAREN Expr RPAREN)? | |
| 11197 | 11198 | / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)? |
| 11198 | 11199 | |
| 11199 | 11200 | # Alignment |
| ... | ... | @@ -11340,6 +11341,7 @@ KEYWORD_inline &lt;- 'inline' end_of_word |
| 11340 | 11341 | KEYWORD_noalias &lt;- 'noalias' end_of_word |
| 11341 | 11342 | KEYWORD_nosuspend &lt;- 'nosuspend' end_of_word |
| 11342 | 11343 | KEYWORD_null &lt;- 'null' end_of_word |
| 11344 | KEYWORD_opaque &lt;- 'opaque' end_of_word | |
| 11343 | 11345 | KEYWORD_or &lt;- 'or' end_of_word |
| 11344 | 11346 | KEYWORD_orelse &lt;- 'orelse' end_of_word |
| 11345 | 11347 | KEYWORD_packed &lt;- 'packed' end_of_word |
| ... | ... | @@ -11368,7 +11370,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_and / KEYWORD_anyframe / KEYWORD_anytype |
| 11368 | 11370 | / KEYWORD_defer / KEYWORD_else / KEYWORD_enum / KEYWORD_errdefer |
| 11369 | 11371 | / KEYWORD_error / KEYWORD_export / KEYWORD_extern / KEYWORD_false |
| 11370 | 11372 | / KEYWORD_fn / KEYWORD_for / KEYWORD_if / KEYWORD_inline |
| 11371 | / KEYWORD_noalias / KEYWORD_null / KEYWORD_or | |
| 11373 | / KEYWORD_noalias / KEYWORD_null / KEYWORD_opaque / KEYWORD_or | |
| 11372 | 11374 | / KEYWORD_orelse / KEYWORD_packed / KEYWORD_pub |
| 11373 | 11375 | / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection |
| 11374 | 11376 | / KEYWORD_struct / KEYWORD_suspend |
lib/std/builtin.zig+7-1| ... | ... | @@ -198,7 +198,7 @@ pub const TypeInfo = union(enum) { |
| 198 | 198 | Union: Union, |
| 199 | 199 | Fn: Fn, |
| 200 | 200 | BoundFn: Fn, |
| 201 | Opaque: void, | |
| 201 | Opaque: Opaque, | |
| 202 | 202 | Frame: Frame, |
| 203 | 203 | AnyFrame: AnyFrame, |
| 204 | 204 | Vector: Vector, |
| ... | ... | @@ -359,6 +359,12 @@ pub const TypeInfo = union(enum) { |
| 359 | 359 | args: []const FnArg, |
| 360 | 360 | }; |
| 361 | 361 | |
| 362 | /// This data structure is used by the Zig language code generation and | |
| 363 | /// therefore must be kept in sync with the compiler implementation. | |
| 364 | pub const Opaque = struct { | |
| 365 | decls: []const Declaration, | |
| 366 | }; | |
| 367 | ||
| 362 | 368 | /// This data structure is used by the Zig language code generation and |
| 363 | 369 | /// therefore must be kept in sync with the compiler implementation. |
| 364 | 370 | pub const Frame = struct { |
lib/std/c.zig+2-2| ... | ... | @@ -329,8 +329,8 @@ pub extern "c" fn pthread_cond_signal(cond: *pthread_cond_t) c_int; |
| 329 | 329 | pub extern "c" fn pthread_cond_broadcast(cond: *pthread_cond_t) c_int; |
| 330 | 330 | pub extern "c" fn pthread_cond_destroy(cond: *pthread_cond_t) c_int; |
| 331 | 331 | |
| 332 | pub const pthread_t = *@Type(.Opaque); | |
| 333 | pub const FILE = @Type(.Opaque); | |
| 332 | pub const pthread_t = *opaque {}; | |
| 333 | pub const FILE = opaque {}; | |
| 334 | 334 | |
| 335 | 335 | pub extern "c" fn dlopen(path: [*:0]const u8, mode: c_int) ?*c_void; |
| 336 | 336 | pub extern "c" fn dlclose(handle: *c_void) c_int; |
lib/std/os/linux/bpf/kern.zig+25-25| ... | ... | @@ -12,28 +12,28 @@ const in_bpf_program = switch (std.builtin.arch) { |
| 12 | 12 | |
| 13 | 13 | pub const helpers = if (in_bpf_program) @import("helpers.zig") else struct {}; |
| 14 | 14 | |
| 15 | pub const BpfSock = @Type(.Opaque); | |
| 16 | pub const BpfSockAddr = @Type(.Opaque); | |
| 17 | pub const FibLookup = @Type(.Opaque); | |
| 18 | pub const MapDef = @Type(.Opaque); | |
| 19 | pub const PerfEventData = @Type(.Opaque); | |
| 20 | pub const PerfEventValue = @Type(.Opaque); | |
| 21 | pub const PidNsInfo = @Type(.Opaque); | |
| 22 | pub const SeqFile = @Type(.Opaque); | |
| 23 | pub const SkBuff = @Type(.Opaque); | |
| 24 | pub const SkMsgMd = @Type(.Opaque); | |
| 25 | pub const SkReusePortMd = @Type(.Opaque); | |
| 26 | pub const Sock = @Type(.Opaque); | |
| 27 | pub const SockAddr = @Type(.Opaque); | |
| 28 | pub const SockOps = @Type(.Opaque); | |
| 29 | pub const SockTuple = @Type(.Opaque); | |
| 30 | pub const SpinLock = @Type(.Opaque); | |
| 31 | pub const SysCtl = @Type(.Opaque); | |
| 32 | pub const Tcp6Sock = @Type(.Opaque); | |
| 33 | pub const TcpRequestSock = @Type(.Opaque); | |
| 34 | pub const TcpSock = @Type(.Opaque); | |
| 35 | pub const TcpTimewaitSock = @Type(.Opaque); | |
| 36 | pub const TunnelKey = @Type(.Opaque); | |
| 37 | pub const Udp6Sock = @Type(.Opaque); | |
| 38 | pub const XdpMd = @Type(.Opaque); | |
| 39 | pub const XfrmState = @Type(.Opaque); | |
| 15 | pub const BpfSock = opaque {}; | |
| 16 | pub const BpfSockAddr = opaque {}; | |
| 17 | pub const FibLookup = opaque {}; | |
| 18 | pub const MapDef = opaque {}; | |
| 19 | pub const PerfEventData = opaque {}; | |
| 20 | pub const PerfEventValue = opaque {}; | |
| 21 | pub const PidNsInfo = opaque {}; | |
| 22 | pub const SeqFile = opaque {}; | |
| 23 | pub const SkBuff = opaque {}; | |
| 24 | pub const SkMsgMd = opaque {}; | |
| 25 | pub const SkReusePortMd = opaque {}; | |
| 26 | pub const Sock = opaque {}; | |
| 27 | pub const SockAddr = opaque {}; | |
| 28 | pub const SockOps = opaque {}; | |
| 29 | pub const SockTuple = opaque {}; | |
| 30 | pub const SpinLock = opaque {}; | |
| 31 | pub const SysCtl = opaque {}; | |
| 32 | pub const Tcp6Sock = opaque {}; | |
| 33 | pub const TcpRequestSock = opaque {}; | |
| 34 | pub const TcpSock = opaque {}; | |
| 35 | pub const TcpTimewaitSock = opaque {}; | |
| 36 | pub const TunnelKey = opaque {}; | |
| 37 | pub const Udp6Sock = opaque {}; | |
| 38 | pub const XdpMd = opaque {}; | |
| 39 | pub const XfrmState = opaque {}; |
lib/std/os/uefi.zig+3-3| ... | ... | @@ -17,7 +17,7 @@ pub var handle: Handle = undefined; |
| 17 | 17 | pub var system_table: *tables.SystemTable = undefined; |
| 18 | 18 | |
| 19 | 19 | /// A handle to an event structure. |
| 20 | pub const Event = *@Type(.Opaque); | |
| 20 | pub const Event = *opaque {}; | |
| 21 | 21 | |
| 22 | 22 | /// GUIDs must be align(8) |
| 23 | 23 | pub const Guid = extern struct { |
| ... | ... | @@ -51,7 +51,7 @@ pub const Guid = extern struct { |
| 51 | 51 | }; |
| 52 | 52 | |
| 53 | 53 | /// An EFI Handle represents a collection of related interfaces. |
| 54 | pub const Handle = *@Type(.Opaque); | |
| 54 | pub const Handle = *opaque {}; | |
| 55 | 55 | |
| 56 | 56 | /// This structure represents time information. |
| 57 | 57 | pub const Time = extern struct { |
| ... | ... | @@ -108,4 +108,4 @@ pub const TimeCapabilities = extern struct { |
| 108 | 108 | }; |
| 109 | 109 | |
| 110 | 110 | /// File Handle as specified in the EFI Shell Spec |
| 111 | pub const FileHandle = *@Type(.Opaque); | |
| 111 | pub const FileHandle = *opaque {}; |
lib/std/os/uefi/protocols/hii.zig+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | const uefi = @import("std").os.uefi; |
| 7 | 7 | const Guid = uefi.Guid; |
| 8 | 8 | |
| 9 | pub const HIIHandle = *@Type(.Opaque); | |
| 9 | pub const HIIHandle = *opaque {}; | |
| 10 | 10 | |
| 11 | 11 | /// The header found at the start of each package. |
| 12 | 12 | pub const HIIPackageHeader = packed struct { |
lib/std/os/windows/bits.zig+15-15| ... | ... | @@ -32,16 +32,16 @@ pub const UCHAR = u8; |
| 32 | 32 | pub const FLOAT = f32; |
| 33 | 33 | pub const HANDLE = *c_void; |
| 34 | 34 | pub const HCRYPTPROV = ULONG_PTR; |
| 35 | pub const HBRUSH = *@Type(.Opaque); | |
| 36 | pub const HCURSOR = *@Type(.Opaque); | |
| 37 | pub const HICON = *@Type(.Opaque); | |
| 38 | pub const HINSTANCE = *@Type(.Opaque); | |
| 39 | pub const HMENU = *@Type(.Opaque); | |
| 40 | pub const HMODULE = *@Type(.Opaque); | |
| 41 | pub const HWND = *@Type(.Opaque); | |
| 42 | pub const HDC = *@Type(.Opaque); | |
| 43 | pub const HGLRC = *@Type(.Opaque); | |
| 44 | pub const FARPROC = *@Type(.Opaque); | |
| 35 | pub const HBRUSH = *opaque {}; | |
| 36 | pub const HCURSOR = *opaque {}; | |
| 37 | pub const HICON = *opaque {}; | |
| 38 | pub const HINSTANCE = *opaque {}; | |
| 39 | pub const HMENU = *opaque {}; | |
| 40 | pub const HMODULE = *opaque {}; | |
| 41 | pub const HWND = *opaque {}; | |
| 42 | pub const HDC = *opaque {}; | |
| 43 | pub const HGLRC = *opaque {}; | |
| 44 | pub const FARPROC = *opaque {}; | |
| 45 | 45 | pub const INT = c_int; |
| 46 | 46 | pub const LPBYTE = *BYTE; |
| 47 | 47 | pub const LPCH = *CHAR; |
| ... | ... | @@ -81,7 +81,7 @@ pub const WPARAM = usize; |
| 81 | 81 | pub const LPARAM = ?*c_void; |
| 82 | 82 | pub const LRESULT = ?*c_void; |
| 83 | 83 | |
| 84 | pub const va_list = *@Type(.Opaque); | |
| 84 | pub const va_list = *opaque {}; | |
| 85 | 85 | |
| 86 | 86 | pub const TRUE = 1; |
| 87 | 87 | pub const FALSE = 0; |
| ... | ... | @@ -1175,10 +1175,10 @@ pub const UNICODE_STRING = extern struct { |
| 1175 | 1175 | Buffer: [*]WCHAR, |
| 1176 | 1176 | }; |
| 1177 | 1177 | |
| 1178 | const ACTIVATION_CONTEXT_DATA = @Type(.Opaque); | |
| 1179 | const ASSEMBLY_STORAGE_MAP = @Type(.Opaque); | |
| 1180 | const FLS_CALLBACK_INFO = @Type(.Opaque); | |
| 1181 | const RTL_BITMAP = @Type(.Opaque); | |
| 1178 | const ACTIVATION_CONTEXT_DATA = opaque {}; | |
| 1179 | const ASSEMBLY_STORAGE_MAP = opaque {}; | |
| 1180 | const FLS_CALLBACK_INFO = opaque {}; | |
| 1181 | const RTL_BITMAP = opaque {}; | |
| 1182 | 1182 | pub const PRTL_BITMAP = *RTL_BITMAP; |
| 1183 | 1183 | const KAFFINITY = usize; |
| 1184 | 1184 |
lib/std/os/windows/ws2_32.zig+1-1| ... | ... | @@ -5,7 +5,7 @@ |
| 5 | 5 | // and substantial portions of the software. |
| 6 | 6 | usingnamespace @import("bits.zig"); |
| 7 | 7 | |
| 8 | pub const SOCKET = *@Type(.Opaque); | |
| 8 | pub const SOCKET = *opaque {}; | |
| 9 | 9 | pub const INVALID_SOCKET = @intToPtr(SOCKET, ~@as(usize, 0)); |
| 10 | 10 | pub const SOCKET_ERROR = -1; |
| 11 | 11 |
lib/std/zig/ast.zig+1-1| ... | ... | @@ -288,7 +288,7 @@ pub const Error = union(enum) { |
| 288 | 288 | pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found '{}'"); |
| 289 | 289 | pub const ExpectedFn = SingleTokenError("Expected function, found '{}'"); |
| 290 | 290 | pub const ExpectedReturnType = SingleTokenError("Expected 'var' or return type expression, found '{}'"); |
| 291 | pub const ExpectedAggregateKw = SingleTokenError("Expected '" ++ Token.Id.Keyword_struct.symbol() ++ "', '" ++ Token.Id.Keyword_union.symbol() ++ "', or '" ++ Token.Id.Keyword_enum.symbol() ++ "', found '{}'"); | |
| 291 | pub const ExpectedAggregateKw = SingleTokenError("Expected '" ++ Token.Id.Keyword_struct.symbol() ++ "', '" ++ Token.Id.Keyword_union.symbol() ++ "', '" ++ Token.Id.Keyword_enum.symbol() ++ "', or '" ++ Token.Id.Keyword_opaque.symbol() ++ "', found '{}'"); | |
| 292 | 292 | pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found '{}'"); |
| 293 | 293 | pub const ExpectedSemiOrLBrace = SingleTokenError("Expected ';' or '{{', found '{}'"); |
| 294 | 294 | pub const ExpectedSemiOrElse = SingleTokenError("Expected ';' or 'else', found '{}'"); |
lib/std/zig/parse.zig+2-1| ... | ... | @@ -2896,11 +2896,12 @@ const Parser = struct { |
| 2896 | 2896 | /// <- KEYWORD_struct |
| 2897 | 2897 | /// / KEYWORD_enum (LPAREN Expr RPAREN)? |
| 2898 | 2898 | /// / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)? |
| 2899 | /// / KEYWORD_opaque | |
| 2899 | 2900 | fn parseContainerDeclType(p: *Parser) !?ContainerDeclType { |
| 2900 | 2901 | const kind_token = p.nextToken(); |
| 2901 | 2902 | |
| 2902 | 2903 | const init_arg_expr = switch (p.token_ids[kind_token]) { |
| 2903 | .Keyword_struct => Node.ContainerDecl.InitArg{ .None = {} }, | |
| 2904 | .Keyword_struct, .Keyword_opaque => Node.ContainerDecl.InitArg{ .None = {} }, | |
| 2904 | 2905 | .Keyword_enum => blk: { |
| 2905 | 2906 | if (p.eatToken(.LParen) != null) { |
| 2906 | 2907 | const expr = try p.expectNode(parseExpr, .{ |
lib/std/zig/render.zig+13-1| ... | ... | @@ -1492,7 +1492,19 @@ fn renderExpression( |
| 1492 | 1492 | |
| 1493 | 1493 | // TODO remove after 0.7.0 release |
| 1494 | 1494 | if (mem.eql(u8, tree.tokenSlice(builtin_call.builtin_token), "@OpaqueType")) |
| 1495 | return ais.writer().writeAll("@Type(.Opaque)"); | |
| 1495 | return ais.writer().writeAll("opaque {}"); | |
| 1496 | ||
| 1497 | // TODO remove after 0.7.0 release | |
| 1498 | { | |
| 1499 | const params = builtin_call.paramsConst(); | |
| 1500 | if (mem.eql(u8, tree.tokenSlice(builtin_call.builtin_token), "@Type") and | |
| 1501 | params.len == 1) | |
| 1502 | { | |
| 1503 | if (params[0].castTag(.EnumLiteral)) |enum_literal| | |
| 1504 | if (mem.eql(u8, tree.tokenSlice(enum_literal.name), "Opaque")) | |
| 1505 | return ais.writer().writeAll("opaque {}"); | |
| 1506 | } | |
| 1507 | } | |
| 1496 | 1508 | |
| 1497 | 1509 | try renderToken(tree, ais, builtin_call.builtin_token, Space.None); // @name |
| 1498 | 1510 |
lib/std/zig/tokenizer.zig+3| ... | ... | @@ -47,6 +47,7 @@ pub const Token = struct { |
| 47 | 47 | .{ "noinline", .Keyword_noinline }, |
| 48 | 48 | .{ "nosuspend", .Keyword_nosuspend }, |
| 49 | 49 | .{ "null", .Keyword_null }, |
| 50 | .{ "opaque", .Keyword_opaque }, | |
| 50 | 51 | .{ "or", .Keyword_or }, |
| 51 | 52 | .{ "orelse", .Keyword_orelse }, |
| 52 | 53 | .{ "packed", .Keyword_packed }, |
| ... | ... | @@ -173,6 +174,7 @@ pub const Token = struct { |
| 173 | 174 | Keyword_noinline, |
| 174 | 175 | Keyword_nosuspend, |
| 175 | 176 | Keyword_null, |
| 177 | Keyword_opaque, | |
| 176 | 178 | Keyword_or, |
| 177 | 179 | Keyword_orelse, |
| 178 | 180 | Keyword_packed, |
| ... | ... | @@ -296,6 +298,7 @@ pub const Token = struct { |
| 296 | 298 | .Keyword_noinline => "noinline", |
| 297 | 299 | .Keyword_nosuspend => "nosuspend", |
| 298 | 300 | .Keyword_null => "null", |
| 301 | .Keyword_opaque => "opaque", | |
| 299 | 302 | .Keyword_or => "or", |
| 300 | 303 | .Keyword_orelse => "orelse", |
| 301 | 304 | .Keyword_packed => "packed", |
src/clang.zig+86-86| ... | ... | @@ -1,89 +1,89 @@ |
| 1 | 1 | const builtin = @import("builtin"); |
| 2 | 2 | |
| 3 | pub const struct_ZigClangConditionalOperator = @Type(.Opaque); | |
| 4 | pub const struct_ZigClangBinaryConditionalOperator = @Type(.Opaque); | |
| 5 | pub const struct_ZigClangAbstractConditionalOperator = @Type(.Opaque); | |
| 6 | pub const struct_ZigClangAPInt = @Type(.Opaque); | |
| 7 | pub const struct_ZigClangAPSInt = @Type(.Opaque); | |
| 8 | pub const struct_ZigClangAPFloat = @Type(.Opaque); | |
| 9 | pub const struct_ZigClangASTContext = @Type(.Opaque); | |
| 10 | pub const struct_ZigClangASTUnit = @Type(.Opaque); | |
| 11 | pub const struct_ZigClangArraySubscriptExpr = @Type(.Opaque); | |
| 12 | pub const struct_ZigClangArrayType = @Type(.Opaque); | |
| 13 | pub const struct_ZigClangAttributedType = @Type(.Opaque); | |
| 14 | pub const struct_ZigClangBinaryOperator = @Type(.Opaque); | |
| 15 | pub const struct_ZigClangBreakStmt = @Type(.Opaque); | |
| 16 | pub const struct_ZigClangBuiltinType = @Type(.Opaque); | |
| 17 | pub const struct_ZigClangCStyleCastExpr = @Type(.Opaque); | |
| 18 | pub const struct_ZigClangCallExpr = @Type(.Opaque); | |
| 19 | pub const struct_ZigClangCaseStmt = @Type(.Opaque); | |
| 20 | pub const struct_ZigClangCompoundAssignOperator = @Type(.Opaque); | |
| 21 | pub const struct_ZigClangCompoundStmt = @Type(.Opaque); | |
| 22 | pub const struct_ZigClangConstantArrayType = @Type(.Opaque); | |
| 23 | pub const struct_ZigClangContinueStmt = @Type(.Opaque); | |
| 24 | pub const struct_ZigClangDecayedType = @Type(.Opaque); | |
| 25 | pub const ZigClangDecl = @Type(.Opaque); | |
| 26 | pub const struct_ZigClangDeclRefExpr = @Type(.Opaque); | |
| 27 | pub const struct_ZigClangDeclStmt = @Type(.Opaque); | |
| 28 | pub const struct_ZigClangDefaultStmt = @Type(.Opaque); | |
| 29 | pub const struct_ZigClangDiagnosticOptions = @Type(.Opaque); | |
| 30 | pub const struct_ZigClangDiagnosticsEngine = @Type(.Opaque); | |
| 31 | pub const struct_ZigClangDoStmt = @Type(.Opaque); | |
| 32 | pub const struct_ZigClangElaboratedType = @Type(.Opaque); | |
| 33 | pub const struct_ZigClangEnumConstantDecl = @Type(.Opaque); | |
| 34 | pub const struct_ZigClangEnumDecl = @Type(.Opaque); | |
| 35 | pub const struct_ZigClangEnumType = @Type(.Opaque); | |
| 36 | pub const struct_ZigClangExpr = @Type(.Opaque); | |
| 37 | pub const struct_ZigClangFieldDecl = @Type(.Opaque); | |
| 38 | pub const struct_ZigClangFileID = @Type(.Opaque); | |
| 39 | pub const struct_ZigClangForStmt = @Type(.Opaque); | |
| 40 | pub const struct_ZigClangFullSourceLoc = @Type(.Opaque); | |
| 41 | pub const struct_ZigClangFunctionDecl = @Type(.Opaque); | |
| 42 | pub const struct_ZigClangFunctionProtoType = @Type(.Opaque); | |
| 43 | pub const struct_ZigClangIfStmt = @Type(.Opaque); | |
| 44 | pub const struct_ZigClangImplicitCastExpr = @Type(.Opaque); | |
| 45 | pub const struct_ZigClangIncompleteArrayType = @Type(.Opaque); | |
| 46 | pub const struct_ZigClangIntegerLiteral = @Type(.Opaque); | |
| 47 | pub const struct_ZigClangMacroDefinitionRecord = @Type(.Opaque); | |
| 48 | pub const struct_ZigClangMacroExpansion = @Type(.Opaque); | |
| 49 | pub const struct_ZigClangMacroQualifiedType = @Type(.Opaque); | |
| 50 | pub const struct_ZigClangMemberExpr = @Type(.Opaque); | |
| 51 | pub const struct_ZigClangNamedDecl = @Type(.Opaque); | |
| 52 | pub const struct_ZigClangNone = @Type(.Opaque); | |
| 53 | pub const struct_ZigClangOpaqueValueExpr = @Type(.Opaque); | |
| 54 | pub const struct_ZigClangPCHContainerOperations = @Type(.Opaque); | |
| 55 | pub const struct_ZigClangParenExpr = @Type(.Opaque); | |
| 56 | pub const struct_ZigClangParenType = @Type(.Opaque); | |
| 57 | pub const struct_ZigClangParmVarDecl = @Type(.Opaque); | |
| 58 | pub const struct_ZigClangPointerType = @Type(.Opaque); | |
| 59 | pub const struct_ZigClangPreprocessedEntity = @Type(.Opaque); | |
| 60 | pub const struct_ZigClangRecordDecl = @Type(.Opaque); | |
| 61 | pub const struct_ZigClangRecordType = @Type(.Opaque); | |
| 62 | pub const struct_ZigClangReturnStmt = @Type(.Opaque); | |
| 63 | pub const struct_ZigClangSkipFunctionBodiesScope = @Type(.Opaque); | |
| 64 | pub const struct_ZigClangSourceManager = @Type(.Opaque); | |
| 65 | pub const struct_ZigClangSourceRange = @Type(.Opaque); | |
| 66 | pub const ZigClangStmt = @Type(.Opaque); | |
| 67 | pub const struct_ZigClangStringLiteral = @Type(.Opaque); | |
| 68 | pub const struct_ZigClangStringRef = @Type(.Opaque); | |
| 69 | pub const struct_ZigClangSwitchStmt = @Type(.Opaque); | |
| 70 | pub const struct_ZigClangTagDecl = @Type(.Opaque); | |
| 71 | pub const struct_ZigClangType = @Type(.Opaque); | |
| 72 | pub const struct_ZigClangTypedefNameDecl = @Type(.Opaque); | |
| 73 | pub const struct_ZigClangTypedefType = @Type(.Opaque); | |
| 74 | pub const struct_ZigClangUnaryExprOrTypeTraitExpr = @Type(.Opaque); | |
| 75 | pub const struct_ZigClangUnaryOperator = @Type(.Opaque); | |
| 76 | pub const struct_ZigClangValueDecl = @Type(.Opaque); | |
| 77 | pub const struct_ZigClangVarDecl = @Type(.Opaque); | |
| 78 | pub const struct_ZigClangWhileStmt = @Type(.Opaque); | |
| 79 | pub const struct_ZigClangFunctionType = @Type(.Opaque); | |
| 80 | pub const struct_ZigClangPredefinedExpr = @Type(.Opaque); | |
| 81 | pub const struct_ZigClangInitListExpr = @Type(.Opaque); | |
| 82 | pub const ZigClangPreprocessingRecord = @Type(.Opaque); | |
| 83 | pub const ZigClangFloatingLiteral = @Type(.Opaque); | |
| 84 | pub const ZigClangConstantExpr = @Type(.Opaque); | |
| 85 | pub const ZigClangCharacterLiteral = @Type(.Opaque); | |
| 86 | pub const ZigClangStmtExpr = @Type(.Opaque); | |
| 3 | pub const struct_ZigClangConditionalOperator = opaque {}; | |
| 4 | pub const struct_ZigClangBinaryConditionalOperator = opaque {}; | |
| 5 | pub const struct_ZigClangAbstractConditionalOperator = opaque {}; | |
| 6 | pub const struct_ZigClangAPInt = opaque {}; | |
| 7 | pub const struct_ZigClangAPSInt = opaque {}; | |
| 8 | pub const struct_ZigClangAPFloat = opaque {}; | |
| 9 | pub const struct_ZigClangASTContext = opaque {}; | |
| 10 | pub const struct_ZigClangASTUnit = opaque {}; | |
| 11 | pub const struct_ZigClangArraySubscriptExpr = opaque {}; | |
| 12 | pub const struct_ZigClangArrayType = opaque {}; | |
| 13 | pub const struct_ZigClangAttributedType = opaque {}; | |
| 14 | pub const struct_ZigClangBinaryOperator = opaque {}; | |
| 15 | pub const struct_ZigClangBreakStmt = opaque {}; | |
| 16 | pub const struct_ZigClangBuiltinType = opaque {}; | |
| 17 | pub const struct_ZigClangCStyleCastExpr = opaque {}; | |
| 18 | pub const struct_ZigClangCallExpr = opaque {}; | |
| 19 | pub const struct_ZigClangCaseStmt = opaque {}; | |
| 20 | pub const struct_ZigClangCompoundAssignOperator = opaque {}; | |
| 21 | pub const struct_ZigClangCompoundStmt = opaque {}; | |
| 22 | pub const struct_ZigClangConstantArrayType = opaque {}; | |
| 23 | pub const struct_ZigClangContinueStmt = opaque {}; | |
| 24 | pub const struct_ZigClangDecayedType = opaque {}; | |
| 25 | pub const ZigClangDecl = opaque {}; | |
| 26 | pub const struct_ZigClangDeclRefExpr = opaque {}; | |
| 27 | pub const struct_ZigClangDeclStmt = opaque {}; | |
| 28 | pub const struct_ZigClangDefaultStmt = opaque {}; | |
| 29 | pub const struct_ZigClangDiagnosticOptions = opaque {}; | |
| 30 | pub const struct_ZigClangDiagnosticsEngine = opaque {}; | |
| 31 | pub const struct_ZigClangDoStmt = opaque {}; | |
| 32 | pub const struct_ZigClangElaboratedType = opaque {}; | |
| 33 | pub const struct_ZigClangEnumConstantDecl = opaque {}; | |
| 34 | pub const struct_ZigClangEnumDecl = opaque {}; | |
| 35 | pub const struct_ZigClangEnumType = opaque {}; | |
| 36 | pub const struct_ZigClangExpr = opaque {}; | |
| 37 | pub const struct_ZigClangFieldDecl = opaque {}; | |
| 38 | pub const struct_ZigClangFileID = opaque {}; | |
| 39 | pub const struct_ZigClangForStmt = opaque {}; | |
| 40 | pub const struct_ZigClangFullSourceLoc = opaque {}; | |
| 41 | pub const struct_ZigClangFunctionDecl = opaque {}; | |
| 42 | pub const struct_ZigClangFunctionProtoType = opaque {}; | |
| 43 | pub const struct_ZigClangIfStmt = opaque {}; | |
| 44 | pub const struct_ZigClangImplicitCastExpr = opaque {}; | |
| 45 | pub const struct_ZigClangIncompleteArrayType = opaque {}; | |
| 46 | pub const struct_ZigClangIntegerLiteral = opaque {}; | |
| 47 | pub const struct_ZigClangMacroDefinitionRecord = opaque {}; | |
| 48 | pub const struct_ZigClangMacroExpansion = opaque {}; | |
| 49 | pub const struct_ZigClangMacroQualifiedType = opaque {}; | |
| 50 | pub const struct_ZigClangMemberExpr = opaque {}; | |
| 51 | pub const struct_ZigClangNamedDecl = opaque {}; | |
| 52 | pub const struct_ZigClangNone = opaque {}; | |
| 53 | pub const struct_ZigClangOpaqueValueExpr = opaque {}; | |
| 54 | pub const struct_ZigClangPCHContainerOperations = opaque {}; | |
| 55 | pub const struct_ZigClangParenExpr = opaque {}; | |
| 56 | pub const struct_ZigClangParenType = opaque {}; | |
| 57 | pub const struct_ZigClangParmVarDecl = opaque {}; | |
| 58 | pub const struct_ZigClangPointerType = opaque {}; | |
| 59 | pub const struct_ZigClangPreprocessedEntity = opaque {}; | |
| 60 | pub const struct_ZigClangRecordDecl = opaque {}; | |
| 61 | pub const struct_ZigClangRecordType = opaque {}; | |
| 62 | pub const struct_ZigClangReturnStmt = opaque {}; | |
| 63 | pub const struct_ZigClangSkipFunctionBodiesScope = opaque {}; | |
| 64 | pub const struct_ZigClangSourceManager = opaque {}; | |
| 65 | pub const struct_ZigClangSourceRange = opaque {}; | |
| 66 | pub const ZigClangStmt = opaque {}; | |
| 67 | pub const struct_ZigClangStringLiteral = opaque {}; | |
| 68 | pub const struct_ZigClangStringRef = opaque {}; | |
| 69 | pub const struct_ZigClangSwitchStmt = opaque {}; | |
| 70 | pub const struct_ZigClangTagDecl = opaque {}; | |
| 71 | pub const struct_ZigClangType = opaque {}; | |
| 72 | pub const struct_ZigClangTypedefNameDecl = opaque {}; | |
| 73 | pub const struct_ZigClangTypedefType = opaque {}; | |
| 74 | pub const struct_ZigClangUnaryExprOrTypeTraitExpr = opaque {}; | |
| 75 | pub const struct_ZigClangUnaryOperator = opaque {}; | |
| 76 | pub const struct_ZigClangValueDecl = opaque {}; | |
| 77 | pub const struct_ZigClangVarDecl = opaque {}; | |
| 78 | pub const struct_ZigClangWhileStmt = opaque {}; | |
| 79 | pub const struct_ZigClangFunctionType = opaque {}; | |
| 80 | pub const struct_ZigClangPredefinedExpr = opaque {}; | |
| 81 | pub const struct_ZigClangInitListExpr = opaque {}; | |
| 82 | pub const ZigClangPreprocessingRecord = opaque {}; | |
| 83 | pub const ZigClangFloatingLiteral = opaque {}; | |
| 84 | pub const ZigClangConstantExpr = opaque {}; | |
| 85 | pub const ZigClangCharacterLiteral = opaque {}; | |
| 86 | pub const ZigClangStmtExpr = opaque {}; | |
| 87 | 87 | |
| 88 | 88 | pub const ZigClangBO = extern enum { |
| 89 | 89 | PtrMemD, |
| ... | ... | @@ -749,11 +749,11 @@ pub const ZigClangCharacterLiteral_CharacterKind = extern enum { |
| 749 | 749 | }; |
| 750 | 750 | |
| 751 | 751 | pub const ZigClangRecordDecl_field_iterator = extern struct { |
| 752 | opaque: *c_void, | |
| 752 | ptr: *c_void, | |
| 753 | 753 | }; |
| 754 | 754 | |
| 755 | 755 | pub const ZigClangEnumDecl_enumerator_iterator = extern struct { |
| 756 | opaque: *c_void, | |
| 756 | ptr: *c_void, | |
| 757 | 757 | }; |
| 758 | 758 | |
| 759 | 759 | pub const ZigClangPreprocessingRecord_iterator = extern struct { |
src/stage1/all_types.hpp+4| ... | ... | @@ -1053,6 +1053,7 @@ enum ContainerKind { |
| 1053 | 1053 | ContainerKindStruct, |
| 1054 | 1054 | ContainerKindEnum, |
| 1055 | 1055 | ContainerKindUnion, |
| 1056 | ContainerKindOpaque, | |
| 1056 | 1057 | }; |
| 1057 | 1058 | |
| 1058 | 1059 | enum ContainerLayout { |
| ... | ... | @@ -1570,7 +1571,10 @@ enum OnePossibleValue { |
| 1570 | 1571 | }; |
| 1571 | 1572 | |
| 1572 | 1573 | struct ZigTypeOpaque { |
| 1574 | AstNode *decl_node; | |
| 1573 | 1575 | Buf *bare_name; |
| 1576 | ||
| 1577 | ScopeDecls *decls_scope; | |
| 1574 | 1578 | }; |
| 1575 | 1579 | |
| 1576 | 1580 | struct ZigTypeFnFrame { |
src/stage1/analyze.cpp+52-10| ... | ... | @@ -86,14 +86,18 @@ ZigType *new_type_table_entry(ZigTypeId id) { |
| 86 | 86 | } |
| 87 | 87 | |
| 88 | 88 | static ScopeDecls **get_container_scope_ptr(ZigType *type_entry) { |
| 89 | if (type_entry->id == ZigTypeIdStruct) { | |
| 90 | return &type_entry->data.structure.decls_scope; | |
| 91 | } else if (type_entry->id == ZigTypeIdEnum) { | |
| 92 | return &type_entry->data.enumeration.decls_scope; | |
| 93 | } else if (type_entry->id == ZigTypeIdUnion) { | |
| 94 | return &type_entry->data.unionation.decls_scope; | |
| 89 | switch (type_entry->id) { | |
| 90 | case ZigTypeIdStruct: | |
| 91 | return &type_entry->data.structure.decls_scope; | |
| 92 | case ZigTypeIdEnum: | |
| 93 | return &type_entry->data.enumeration.decls_scope; | |
| 94 | case ZigTypeIdUnion: | |
| 95 | return &type_entry->data.unionation.decls_scope; | |
| 96 | case ZigTypeIdOpaque: | |
| 97 | return &type_entry->data.opaque.decls_scope; | |
| 98 | default: | |
| 99 | zig_unreachable(); | |
| 95 | 100 | } |
| 96 | zig_unreachable(); | |
| 97 | 101 | } |
| 98 | 102 | |
| 99 | 103 | static ScopeExpr *find_expr_scope(Scope *scope) { |
| ... | ... | @@ -912,13 +916,17 @@ ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const c |
| 912 | 916 | ZigType *import = scope ? get_scope_import(scope) : nullptr; |
| 913 | 917 | unsigned line = source_node ? (unsigned)(source_node->line + 1) : 0; |
| 914 | 918 | |
| 919 | // Note: duplicated in get_partial_container_type | |
| 915 | 920 | entry->llvm_type = LLVMInt8Type(); |
| 916 | 921 | entry->llvm_di_type = ZigLLVMCreateDebugForwardDeclType(g->dbuilder, |
| 917 | 922 | ZigLLVMTag_DW_structure_type(), full_name, |
| 918 | 923 | import ? ZigLLVMFileToScope(import->data.structure.root_struct->di_file) : nullptr, |
| 919 | 924 | import ? import->data.structure.root_struct->di_file : nullptr, |
| 920 | 925 | line); |
| 926 | entry->data.opaque.decl_node = source_node; | |
| 921 | 927 | entry->data.opaque.bare_name = bare_name; |
| 928 | entry->data.opaque.decls_scope = create_decls_scope( | |
| 929 | g, source_node, scope, entry, import, &entry->name); | |
| 922 | 930 | |
| 923 | 931 | // The actual size is unknown, but the value must not be 0 because that |
| 924 | 932 | // is how type_has_bits is determined. |
| ... | ... | @@ -1078,6 +1086,8 @@ static ZigTypeId container_to_type(ContainerKind kind) { |
| 1078 | 1086 | return ZigTypeIdEnum; |
| 1079 | 1087 | case ContainerKindUnion: |
| 1080 | 1088 | return ZigTypeIdUnion; |
| 1089 | case ContainerKindOpaque: | |
| 1090 | return ZigTypeIdOpaque; | |
| 1081 | 1091 | } |
| 1082 | 1092 | zig_unreachable(); |
| 1083 | 1093 | } |
| ... | ... | @@ -1119,6 +1129,22 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind |
| 1119 | 1129 | entry->data.unionation.decl_node = decl_node; |
| 1120 | 1130 | entry->data.unionation.layout = layout; |
| 1121 | 1131 | break; |
| 1132 | case ContainerKindOpaque: { | |
| 1133 | ZigType *import = scope ? get_scope_import(scope) : nullptr; | |
| 1134 | unsigned line = decl_node ? (unsigned)(decl_node->line + 1) : 0; | |
| 1135 | // Note: duplicated in get_opaque_type | |
| 1136 | entry->llvm_type = LLVMInt8Type(); | |
| 1137 | entry->llvm_di_type = ZigLLVMCreateDebugForwardDeclType(g->dbuilder, | |
| 1138 | ZigLLVMTag_DW_structure_type(), full_name, | |
| 1139 | import ? ZigLLVMFileToScope(import->data.structure.root_struct->di_file) : nullptr, | |
| 1140 | import ? import->data.structure.root_struct->di_file : nullptr, | |
| 1141 | line); | |
| 1142 | entry->data.opaque.decl_node = decl_node; | |
| 1143 | entry->abi_size = SIZE_MAX; | |
| 1144 | entry->size_in_bits = SIZE_MAX; | |
| 1145 | entry->abi_align = 1; | |
| 1146 | break; | |
| 1147 | } | |
| 1122 | 1148 | } |
| 1123 | 1149 | |
| 1124 | 1150 | buf_init_from_str(&entry->name, full_name); |
| ... | ... | @@ -3428,6 +3454,21 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { |
| 3428 | 3454 | return ErrorNone; |
| 3429 | 3455 | } |
| 3430 | 3456 | |
| 3457 | static Error resolve_opaque_type(CodeGen *g, ZigType *opaque_type) { | |
| 3458 | Error err = ErrorNone; | |
| 3459 | AstNode *container_node = opaque_type->data.opaque.decl_node; | |
| 3460 | if (container_node != nullptr) { | |
| 3461 | assert(container_node->type == NodeTypeContainerDecl); | |
| 3462 | AstNodeContainerDecl *container_decl = &container_node->data.container_decl; | |
| 3463 | for (size_t i = 0; i < container_decl->fields.length; i++) { | |
| 3464 | AstNode *field_node = container_decl->fields.items[i]; | |
| 3465 | add_node_error(g, field_node, buf_create_from_str("opaque types cannot have fields")); | |
| 3466 | err = ErrorSemanticAnalyzeFail; | |
| 3467 | } | |
| 3468 | } | |
| 3469 | return err; | |
| 3470 | } | |
| 3471 | ||
| 3431 | 3472 | void append_namespace_qualification(CodeGen *g, Buf *buf, ZigType *container_type) { |
| 3432 | 3473 | if (g->root_import == container_type || buf_len(&container_type->name) == 0) return; |
| 3433 | 3474 | buf_append_buf(buf, &container_type->name); |
| ... | ... | @@ -3893,6 +3934,8 @@ static Error resolve_decl_container(CodeGen *g, TldContainer *tld_container) { |
| 3893 | 3934 | return resolve_enum_zero_bits(g, tld_container->type_entry); |
| 3894 | 3935 | case ZigTypeIdUnion: |
| 3895 | 3936 | return resolve_union_type(g, tld_container->type_entry); |
| 3937 | case ZigTypeIdOpaque: | |
| 3938 | return resolve_opaque_type(g, tld_container->type_entry); | |
| 3896 | 3939 | default: |
| 3897 | 3940 | zig_unreachable(); |
| 3898 | 3941 | } |
| ... | ... | @@ -4459,6 +4502,7 @@ bool is_container(ZigType *type_entry) { |
| 4459 | 4502 | return type_entry->data.structure.special != StructSpecialSlice; |
| 4460 | 4503 | case ZigTypeIdEnum: |
| 4461 | 4504 | case ZigTypeIdUnion: |
| 4505 | case ZigTypeIdOpaque: | |
| 4462 | 4506 | return true; |
| 4463 | 4507 | case ZigTypeIdPointer: |
| 4464 | 4508 | case ZigTypeIdMetaType: |
| ... | ... | @@ -4478,7 +4522,6 @@ bool is_container(ZigType *type_entry) { |
| 4478 | 4522 | case ZigTypeIdErrorSet: |
| 4479 | 4523 | case ZigTypeIdFn: |
| 4480 | 4524 | case ZigTypeIdBoundFn: |
| 4481 | case ZigTypeIdOpaque: | |
| 4482 | 4525 | case ZigTypeIdVector: |
| 4483 | 4526 | case ZigTypeIdFnFrame: |
| 4484 | 4527 | case ZigTypeIdAnyFrame: |
| ... | ... | @@ -8165,6 +8208,7 @@ const char *container_string(ContainerKind kind) { |
| 8165 | 8208 | case ContainerKindEnum: return "enum"; |
| 8166 | 8209 | case ContainerKindStruct: return "struct"; |
| 8167 | 8210 | case ContainerKindUnion: return "union"; |
| 8211 | case ContainerKindOpaque: return "opaque"; | |
| 8168 | 8212 | } |
| 8169 | 8213 | zig_unreachable(); |
| 8170 | 8214 | } |
| ... | ... | @@ -8183,8 +8227,6 @@ Buf *type_bare_name(ZigType *type_entry) { |
| 8183 | 8227 | return &type_entry->name; |
| 8184 | 8228 | } else if (is_container(type_entry)) { |
| 8185 | 8229 | return get_container_scope(type_entry)->bare_name; |
| 8186 | } else if (type_entry->id == ZigTypeIdOpaque) { | |
| 8187 | return type_entry->data.opaque.bare_name; | |
| 8188 | 8230 | } else { |
| 8189 | 8231 | return &type_entry->name; |
| 8190 | 8232 | } |
src/stage1/ir.cpp+37-2| ... | ... | @@ -22386,6 +22386,8 @@ static IrInstGen *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 22386 | 22386 | prefix_name = "enum "; |
| 22387 | 22387 | } else if (bare_struct_type->id == ZigTypeIdUnion) { |
| 22388 | 22388 | prefix_name = "union "; |
| 22389 | } else if (bare_struct_type->id == ZigTypeIdOpaque) { | |
| 22390 | prefix_name = "opaque type "; | |
| 22389 | 22391 | } else { |
| 22390 | 22392 | prefix_name = ""; |
| 22391 | 22393 | } |
| ... | ... | @@ -22586,7 +22588,7 @@ static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name |
| 22586 | 22588 | } |
| 22587 | 22589 | } |
| 22588 | 22590 | |
| 22589 | if (bare_type->id == ZigTypeIdEnum) { | |
| 22591 | if (bare_type->id == ZigTypeIdEnum || bare_type->id == ZigTypeIdOpaque) { | |
| 22590 | 22592 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 22591 | 22593 | source_instr, container_ptr, container_ptr_src, container_type); |
| 22592 | 22594 | } |
| ... | ... | @@ -25182,7 +25184,6 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy |
| 25182 | 25184 | case ZigTypeIdEnumLiteral: |
| 25183 | 25185 | case ZigTypeIdUndefined: |
| 25184 | 25186 | case ZigTypeIdNull: |
| 25185 | case ZigTypeIdOpaque: | |
| 25186 | 25187 | result = ira->codegen->intern.for_void(); |
| 25187 | 25188 | break; |
| 25188 | 25189 | case ZigTypeIdInt: |
| ... | ... | @@ -25736,6 +25737,25 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy |
| 25736 | 25737 | if ((err = ir_make_type_info_value(ira, source_instr, fn_type, &result))) |
| 25737 | 25738 | return err; |
| 25738 | 25739 | |
| 25740 | break; | |
| 25741 | } | |
| 25742 | case ZigTypeIdOpaque: | |
| 25743 | { | |
| 25744 | result = ira->codegen->pass1_arena->create<ZigValue>(); | |
| 25745 | result->special = ConstValSpecialStatic; | |
| 25746 | result->type = ir_type_info_get_type(ira, "Opaque", nullptr); | |
| 25747 | ||
| 25748 | ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); | |
| 25749 | result->data.x_struct.fields = fields; | |
| 25750 | ||
| 25751 | // decls: []TypeInfo.Declaration | |
| 25752 | ensure_field_index(result->type, "decls", 0); | |
| 25753 | if ((err = ir_make_type_info_decls(ira, source_instr, fields[0], | |
| 25754 | type_entry->data.opaque.decls_scope, false))) | |
| 25755 | { | |
| 25756 | return err; | |
| 25757 | } | |
| 25758 | ||
| 25739 | 25759 | break; |
| 25740 | 25760 | } |
| 25741 | 25761 | case ZigTypeIdFnFrame: |
| ... | ... | @@ -26043,6 +26063,21 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI |
| 26043 | 26063 | return get_error_union_type(ira->codegen, err_set_type, payload_type); |
| 26044 | 26064 | } |
| 26045 | 26065 | case ZigTypeIdOpaque: { |
| 26066 | assert(payload->special == ConstValSpecialStatic); | |
| 26067 | assert(payload->type == ir_type_info_get_type(ira, "Opaque", nullptr)); | |
| 26068 | ||
| 26069 | ZigValue *decls_value = get_const_field(ira, source_instr->source_node, payload, "decls", 0); | |
| 26070 | if (decls_value == nullptr) | |
| 26071 | return ira->codegen->invalid_inst_gen->value->type; | |
| 26072 | assert(decls_value->special == ConstValSpecialStatic); | |
| 26073 | assert(is_slice(decls_value->type)); | |
| 26074 | ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index]; | |
| 26075 | size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint); | |
| 26076 | if (decls_len != 0) { | |
| 26077 | ir_add_error(ira, source_instr, buf_create_from_str("TypeInfo.Struct.decls must be empty for @Type")); | |
| 26078 | return ira->codegen->invalid_inst_gen->value->type; | |
| 26079 | } | |
| 26080 | ||
| 26046 | 26081 | Buf *bare_name = buf_alloc(); |
| 26047 | 26082 | Buf *full_name = get_anon_type_name(ira->codegen, |
| 26048 | 26083 | ira->old_irb.exec, "opaque", source_instr->scope, source_instr->source_node, bare_name); |
src/stage1/parser.cpp+9| ... | ... | @@ -2920,6 +2920,7 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) { |
| 2920 | 2920 | // <- KEYWORD_struct |
| 2921 | 2921 | // / KEYWORD_enum (LPAREN Expr RPAREN)? |
| 2922 | 2922 | // / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)? |
| 2923 | // / KEYWORD_opaque | |
| 2923 | 2924 | static AstNode *ast_parse_container_decl_type(ParseContext *pc) { |
| 2924 | 2925 | Token *first = eat_token_if(pc, TokenIdKeywordStruct); |
| 2925 | 2926 | if (first != nullptr) { |
| ... | ... | @@ -2929,6 +2930,14 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) { |
| 2929 | 2930 | return res; |
| 2930 | 2931 | } |
| 2931 | 2932 | |
| 2933 | first = eat_token_if(pc, TokenIdKeywordOpaque); | |
| 2934 | if (first != nullptr) { | |
| 2935 | AstNode *res = ast_create_node(pc, NodeTypeContainerDecl, first); | |
| 2936 | res->data.container_decl.init_arg_expr = nullptr; | |
| 2937 | res->data.container_decl.kind = ContainerKindOpaque; | |
| 2938 | return res; | |
| 2939 | } | |
| 2940 | ||
| 2932 | 2941 | first = eat_token_if(pc, TokenIdKeywordEnum); |
| 2933 | 2942 | if (first != nullptr) { |
| 2934 | 2943 | AstNode *init_arg_expr = nullptr; |
src/stage1/tokenizer.cpp+2| ... | ... | @@ -133,6 +133,7 @@ static const struct ZigKeyword zig_keywords[] = { |
| 133 | 133 | {"noinline", TokenIdKeywordNoInline}, |
| 134 | 134 | {"nosuspend", TokenIdKeywordNoSuspend}, |
| 135 | 135 | {"null", TokenIdKeywordNull}, |
| 136 | {"opaque", TokenIdKeywordOpaque}, | |
| 136 | 137 | {"or", TokenIdKeywordOr}, |
| 137 | 138 | {"orelse", TokenIdKeywordOrElse}, |
| 138 | 139 | {"packed", TokenIdKeywordPacked}, |
| ... | ... | @@ -1595,6 +1596,7 @@ const char * token_name(TokenId id) { |
| 1595 | 1596 | case TokenIdKeywordNoInline: return "noinline"; |
| 1596 | 1597 | case TokenIdKeywordNoSuspend: return "nosuspend"; |
| 1597 | 1598 | case TokenIdKeywordNull: return "null"; |
| 1599 | case TokenIdKeywordOpaque: return "opaque"; | |
| 1598 | 1600 | case TokenIdKeywordOr: return "or"; |
| 1599 | 1601 | case TokenIdKeywordOrElse: return "orelse"; |
| 1600 | 1602 | case TokenIdKeywordPacked: return "packed"; |
src/stage1/tokenizer.hpp+1| ... | ... | @@ -81,6 +81,7 @@ enum TokenId { |
| 81 | 81 | TokenIdKeywordNoAlias, |
| 82 | 82 | TokenIdKeywordNoSuspend, |
| 83 | 83 | TokenIdKeywordNull, |
| 84 | TokenIdKeywordOpaque, | |
| 84 | 85 | TokenIdKeywordOr, |
| 85 | 86 | TokenIdKeywordOrElse, |
| 86 | 87 | TokenIdKeywordPacked, |
src/translate_c.zig+20-12| ... | ... | @@ -930,9 +930,9 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 930 | 930 | const init_node = blk: { |
| 931 | 931 | const rp = makeRestorePoint(c); |
| 932 | 932 | const record_def = ZigClangRecordDecl_getDefinition(record_decl) orelse { |
| 933 | const opaque = try transCreateNodeOpaqueType(c); | |
| 933 | const opaque_type = try transCreateNodeOpaqueType(c); | |
| 934 | 934 | semicolon = try appendToken(c, .Semicolon, ";"); |
| 935 | break :blk opaque; | |
| 935 | break :blk opaque_type; | |
| 936 | 936 | }; |
| 937 | 937 | |
| 938 | 938 | const layout_tok = try if (ZigClangRecordDecl_getPackedAttribute(record_decl)) |
| ... | ... | @@ -954,17 +954,17 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 954 | 954 | const field_qt = ZigClangFieldDecl_getType(field_decl); |
| 955 | 955 | |
| 956 | 956 | if (ZigClangFieldDecl_isBitField(field_decl)) { |
| 957 | const opaque = try transCreateNodeOpaqueType(c); | |
| 957 | const opaque_type = try transCreateNodeOpaqueType(c); | |
| 958 | 958 | semicolon = try appendToken(c, .Semicolon, ";"); |
| 959 | 959 | try emitWarning(c, field_loc, "{} demoted to opaque type - has bitfield", .{container_kind_name}); |
| 960 | break :blk opaque; | |
| 960 | break :blk opaque_type; | |
| 961 | 961 | } |
| 962 | 962 | |
| 963 | 963 | if (ZigClangType_isIncompleteOrZeroLengthArrayType(qualTypeCanon(field_qt), c.clang_context)) { |
| 964 | const opaque = try transCreateNodeOpaqueType(c); | |
| 964 | const opaque_type = try transCreateNodeOpaqueType(c); | |
| 965 | 965 | semicolon = try appendToken(c, .Semicolon, ";"); |
| 966 | 966 | try emitWarning(c, field_loc, "{} demoted to opaque type - has variable length array", .{container_kind_name}); |
| 967 | break :blk opaque; | |
| 967 | break :blk opaque_type; | |
| 968 | 968 | } |
| 969 | 969 | |
| 970 | 970 | var is_anon = false; |
| ... | ... | @@ -979,10 +979,10 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?* |
| 979 | 979 | _ = try appendToken(c, .Colon, ":"); |
| 980 | 980 | const field_type = transQualType(rp, field_qt, field_loc) catch |err| switch (err) { |
| 981 | 981 | error.UnsupportedType => { |
| 982 | const opaque = try transCreateNodeOpaqueType(c); | |
| 982 | const opaque_type = try transCreateNodeOpaqueType(c); | |
| 983 | 983 | semicolon = try appendToken(c, .Semicolon, ";"); |
| 984 | 984 | try emitWarning(c, record_loc, "{} demoted to opaque type - unable to translate type of field {}", .{ container_kind_name, raw_name }); |
| 985 | break :blk opaque; | |
| 985 | break :blk opaque_type; | |
| 986 | 986 | }, |
| 987 | 987 | else => |e| return e, |
| 988 | 988 | }; |
| ... | ... | @@ -4438,10 +4438,18 @@ fn transCreateNodeFloat(c: *Context, int: anytype) !*ast.Node { |
| 4438 | 4438 | } |
| 4439 | 4439 | |
| 4440 | 4440 | fn transCreateNodeOpaqueType(c: *Context) !*ast.Node { |
| 4441 | const call_node = try c.createBuiltinCall("@Type", 1); | |
| 4442 | call_node.params()[0] = try transCreateNodeEnumLiteral(c, "Opaque"); | |
| 4443 | call_node.rparen_token = try appendToken(c, .RParen, ")"); | |
| 4444 | return &call_node.base; | |
| 4441 | const container_tok = try appendToken(c, .Keyword_opaque, "opaque"); | |
| 4442 | const lbrace_token = try appendToken(c, .LBrace, "{"); | |
| 4443 | const container_node = try ast.Node.ContainerDecl.alloc(c.arena, 0); | |
| 4444 | container_node.* = .{ | |
| 4445 | .kind_token = container_tok, | |
| 4446 | .layout_token = null, | |
| 4447 | .lbrace_token = lbrace_token, | |
| 4448 | .rbrace_token = try appendToken(c, .RBrace, "}"), | |
| 4449 | .fields_and_decls_len = 0, | |
| 4450 | .init_arg_expr = .None, | |
| 4451 | }; | |
| 4452 | return &container_node.base; | |
| 4445 | 4453 | } |
| 4446 | 4454 | |
| 4447 | 4455 | fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_alias: *ast.Node.FnProto) !*ast.Node { |
test/compile_errors.zig+37-27| ... | ... | @@ -125,6 +125,31 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 125 | 125 | "tmp.zig:15:23: error: enum field missing: 'arst'", |
| 126 | 126 | "tmp.zig:27:24: note: referenced here", |
| 127 | 127 | }); |
| 128 | ||
| 129 | cases.add("field access of opaque type", | |
| 130 | \\const MyType = opaque {}; | |
| 131 | \\ | |
| 132 | \\export fn entry() bool { | |
| 133 | \\ var x: i32 = 1; | |
| 134 | \\ return bar(@ptrCast(*MyType, &x)); | |
| 135 | \\} | |
| 136 | \\ | |
| 137 | \\fn bar(x: *MyType) bool { | |
| 138 | \\ return x.blah; | |
| 139 | \\} | |
| 140 | , &[_][]const u8{ | |
| 141 | "tmp.zig:9:13: error: no member named 'blah' in opaque type 'MyType'", | |
| 142 | }); | |
| 143 | ||
| 144 | cases.add("opaque type with field", | |
| 145 | \\const Opaque = opaque { foo: i32 }; | |
| 146 | \\export fn entry() void { | |
| 147 | \\ const foo: ?*Opaque = null; | |
| 148 | \\} | |
| 149 | , &[_][]const u8{ | |
| 150 | "tmp.zig:1:25: error: opaque types cannot have fields", | |
| 151 | }); | |
| 152 | ||
| 128 | 153 | cases.add("@Type(.Fn) with is_generic = true", |
| 129 | 154 | \\const Foo = @Type(.{ |
| 130 | 155 | \\ .Fn = .{ |
| ... | ... | @@ -180,7 +205,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 180 | 205 | \\ .layout = .Auto, |
| 181 | 206 | \\ .tag_type = null, |
| 182 | 207 | \\ .fields = &[_]TypeInfo.UnionField{ |
| 183 | \\ .{ .name = "foo", .field_type = @Type(.Opaque), .alignment = 1 }, | |
| 208 | \\ .{ .name = "foo", .field_type = opaque {}, .alignment = 1 }, | |
| 184 | 209 | \\ }, |
| 185 | 210 | \\ .decls = &[_]TypeInfo.Declaration{}, |
| 186 | 211 | \\ }, |
| ... | ... | @@ -2613,7 +2638,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2613 | 2638 | }); |
| 2614 | 2639 | |
| 2615 | 2640 | cases.add("directly embedding opaque type in struct and union", |
| 2616 | \\const O = @Type(.Opaque); | |
| 2641 | \\const O = opaque {}; | |
| 2617 | 2642 | \\const Foo = struct { |
| 2618 | 2643 | \\ o: O, |
| 2619 | 2644 | \\}; |
| ... | ... | @@ -2628,7 +2653,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2628 | 2653 | \\ var bar: Bar = undefined; |
| 2629 | 2654 | \\} |
| 2630 | 2655 | \\export fn c() void { |
| 2631 | \\ var baz: *@Type(.Opaque) = undefined; | |
| 2656 | \\ var baz: *opaque {} = undefined; | |
| 2632 | 2657 | \\ const qux = .{baz.*}; |
| 2633 | 2658 | \\} |
| 2634 | 2659 | , &[_][]const u8{ |
| ... | ... | @@ -3592,7 +3617,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 3592 | 3617 | }); |
| 3593 | 3618 | |
| 3594 | 3619 | cases.add("unknown length pointer to opaque", |
| 3595 | \\export const T = [*]@Type(.Opaque); | |
| 3620 | \\export const T = [*]opaque {}; | |
| 3596 | 3621 | , &[_][]const u8{ |
| 3597 | 3622 | "tmp.zig:1:21: error: unknown-length pointer to opaque", |
| 3598 | 3623 | }); |
| ... | ... | @@ -6827,8 +6852,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6827 | 6852 | "tmp.zig:2:31: error: index 2 outside array of size 2", |
| 6828 | 6853 | }); |
| 6829 | 6854 | |
| 6830 | cases.add("wrong pointer coerced to pointer to @Type(.Opaque)", | |
| 6831 | \\const Derp = @Type(.Opaque); | |
| 6855 | cases.add("wrong pointer coerced to pointer to opaque {}", | |
| 6856 | \\const Derp = opaque {}; | |
| 6832 | 6857 | \\extern fn bar(d: *Derp) void; |
| 6833 | 6858 | \\export fn foo() void { |
| 6834 | 6859 | \\ var x = @as(u8, 1); |
| ... | ... | @@ -6854,8 +6879,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6854 | 6879 | \\export fn entry5() void { |
| 6855 | 6880 | \\ var d = null; |
| 6856 | 6881 | \\} |
| 6857 | \\export fn entry6(opaque: *Opaque) void { | |
| 6858 | \\ var e = opaque.*; | |
| 6882 | \\export fn entry6(opaque_: *Opaque) void { | |
| 6883 | \\ var e = opaque_.*; | |
| 6859 | 6884 | \\} |
| 6860 | 6885 | \\export fn entry7() void { |
| 6861 | 6886 | \\ var f = i32; |
| ... | ... | @@ -6866,7 +6891,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6866 | 6891 | \\export fn entry9() void { |
| 6867 | 6892 | \\ var z: noreturn = return; |
| 6868 | 6893 | \\} |
| 6869 | \\const Opaque = @Type(.Opaque); | |
| 6894 | \\const Opaque = opaque {}; | |
| 6870 | 6895 | \\const Foo = struct { |
| 6871 | 6896 | \\ fn bar(self: *const Foo) void {} |
| 6872 | 6897 | \\}; |
| ... | ... | @@ -7019,21 +7044,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 7019 | 7044 | "tmp.zig:37:29: error: cannot store runtime value in compile time variable", |
| 7020 | 7045 | }); |
| 7021 | 7046 | |
| 7022 | cases.add("field access of opaque type", | |
| 7023 | \\const MyType = @Type(.Opaque); | |
| 7024 | \\ | |
| 7025 | \\export fn entry() bool { | |
| 7026 | \\ var x: i32 = 1; | |
| 7027 | \\ return bar(@ptrCast(*MyType, &x)); | |
| 7028 | \\} | |
| 7029 | \\ | |
| 7030 | \\fn bar(x: *MyType) bool { | |
| 7031 | \\ return x.blah; | |
| 7032 | \\} | |
| 7033 | , &[_][]const u8{ | |
| 7034 | "tmp.zig:9:13: error: type '*MyType' does not support field access", | |
| 7035 | }); | |
| 7036 | ||
| 7037 | 7047 | cases.add("invalid legacy unicode escape", |
| 7038 | 7048 | \\export fn entry() void { |
| 7039 | 7049 | \\ const a = '\U1234'; |
| ... | ... | @@ -7623,7 +7633,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 7623 | 7633 | }); |
| 7624 | 7634 | |
| 7625 | 7635 | cases.add("function returning opaque type", |
| 7626 | \\const FooType = @Type(.Opaque); | |
| 7636 | \\const FooType = opaque {}; | |
| 7627 | 7637 | \\export fn bar() !FooType { |
| 7628 | 7638 | \\ return error.InvalidValue; |
| 7629 | 7639 | \\} |
| ... | ... | @@ -7641,7 +7651,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 7641 | 7651 | }); |
| 7642 | 7652 | |
| 7643 | 7653 | cases.add("generic function returning opaque type", |
| 7644 | \\const FooType = @Type(.Opaque); | |
| 7654 | \\const FooType = opaque {}; | |
| 7645 | 7655 | \\fn generic(comptime T: type) !T { |
| 7646 | 7656 | \\ return undefined; |
| 7647 | 7657 | \\} |
| ... | ... | @@ -7665,7 +7675,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 7665 | 7675 | }); |
| 7666 | 7676 | |
| 7667 | 7677 | cases.add("function parameter is opaque", |
| 7668 | \\const FooType = @Type(.Opaque); | |
| 7678 | \\const FooType = opaque {}; | |
| 7669 | 7679 | \\export fn entry1() void { |
| 7670 | 7680 | \\ const someFuncPtr: fn (FooType) void = undefined; |
| 7671 | 7681 | \\} |
test/gen_h.zig+1-1| ... | ... | @@ -74,7 +74,7 @@ pub fn addCases(cases: *tests.GenHContext) void { |
| 74 | 74 | }); |
| 75 | 75 | |
| 76 | 76 | cases.add("declare opaque type", |
| 77 | \\const Foo = @Type(.Opaque); | |
| 77 | \\const Foo = opaque {}; | |
| 78 | 78 | \\ |
| 79 | 79 | \\export fn entry(foo: ?*Foo) void { } |
| 80 | 80 | , &[_][]const u8{ |
test/stage1/behavior/misc.zig+3-3| ... | ... | @@ -438,8 +438,8 @@ export fn writeToVRam() void { |
| 438 | 438 | vram[0] = 'X'; |
| 439 | 439 | } |
| 440 | 440 | |
| 441 | const OpaqueA = @Type(.Opaque); | |
| 442 | const OpaqueB = @Type(.Opaque); | |
| 441 | const OpaqueA = opaque {}; | |
| 442 | const OpaqueB = opaque {}; | |
| 443 | 443 | test "opaque types" { |
| 444 | 444 | expect(*OpaqueA != *OpaqueB); |
| 445 | 445 | expect(mem.eql(u8, @typeName(OpaqueA), "OpaqueA")); |
| ... | ... | @@ -704,7 +704,7 @@ test "auto created variables have correct alignment" { |
| 704 | 704 | comptime expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a); |
| 705 | 705 | } |
| 706 | 706 | |
| 707 | extern var opaque_extern_var: @Type(.Opaque); | |
| 707 | extern var opaque_extern_var: opaque {}; | |
| 708 | 708 | var var_to_export: u32 = 42; |
| 709 | 709 | test "extern variable with non-pointer opaque type" { |
| 710 | 710 | @export(var_to_export, .{ .name = "opaque_extern_var" }); |
test/stage1/behavior/type.zig+11-2| ... | ... | @@ -190,8 +190,17 @@ test "Type.ErrorUnion" { |
| 190 | 190 | } |
| 191 | 191 | |
| 192 | 192 | test "Type.Opaque" { |
| 193 | testing.expect(@Type(.Opaque) != @Type(.Opaque)); | |
| 194 | testing.expect(@typeInfo(@Type(.Opaque)) == .Opaque); | |
| 193 | const Opaque = @Type(.{ | |
| 194 | .Opaque = .{ | |
| 195 | .decls = &[_]TypeInfo.Declaration{}, | |
| 196 | }, | |
| 197 | }); | |
| 198 | testing.expect(Opaque != opaque {}); | |
| 199 | testing.expectEqualSlices( | |
| 200 | TypeInfo.Declaration, | |
| 201 | &[_]TypeInfo.Declaration{}, | |
| 202 | @typeInfo(Opaque).Opaque.decls, | |
| 203 | ); | |
| 195 | 204 | } |
| 196 | 205 | |
| 197 | 206 | test "Type.Vector" { |
test/stage1/behavior/type_info.zig+16-1| ... | ... | @@ -199,7 +199,7 @@ fn testUnion() void { |
| 199 | 199 | expect(typeinfo_info.Union.tag_type.? == TypeId); |
| 200 | 200 | expect(typeinfo_info.Union.fields.len == 25); |
| 201 | 201 | expect(typeinfo_info.Union.fields[4].field_type == @TypeOf(@typeInfo(u8).Int)); |
| 202 | expect(typeinfo_info.Union.decls.len == 21); | |
| 202 | expect(typeinfo_info.Union.decls.len == 22); | |
| 203 | 203 | |
| 204 | 204 | const TestNoTagUnion = union { |
| 205 | 205 | Foo: void, |
| ... | ... | @@ -265,6 +265,21 @@ const TestStruct = packed struct { |
| 265 | 265 | const Self = @This(); |
| 266 | 266 | }; |
| 267 | 267 | |
| 268 | test "type info: opaque info" { | |
| 269 | testOpaque(); | |
| 270 | comptime testOpaque(); | |
| 271 | } | |
| 272 | ||
| 273 | fn testOpaque() void { | |
| 274 | const Foo = opaque { | |
| 275 | const A = 1; | |
| 276 | fn b() void {} | |
| 277 | }; | |
| 278 | ||
| 279 | const foo_info = @typeInfo(Foo); | |
| 280 | expect(foo_info.Opaque.decls.len == 2); | |
| 281 | } | |
| 282 | ||
| 268 | 283 | test "type info: function type info" { |
| 269 | 284 | // wasm doesn't support align attributes on functions |
| 270 | 285 | if (builtin.arch == .wasm32 or builtin.arch == .wasm64) return error.SkipZigTest; |
test/translate_c.zig+7-7| ... | ... | @@ -137,9 +137,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 137 | 137 | \\struct foo { int x; int y[]; }; |
| 138 | 138 | \\struct bar { int x; int y[0]; }; |
| 139 | 139 | , &[_][]const u8{ |
| 140 | \\pub const struct_foo = @Type(.Opaque); | |
| 140 | \\pub const struct_foo = opaque {}; | |
| 141 | 141 | , |
| 142 | \\pub const struct_bar = @Type(.Opaque); | |
| 142 | \\pub const struct_bar = opaque {}; | |
| 143 | 143 | }); |
| 144 | 144 | |
| 145 | 145 | cases.add("nested loops without blocks", |
| ... | ... | @@ -207,7 +207,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 207 | 207 | \\pub const struct_arcan_shmif_page = // |
| 208 | 208 | , |
| 209 | 209 | \\warning: unsupported type: 'Atomic' |
| 210 | \\ @Type(.Opaque); // | |
| 210 | \\ opaque {}; // | |
| 211 | 211 | , |
| 212 | 212 | \\ warning: struct demoted to opaque type - unable to translate type of field abufused |
| 213 | 213 | , // TODO should be `addr: *struct_arcan_shmif_page` |
| ... | ... | @@ -386,8 +386,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 386 | 386 | \\ struct opaque_2 *cast = (struct opaque_2 *)opaque; |
| 387 | 387 | \\} |
| 388 | 388 | , &[_][]const u8{ |
| 389 | \\pub const struct_opaque = @Type(.Opaque); | |
| 390 | \\pub const struct_opaque_2 = @Type(.Opaque); | |
| 389 | \\pub const struct_opaque = opaque {}; | |
| 390 | \\pub const struct_opaque_2 = opaque {}; | |
| 391 | 391 | \\pub export fn function(arg_opaque_1: ?*struct_opaque) void { |
| 392 | 392 | \\ var opaque_1 = arg_opaque_1; |
| 393 | 393 | \\ var cast: ?*struct_opaque_2 = @ptrCast(?*struct_opaque_2, opaque_1); |
| ... | ... | @@ -628,7 +628,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 628 | 628 | \\ struct Foo *foo; |
| 629 | 629 | \\}; |
| 630 | 630 | , &[_][]const u8{ |
| 631 | \\pub const struct_Foo = @Type(.Opaque); | |
| 631 | \\pub const struct_Foo = opaque {}; | |
| 632 | 632 | , |
| 633 | 633 | \\pub const struct_Bar = extern struct { |
| 634 | 634 | \\ foo: ?*struct_Foo, |
| ... | ... | @@ -705,7 +705,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 705 | 705 | \\struct Foo; |
| 706 | 706 | \\struct Foo *some_func(struct Foo *foo, int x); |
| 707 | 707 | , &[_][]const u8{ |
| 708 | \\pub const struct_Foo = @Type(.Opaque); | |
| 708 | \\pub const struct_Foo = opaque {}; | |
| 709 | 709 | , |
| 710 | 710 | \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo; |
| 711 | 711 | , |