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