Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2015 Andrew Kelley
3 : : *
4 : : * This file is part of zig, which is MIT licensed.
5 : : * See http://opensource.org/licenses/MIT
6 : : */
7 : :
8 : : #include "analyze.hpp"
9 : : #include "ast_render.hpp"
10 : : #include "codegen.hpp"
11 : : #include "config.h"
12 : : #include "error.hpp"
13 : : #include "ir.hpp"
14 : : #include "ir_print.hpp"
15 : : #include "os.hpp"
16 : : #include "parser.hpp"
17 : : #include "softfloat.hpp"
18 : : #include "zig_llvm.h"
19 : :
20 : :
21 : : static const size_t default_backward_branch_quota = 1000;
22 : :
23 : : static Error ATTRIBUTE_MUST_USE resolve_struct_type(CodeGen *g, ZigType *struct_type);
24 : :
25 : : static Error ATTRIBUTE_MUST_USE resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type);
26 : : static Error ATTRIBUTE_MUST_USE resolve_struct_alignment(CodeGen *g, ZigType *struct_type);
27 : : static Error ATTRIBUTE_MUST_USE resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type);
28 : : static Error ATTRIBUTE_MUST_USE resolve_union_zero_bits(CodeGen *g, ZigType *union_type);
29 : : static Error ATTRIBUTE_MUST_USE resolve_union_alignment(CodeGen *g, ZigType *union_type);
30 : : static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry);
31 : : static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status);
32 : : static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, ScopeDecls *dest_decls_scope);
33 : : static void resolve_use_decl(CodeGen *g, TldUsingNamespace *tld_using_namespace, ScopeDecls *dest_decls_scope);
34 : : static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame);
35 : :
36 : : // nullptr means not analyzed yet; this one means currently being analyzed
37 : : static const AstNode *inferred_async_checking = reinterpret_cast<AstNode *>(0x1);
38 : : // this one means analyzed and it's not async
39 : : static const AstNode *inferred_async_none = reinterpret_cast<AstNode *>(0x2);
40 : :
41 : 1770853 : static bool is_top_level_struct(ZigType *import) {
42 [ + + ][ + + ]: 1770853 : return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr;
43 : : }
44 : :
45 : 0 : static ErrorMsg *add_error_note_token(CodeGen *g, ErrorMsg *parent_msg, ZigType *owner, Token *token, Buf *msg) {
46 : 0 : assert(is_top_level_struct(owner));
47 : 0 : RootStruct *root_struct = owner->data.structure.root_struct;
48 : :
49 : 0 : ErrorMsg *err = err_msg_create_with_line(root_struct->path, token->start_line, token->start_column,
50 : 0 : root_struct->source_code, root_struct->line_offsets, msg);
51 : :
52 : 0 : err_msg_add_note(parent_msg, err);
53 : 0 : return err;
54 : : }
55 : :
56 : 0 : ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg) {
57 : 0 : assert(is_top_level_struct(owner));
58 : 0 : RootStruct *root_struct = owner->data.structure.root_struct;
59 : 0 : ErrorMsg *err = err_msg_create_with_line(root_struct->path, token->start_line, token->start_column,
60 : 0 : root_struct->source_code, root_struct->line_offsets, msg);
61 : :
62 : 0 : g->errors.append(err);
63 : 0 : g->trace_err = err;
64 : 0 : return err;
65 : : }
66 : :
67 : 0 : ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
68 : : Token fake_token;
69 : 0 : fake_token.start_line = node->line;
70 : 0 : fake_token.start_column = node->column;
71 : 0 : node->already_traced_this_node = true;
72 : 0 : return add_token_error(g, node->owner, &fake_token, msg);
73 : : }
74 : :
75 : 0 : ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg) {
76 : : Token fake_token;
77 : 0 : fake_token.start_line = node->line;
78 : 0 : fake_token.start_column = node->column;
79 : 0 : return add_error_note_token(g, parent_msg, node->owner, &fake_token, msg);
80 : : }
81 : :
82 : 66926 : ZigType *new_type_table_entry(ZigTypeId id) {
83 : 66926 : ZigType *entry = allocate<ZigType>(1);
84 : 66926 : entry->id = id;
85 : 66926 : return entry;
86 : : }
87 : :
88 : 78641 : static ScopeDecls **get_container_scope_ptr(ZigType *type_entry) {
89 [ + + ]: 78641 : if (type_entry->id == ZigTypeIdStruct) {
90 : 71486 : return &type_entry->data.structure.decls_scope;
91 [ + + ]: 7155 : } else if (type_entry->id == ZigTypeIdEnum) {
92 : 2242 : return &type_entry->data.enumeration.decls_scope;
93 [ + - ]: 4913 : } else if (type_entry->id == ZigTypeIdUnion) {
94 : 4913 : return &type_entry->data.unionation.decls_scope;
95 : : }
96 : 0 : zig_unreachable();
97 : : }
98 : :
99 : 73033 : ScopeDecls *get_container_scope(ZigType *type_entry) {
100 : 73033 : return *get_container_scope_ptr(type_entry);
101 : : }
102 : :
103 : 1005438 : void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) {
104 : 1005438 : dest->codegen = g;
105 : 1005438 : dest->id = id;
106 : 1005438 : dest->source_node = source_node;
107 : 1005438 : dest->parent = parent;
108 : 1005438 : }
109 : :
110 : 7412 : static ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type,
111 : : ZigType *import, Buf *bare_name)
112 : : {
113 [ + + ][ - + ]: 7412 : assert(node == nullptr || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr);
[ # # ]
114 : 7412 : ScopeDecls *scope = allocate<ScopeDecls>(1);
115 : 7412 : init_scope(g, &scope->base, ScopeIdDecls, node, parent);
116 : 7412 : scope->decl_table.init(4);
117 : 7412 : scope->container_type = container_type;
118 : 7412 : scope->import = import;
119 : 7412 : scope->bare_name = bare_name;
120 : 7412 : return scope;
121 : : }
122 : :
123 : 188744 : ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent) {
124 : 188744 : assert(node->type == NodeTypeBlock);
125 : 188744 : ScopeBlock *scope = allocate<ScopeBlock>(1);
126 : 188744 : init_scope(g, &scope->base, ScopeIdBlock, node, parent);
127 : 188744 : scope->name = node->data.block.name;
128 : 188744 : return scope;
129 : : }
130 : :
131 : 1222 : ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent) {
132 : 1222 : assert(node->type == NodeTypeDefer);
133 : 1222 : ScopeDefer *scope = allocate<ScopeDefer>(1);
134 : 1222 : init_scope(g, &scope->base, ScopeIdDefer, node, parent);
135 : 1222 : return scope;
136 : : }
137 : :
138 : 1222 : ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent) {
139 : 1222 : assert(node->type == NodeTypeDefer);
140 : 1222 : ScopeDeferExpr *scope = allocate<ScopeDeferExpr>(1);
141 : 1222 : init_scope(g, &scope->base, ScopeIdDeferExpr, node, parent);
142 : 1222 : return scope;
143 : : }
144 : :
145 : 289872 : Scope *create_var_scope(CodeGen *g, AstNode *node, Scope *parent, ZigVar *var) {
146 : 289872 : ScopeVarDecl *scope = allocate<ScopeVarDecl>(1);
147 : 289872 : init_scope(g, &scope->base, ScopeIdVarDecl, node, parent);
148 : 289872 : scope->var = var;
149 : 289872 : return &scope->base;
150 : : }
151 : :
152 : 0 : ScopeCImport *create_cimport_scope(CodeGen *g, AstNode *node, Scope *parent) {
153 : 0 : assert(node->type == NodeTypeFnCallExpr);
154 : 0 : ScopeCImport *scope = allocate<ScopeCImport>(1);
155 : 0 : init_scope(g, &scope->base, ScopeIdCImport, node, parent);
156 : 0 : buf_resize(&scope->buf, 0);
157 : 0 : return scope;
158 : : }
159 : :
160 : 6816 : ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent) {
161 : 6816 : ScopeLoop *scope = allocate<ScopeLoop>(1);
162 : 6816 : init_scope(g, &scope->base, ScopeIdLoop, node, parent);
163 [ + + ]: 6816 : if (node->type == NodeTypeWhileExpr) {
164 : 2923 : scope->name = node->data.while_expr.name;
165 [ + - ]: 3893 : } else if (node->type == NodeTypeForExpr) {
166 : 3893 : scope->name = node->data.for_expr.name;
167 : : } else {
168 : 0 : zig_unreachable();
169 : : }
170 : 6816 : return scope;
171 : : }
172 : :
173 : 117307 : Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime) {
174 : 117307 : ScopeRuntime *scope = allocate<ScopeRuntime>(1);
175 : 117307 : scope->is_comptime = is_comptime;
176 : 117307 : init_scope(g, &scope->base, ScopeIdRuntime, node, parent);
177 : 117307 : return &scope->base;
178 : : }
179 : :
180 : 384 : ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent) {
181 : 384 : assert(node->type == NodeTypeSuspend);
182 : 384 : ScopeSuspend *scope = allocate<ScopeSuspend>(1);
183 : 384 : init_scope(g, &scope->base, ScopeIdSuspend, node, parent);
184 : 384 : return scope;
185 : : }
186 : :
187 : 35143 : ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry) {
188 : 35143 : ScopeFnDef *scope = allocate<ScopeFnDef>(1);
189 : 35143 : init_scope(g, &scope->base, ScopeIdFnDef, node, parent);
190 : 35143 : scope->fn_entry = fn_entry;
191 : 35143 : return scope;
192 : : }
193 : :
194 : 324975 : Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) {
195 : 324975 : ScopeCompTime *scope = allocate<ScopeCompTime>(1);
196 : 324975 : init_scope(g, &scope->base, ScopeIdCompTime, node, parent);
197 : 324975 : return &scope->base;
198 : : }
199 : :
200 : 32341 : Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent) {
201 : 32341 : ScopeTypeOf *scope = allocate<ScopeTypeOf>(1);
202 : 32341 : init_scope(g, &scope->base, ScopeIdTypeOf, node, parent);
203 : 32341 : return &scope->base;
204 : : }
205 : :
206 : 1755133 : ZigType *get_scope_import(Scope *scope) {
207 [ + - ]: 21893428 : while (scope) {
208 [ + + ]: 21893428 : if (scope->id == ScopeIdDecls) {
209 : 1755133 : ScopeDecls *decls_scope = (ScopeDecls *)scope;
210 : 1755133 : assert(is_top_level_struct(decls_scope->import));
211 : 1755133 : return decls_scope->import;
212 : : }
213 : 20138295 : scope = scope->parent;
214 : : }
215 : 0 : zig_unreachable();
216 : : }
217 : :
218 : 732694 : ScopeTypeOf *get_scope_typeof(Scope *scope) {
219 [ + - ]: 8669639 : while (scope) {
220 [ + + + ]: 8669639 : switch (scope->id) {
221 : 2934 : case ScopeIdTypeOf:
222 : 2934 : return reinterpret_cast<ScopeTypeOf *>(scope);
223 : 729760 : case ScopeIdFnDef:
224 : : case ScopeIdDecls:
225 : 729760 : return nullptr;
226 : 7936945 : default:
227 : 7936945 : scope = scope->parent;
228 : 7936945 : continue;
229 : : }
230 : : }
231 : 0 : zig_unreachable();
232 : : }
233 : :
234 : 5608 : static ZigType *new_container_type_entry(CodeGen *g, ZigTypeId id, AstNode *source_node, Scope *parent_scope,
235 : : Buf *bare_name)
236 : : {
237 : 5608 : ZigType *entry = new_type_table_entry(id);
238 : 5608 : *get_container_scope_ptr(entry) = create_decls_scope(g, source_node, parent_scope, entry,
239 : : get_scope_import(parent_scope), bare_name);
240 : 5608 : return entry;
241 : : }
242 : :
243 : 19594 : static uint8_t bits_needed_for_unsigned(uint64_t x) {
244 [ + + ]: 19594 : if (x == 0) {
245 : 48 : return 0;
246 : : }
247 : 19546 : uint8_t base = log2_u64(x);
248 : 19546 : uint64_t upper = (((uint64_t)1) << base) - 1;
249 [ + - ]: 19546 : return (upper >= x) ? base : (base + 1);
250 : : }
251 : :
252 : 0 : AstNode *type_decl_node(ZigType *type_entry) {
253 [ # # # # : 0 : switch (type_entry->id) {
# # # ]
254 : 0 : case ZigTypeIdInvalid:
255 : 0 : zig_unreachable();
256 : 0 : case ZigTypeIdStruct:
257 : 0 : return type_entry->data.structure.decl_node;
258 : 0 : case ZigTypeIdEnum:
259 : 0 : return type_entry->data.enumeration.decl_node;
260 : 0 : case ZigTypeIdUnion:
261 : 0 : return type_entry->data.unionation.decl_node;
262 : 0 : case ZigTypeIdFnFrame:
263 : 0 : return type_entry->data.frame.fn->proto_node;
264 : 0 : case ZigTypeIdOpaque:
265 : : case ZigTypeIdMetaType:
266 : : case ZigTypeIdVoid:
267 : : case ZigTypeIdBool:
268 : : case ZigTypeIdUnreachable:
269 : : case ZigTypeIdInt:
270 : : case ZigTypeIdFloat:
271 : : case ZigTypeIdPointer:
272 : : case ZigTypeIdArray:
273 : : case ZigTypeIdComptimeFloat:
274 : : case ZigTypeIdComptimeInt:
275 : : case ZigTypeIdEnumLiteral:
276 : : case ZigTypeIdUndefined:
277 : : case ZigTypeIdNull:
278 : : case ZigTypeIdOptional:
279 : : case ZigTypeIdErrorUnion:
280 : : case ZigTypeIdErrorSet:
281 : : case ZigTypeIdFn:
282 : : case ZigTypeIdBoundFn:
283 : : case ZigTypeIdArgTuple:
284 : : case ZigTypeIdVector:
285 : : case ZigTypeIdAnyFrame:
286 : 0 : return nullptr;
287 : : }
288 : 0 : zig_unreachable();
289 : : }
290 : :
291 : 6949072 : bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
292 [ - + + + : 6949072 : switch (type_entry->id) {
+ + + +
- ]
293 : 0 : case ZigTypeIdInvalid:
294 : 0 : zig_unreachable();
295 : 683501 : case ZigTypeIdStruct:
296 : 683501 : return type_entry->data.structure.resolve_status >= status;
297 : 28510 : case ZigTypeIdUnion:
298 : 28510 : return type_entry->data.unionation.resolve_status >= status;
299 : 189331 : case ZigTypeIdEnum:
300 : 189331 : return type_entry->data.enumeration.resolve_status >= status;
301 : 11056 : case ZigTypeIdFnFrame:
302 [ - + + - : 11056 : switch (status) {
- ]
303 : 0 : case ResolveStatusInvalid:
304 : 0 : zig_unreachable();
305 : 8512 : case ResolveStatusUnstarted:
306 : : case ResolveStatusZeroBitsKnown:
307 : 8512 : return true;
308 : 2544 : case ResolveStatusAlignmentKnown:
309 : : case ResolveStatusSizeKnown:
310 : 2544 : return type_entry->data.frame.locals_struct != nullptr;
311 : 0 : case ResolveStatusLLVMFwdDecl:
312 : : case ResolveStatusLLVMFull:
313 : 0 : return type_entry->llvm_type != nullptr;
314 : : }
315 : : case ZigTypeIdOpaque:
316 : 473 : return status < ResolveStatusSizeKnown;
317 : 751487 : case ZigTypeIdPointer:
318 [ - - + - : 751487 : switch (status) {
- ]
319 : 0 : case ResolveStatusInvalid:
320 : 0 : zig_unreachable();
321 : 0 : case ResolveStatusUnstarted:
322 : 0 : return true;
323 : 751487 : case ResolveStatusZeroBitsKnown:
324 : : case ResolveStatusAlignmentKnown:
325 : : case ResolveStatusSizeKnown:
326 : 751487 : return type_entry->abi_size != SIZE_MAX;
327 : 0 : case ResolveStatusLLVMFwdDecl:
328 : : case ResolveStatusLLVMFull:
329 : 0 : return type_entry->llvm_type != nullptr;
330 : : }
331 : : case ZigTypeIdMetaType:
332 : : case ZigTypeIdVoid:
333 : : case ZigTypeIdBool:
334 : : case ZigTypeIdUnreachable:
335 : : case ZigTypeIdInt:
336 : : case ZigTypeIdFloat:
337 : : case ZigTypeIdArray:
338 : : case ZigTypeIdComptimeFloat:
339 : : case ZigTypeIdComptimeInt:
340 : : case ZigTypeIdEnumLiteral:
341 : : case ZigTypeIdUndefined:
342 : : case ZigTypeIdNull:
343 : : case ZigTypeIdOptional:
344 : : case ZigTypeIdErrorUnion:
345 : : case ZigTypeIdErrorSet:
346 : : case ZigTypeIdFn:
347 : : case ZigTypeIdBoundFn:
348 : : case ZigTypeIdArgTuple:
349 : : case ZigTypeIdVector:
350 : : case ZigTypeIdAnyFrame:
351 : 5284714 : return true;
352 : : }
353 : 0 : zig_unreachable();
354 : : }
355 : :
356 : 0 : bool type_is_complete(ZigType *type_entry) {
357 : 0 : return type_is_resolved(type_entry, ResolveStatusSizeKnown);
358 : : }
359 : :
360 : 1399972 : uint64_t type_size(CodeGen *g, ZigType *type_entry) {
361 : 1399972 : assert(type_is_resolved(type_entry, ResolveStatusSizeKnown));
362 : 1399972 : return type_entry->abi_size;
363 : : }
364 : :
365 : 43899 : uint64_t type_size_bits(CodeGen *g, ZigType *type_entry) {
366 : 43899 : assert(type_is_resolved(type_entry, ResolveStatusSizeKnown));
367 : 43899 : return type_entry->size_in_bits;
368 : : }
369 : :
370 : 1188987 : uint32_t get_abi_alignment(CodeGen *g, ZigType *type_entry) {
371 : 1188987 : assert(type_is_resolved(type_entry, ResolveStatusAlignmentKnown));
372 : 1188987 : return type_entry->abi_align;
373 : : }
374 : :
375 : 214624 : static bool is_slice(ZigType *type) {
376 [ + + ][ + + ]: 214624 : return type->id == ZigTypeIdStruct && type->data.structure.is_slice;
377 : : }
378 : :
379 : 19594 : ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
380 : 19594 : return get_int_type(g, false, bits_needed_for_unsigned(x));
381 : : }
382 : :
383 : 3888 : ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type) {
384 [ + + ][ + + ]: 3888 : if (result_type != nullptr && result_type->any_frame_parent != nullptr) {
385 : 2896 : return result_type->any_frame_parent;
386 [ + + ][ + + ]: 992 : } else if (result_type == nullptr && g->builtin_types.entry_any_frame != nullptr) {
387 : 720 : return g->builtin_types.entry_any_frame;
388 : : }
389 : :
390 : 272 : ZigType *entry = new_type_table_entry(ZigTypeIdAnyFrame);
391 : 272 : entry->abi_size = g->builtin_types.entry_usize->abi_size;
392 : 272 : entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
393 : 272 : entry->abi_align = g->builtin_types.entry_usize->abi_align;
394 : 272 : entry->data.any_frame.result_type = result_type;
395 : 272 : buf_init_from_str(&entry->name, "anyframe");
396 [ + + ]: 272 : if (result_type != nullptr) {
397 : 264 : buf_appendf(&entry->name, "->%s", buf_ptr(&result_type->name));
398 : : }
399 : :
400 [ + + ]: 272 : if (result_type != nullptr) {
401 : 264 : result_type->any_frame_parent = entry;
402 [ + - ]: 8 : } else if (result_type == nullptr) {
403 : 8 : g->builtin_types.entry_any_frame = entry;
404 : : }
405 : 272 : return entry;
406 : : }
407 : :
408 : 30438 : static const char *ptr_len_to_star_str(PtrLen ptr_len) {
409 [ + + + - ]: 30438 : switch (ptr_len) {
410 : 29167 : case PtrLenSingle:
411 : 29167 : return "*";
412 : 1127 : case PtrLenUnknown:
413 : 1127 : return "[*]";
414 : 144 : case PtrLenC:
415 : 144 : return "[*c]";
416 : : }
417 : 0 : zig_unreachable();
418 : : }
419 : :
420 : 7280 : ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn) {
421 [ + + ]: 7280 : if (fn->frame_type != nullptr) {
422 : 6144 : return fn->frame_type;
423 : : }
424 : :
425 : 1136 : ZigType *entry = new_type_table_entry(ZigTypeIdFnFrame);
426 : 1136 : buf_resize(&entry->name, 0);
427 : 1136 : buf_appendf(&entry->name, "@Frame(%s)", buf_ptr(&fn->symbol_name));
428 : :
429 : 1136 : entry->data.frame.fn = fn;
430 : :
431 : : // Async function frames are always non-zero bits because they always have a resume index.
432 : 1136 : entry->abi_size = SIZE_MAX;
433 : 1136 : entry->size_in_bits = SIZE_MAX;
434 : :
435 : 1136 : fn->frame_type = entry;
436 : 1136 : return entry;
437 : : }
438 : :
439 : 1504781 : ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
440 : : bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,
441 : : uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero)
442 : : {
443 [ + + ][ + - ]: 1504781 : assert(ptr_len != PtrLenC || allow_zero);
444 : 1504781 : assert(!type_is_invalid(child_type));
445 [ + - ][ + + ]: 1504781 : assert(ptr_len == PtrLenSingle || child_type->id != ZigTypeIdOpaque);
446 : :
447 [ + + ]: 1504781 : if (byte_alignment != 0) {
448 : 625229 : uint32_t abi_alignment = get_abi_alignment(g, child_type);
449 [ + + ]: 625229 : if (byte_alignment == abi_alignment)
450 : 625229 : byte_alignment = 0;
451 : : }
452 : :
453 [ + + ]: 1504781 : if (host_int_bytes != 0) {
454 : 1770 : uint32_t child_type_bits = type_size_bits(g, child_type);
455 [ + + ]: 1770 : if (host_int_bytes * 8 == child_type_bits) {
456 : 556 : assert(bit_offset_in_host == 0);
457 : 1770 : host_int_bytes = 0;
458 : : }
459 : : }
460 : :
461 : 1504781 : TypeId type_id = {};
462 : 1504781 : ZigType **parent_pointer = nullptr;
463 [ + + ][ + + ]: 1504781 : if (host_int_bytes != 0 || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle || allow_zero) {
[ + + ][ + + ]
[ + + ]
464 : 113271 : type_id.id = ZigTypeIdPointer;
465 : 113271 : type_id.data.pointer.child_type = child_type;
466 : 113271 : type_id.data.pointer.is_const = is_const;
467 : 113271 : type_id.data.pointer.is_volatile = is_volatile;
468 : 113271 : type_id.data.pointer.alignment = byte_alignment;
469 : 113271 : type_id.data.pointer.bit_offset_in_host = bit_offset_in_host;
470 : 113271 : type_id.data.pointer.host_int_bytes = host_int_bytes;
471 : 113271 : type_id.data.pointer.ptr_len = ptr_len;
472 : 113271 : type_id.data.pointer.allow_zero = allow_zero;
473 : :
474 : 113271 : auto existing_entry = g->type_table.maybe_get(type_id);
475 [ + + ]: 113271 : if (existing_entry)
476 : 113271 : return existing_entry->value;
477 : : } else {
478 : 1391510 : assert(bit_offset_in_host == 0);
479 [ + + ]: 1391510 : parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)];
480 [ + + ]: 1391510 : if (*parent_pointer) {
481 : 1363121 : assert((*parent_pointer)->data.pointer.explicit_alignment == 0);
482 : 1363121 : return *parent_pointer;
483 : : }
484 : : }
485 : :
486 : 30438 : ZigType *entry = new_type_table_entry(ZigTypeIdPointer);
487 : :
488 : 30438 : const char *star_str = ptr_len_to_star_str(ptr_len);
489 [ + + ]: 30438 : const char *const_str = is_const ? "const " : "";
490 [ + + ]: 30438 : const char *volatile_str = is_volatile ? "volatile " : "";
491 : : const char *allow_zero_str;
492 [ + + ]: 30438 : if (ptr_len == PtrLenC) {
493 : 144 : assert(allow_zero);
494 : 144 : allow_zero_str = "";
495 : : } else {
496 [ + + ]: 30294 : allow_zero_str = allow_zero ? "allowzero " : "";
497 : : }
498 : 30438 : buf_resize(&entry->name, 0);
499 [ + + ][ + + ]: 30438 : if (host_int_bytes == 0 && byte_alignment == 0) {
500 : 29502 : buf_appendf(&entry->name, "%s%s%s%s%s",
501 : : star_str, const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));
502 [ + + ]: 936 : } else if (host_int_bytes == 0) {
503 : 676 : buf_appendf(&entry->name, "%salign(%" PRIu32 ") %s%s%s%s", star_str, byte_alignment,
504 : : const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));
505 [ + + ]: 260 : } else if (byte_alignment == 0) {
506 : 178 : buf_appendf(&entry->name, "%salign(:%" PRIu32 ":%" PRIu32 ") %s%s%s%s", star_str,
507 : : bit_offset_in_host, host_int_bytes, const_str, volatile_str, allow_zero_str,
508 : : buf_ptr(&child_type->name));
509 : : } else {
510 : 82 : buf_appendf(&entry->name, "%salign(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s%s", star_str, byte_alignment,
511 : : bit_offset_in_host, host_int_bytes, const_str, volatile_str, allow_zero_str,
512 : : buf_ptr(&child_type->name));
513 : : }
514 : :
515 [ + + ]: 30438 : if (type_is_resolved(child_type, ResolveStatusZeroBitsKnown)) {
516 [ + + ]: 30161 : if (type_has_bits(child_type)) {
517 : 26183 : entry->abi_size = g->builtin_types.entry_usize->abi_size;
518 : 26183 : entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
519 : 26183 : entry->abi_align = g->builtin_types.entry_usize->abi_align;
520 : : } else {
521 : 3978 : assert(byte_alignment == 0);
522 : 3978 : entry->abi_size = 0;
523 : 3978 : entry->size_in_bits = 0;
524 : 30161 : entry->abi_align = 0;
525 : : }
526 : : } else {
527 : 277 : entry->abi_size = SIZE_MAX;
528 : 277 : entry->size_in_bits = SIZE_MAX;
529 : 277 : entry->abi_align = UINT32_MAX;
530 : : }
531 : :
532 : 30438 : entry->data.pointer.ptr_len = ptr_len;
533 : 30438 : entry->data.pointer.child_type = child_type;
534 : 30438 : entry->data.pointer.is_const = is_const;
535 : 30438 : entry->data.pointer.is_volatile = is_volatile;
536 : 30438 : entry->data.pointer.explicit_alignment = byte_alignment;
537 : 30438 : entry->data.pointer.bit_offset_in_host = bit_offset_in_host;
538 : 30438 : entry->data.pointer.host_int_bytes = host_int_bytes;
539 : 30438 : entry->data.pointer.allow_zero = allow_zero;
540 : :
541 [ + + ]: 30438 : if (parent_pointer) {
542 : 28389 : *parent_pointer = entry;
543 : : } else {
544 : 2049 : g->type_table.put(type_id, entry);
545 : : }
546 : 1504781 : return entry;
547 : : }
548 : :
549 : 135012 : ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const) {
550 : 135012 : return get_pointer_to_type_extra(g, child_type, is_const, false, PtrLenSingle, 0, 0, 0, false);
551 : : }
552 : :
553 : 4973 : ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {
554 [ + + ]: 4973 : if (child_type->optional_parent != nullptr) {
555 : 4185 : return child_type->optional_parent;
556 : : }
557 : :
558 : 788 : assert(type_is_resolved(child_type, ResolveStatusSizeKnown));
559 : :
560 : 788 : ZigType *entry = new_type_table_entry(ZigTypeIdOptional);
561 : :
562 : 788 : buf_resize(&entry->name, 0);
563 : 788 : buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name));
564 : :
565 [ + + ]: 788 : if (!type_has_bits(child_type)) {
566 : 54 : entry->size_in_bits = g->builtin_types.entry_bool->size_in_bits;
567 : 54 : entry->abi_size = g->builtin_types.entry_bool->abi_size;
568 : 54 : entry->abi_align = g->builtin_types.entry_bool->abi_align;
569 [ + + ][ + + ]: 734 : } else if (type_is_nonnull_ptr(child_type) || child_type->id == ZigTypeIdErrorSet) {
[ + + ]
570 : : // This is an optimization but also is necessary for calling C
571 : : // functions where all pointers are optional pointers.
572 : : // Function types are technically pointers.
573 : 456 : entry->size_in_bits = child_type->size_in_bits;
574 : 456 : entry->abi_size = child_type->abi_size;
575 : 456 : entry->abi_align = child_type->abi_align;
576 : : } else {
577 : : // This value only matters if the type is legal in a packed struct, which is not
578 : : // true for optional types which did not fit the above 2 categories (zero bit child type,
579 : : // or nonnull ptr child type, or error set child type).
580 : 278 : entry->size_in_bits = child_type->size_in_bits + 1;
581 : :
582 : : // We're going to make a struct with the child type as the first field,
583 : : // and a bool as the second. Since the child type's abi alignment is guaranteed
584 : : // to be >= the bool's abi size (1 byte), the added size is exactly equal to the
585 : : // child type's ABI alignment.
586 : 278 : assert(child_type->abi_align >= g->builtin_types.entry_bool->abi_size);
587 : 278 : entry->abi_align = child_type->abi_align;
588 : 278 : entry->abi_size = child_type->abi_size + child_type->abi_align;
589 : : }
590 : :
591 : 788 : entry->data.maybe.child_type = child_type;
592 : 788 : entry->data.maybe.resolve_status = ResolveStatusSizeKnown;
593 : :
594 : 788 : child_type->optional_parent = entry;
595 : 788 : return entry;
596 : : }
597 : :
598 : 52824 : static size_t align_forward(size_t addr, size_t alignment) {
599 : 52824 : return (addr + alignment - 1) & ~(alignment - 1);
600 : : }
601 : :
602 : 50614 : static size_t next_field_offset(size_t offset, size_t align_from_zero, size_t field_size, size_t next_field_align) {
603 : : // Convert offset to a pretend address which has the specified alignment.
604 : 50614 : size_t addr = offset + align_from_zero;
605 : : // March the address forward to respect the field alignment.
606 : 50614 : size_t aligned_addr = align_forward(addr + field_size, next_field_align);
607 : : // Convert back from pretend address to offset.
608 : 50614 : return aligned_addr - align_from_zero;
609 : : }
610 : :
611 : 12759 : ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payload_type) {
612 : 12759 : assert(err_set_type->id == ZigTypeIdErrorSet);
613 : 12759 : assert(!type_is_invalid(payload_type));
614 : :
615 : 12759 : TypeId type_id = {};
616 : 12759 : type_id.id = ZigTypeIdErrorUnion;
617 : 12759 : type_id.data.error_union.err_set_type = err_set_type;
618 : 12759 : type_id.data.error_union.payload_type = payload_type;
619 : :
620 : 12759 : auto existing_entry = g->type_table.maybe_get(type_id);
621 [ + + ]: 12759 : if (existing_entry) {
622 : 8798 : return existing_entry->value;
623 : : }
624 : :
625 : 3961 : ZigType *entry = new_type_table_entry(ZigTypeIdErrorUnion);
626 : 3961 : assert(type_is_resolved(payload_type, ResolveStatusSizeKnown));
627 : :
628 : 3961 : buf_resize(&entry->name, 0);
629 : 3961 : buf_appendf(&entry->name, "%s!%s", buf_ptr(&err_set_type->name), buf_ptr(&payload_type->name));
630 : :
631 : 3961 : entry->data.error_union.err_set_type = err_set_type;
632 : 3961 : entry->data.error_union.payload_type = payload_type;
633 : :
634 [ + + ]: 3961 : if (!type_has_bits(payload_type)) {
635 [ + - ]: 972 : if (type_has_bits(err_set_type)) {
636 : 972 : entry->size_in_bits = err_set_type->size_in_bits;
637 : 972 : entry->abi_size = err_set_type->abi_size;
638 : 972 : entry->abi_align = err_set_type->abi_align;
639 : : } else {
640 : 0 : entry->size_in_bits = 0;
641 : 0 : entry->abi_size = 0;
642 : 972 : entry->abi_align = 0;
643 : : }
644 [ - + ]: 2989 : } else if (!type_has_bits(err_set_type)) {
645 : 0 : entry->size_in_bits = payload_type->size_in_bits;
646 : 0 : entry->abi_size = payload_type->abi_size;
647 : 0 : entry->abi_align = payload_type->abi_align;
648 : : } else {
649 : 2989 : entry->abi_align = max(err_set_type->abi_align, payload_type->abi_align);
650 : : size_t field_sizes[2];
651 : : size_t field_aligns[2];
652 : 2989 : field_sizes[err_union_err_index] = err_set_type->abi_size;
653 : 2989 : field_aligns[err_union_err_index] = err_set_type->abi_align;
654 : 2989 : field_sizes[err_union_payload_index] = payload_type->abi_size;
655 : 2989 : field_aligns[err_union_payload_index] = payload_type->abi_align;
656 : 2989 : size_t field2_offset = next_field_offset(0, entry->abi_align, field_sizes[0], field_aligns[1]);
657 : 2989 : entry->abi_size = next_field_offset(field2_offset, entry->abi_align, field_sizes[1], entry->abi_align);
658 : 2989 : entry->size_in_bits = entry->abi_size * 8;
659 : 2989 : entry->data.error_union.pad_bytes = entry->abi_size - (field2_offset + field_sizes[1]);
660 : : }
661 : :
662 : 3961 : g->type_table.put(type_id, entry);
663 : 12759 : return entry;
664 : : }
665 : :
666 : 27354 : ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size) {
667 : 27354 : TypeId type_id = {};
668 : 27354 : type_id.id = ZigTypeIdArray;
669 : 27354 : type_id.data.array.child_type = child_type;
670 : 27354 : type_id.data.array.size = array_size;
671 : 27354 : auto existing_entry = g->type_table.maybe_get(type_id);
672 [ + + ]: 27354 : if (existing_entry) {
673 : 24618 : return existing_entry->value;
674 : : }
675 : :
676 : 2736 : assert(type_is_resolved(child_type, ResolveStatusSizeKnown));
677 : :
678 : 2736 : ZigType *entry = new_type_table_entry(ZigTypeIdArray);
679 : :
680 : 2736 : buf_resize(&entry->name, 0);
681 : 2736 : buf_appendf(&entry->name, "[%" ZIG_PRI_u64 "]%s", array_size, buf_ptr(&child_type->name));
682 : :
683 : 2736 : entry->size_in_bits = child_type->size_in_bits * array_size;
684 : 2736 : entry->abi_align = child_type->abi_align;
685 : 2736 : entry->abi_size = child_type->abi_size * array_size;
686 : :
687 : 2736 : entry->data.array.child_type = child_type;
688 : 2736 : entry->data.array.len = array_size;
689 : :
690 : 2736 : g->type_table.put(type_id, entry);
691 : 27354 : return entry;
692 : : }
693 : :
694 : 83780 : ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
695 : 83780 : assert(ptr_type->id == ZigTypeIdPointer);
696 : 83780 : assert(ptr_type->data.pointer.ptr_len == PtrLenUnknown);
697 : :
698 : 83780 : ZigType **parent_pointer = &ptr_type->data.pointer.slice_parent;
699 [ + + ]: 83780 : if (*parent_pointer) {
700 : 82715 : return *parent_pointer;
701 : : }
702 : :
703 : 1065 : ZigType *entry = new_type_table_entry(ZigTypeIdStruct);
704 : :
705 : : // replace the & with [] to go from a ptr type name to a slice type name
706 : 1065 : buf_resize(&entry->name, 0);
707 [ - + ]: 1065 : size_t name_offset = (ptr_type->data.pointer.ptr_len == PtrLenSingle) ? 1 : 3;
708 : 1065 : buf_appendf(&entry->name, "[]%s", buf_ptr(&ptr_type->name) + name_offset);
709 : :
710 : 1065 : unsigned element_count = 2;
711 : 1065 : Buf *ptr_field_name = buf_create_from_str("ptr");
712 : 1065 : Buf *len_field_name = buf_create_from_str("len");
713 : :
714 : 1065 : entry->data.structure.resolve_status = ResolveStatusSizeKnown;
715 : 1065 : entry->data.structure.layout = ContainerLayoutAuto;
716 : 1065 : entry->data.structure.is_slice = true;
717 : 1065 : entry->data.structure.src_field_count = element_count;
718 : 1065 : entry->data.structure.gen_field_count = element_count;
719 : 1065 : entry->data.structure.fields = allocate<TypeStructField>(element_count);
720 : 1065 : entry->data.structure.fields_by_name.init(element_count);
721 : 1065 : entry->data.structure.fields[slice_ptr_index].name = ptr_field_name;
722 : 1065 : entry->data.structure.fields[slice_ptr_index].type_entry = ptr_type;
723 : 1065 : entry->data.structure.fields[slice_ptr_index].src_index = slice_ptr_index;
724 : 1065 : entry->data.structure.fields[slice_ptr_index].gen_index = 0;
725 : 1065 : entry->data.structure.fields[slice_len_index].name = len_field_name;
726 : 1065 : entry->data.structure.fields[slice_len_index].type_entry = g->builtin_types.entry_usize;
727 : 1065 : entry->data.structure.fields[slice_len_index].src_index = slice_len_index;
728 : 1065 : entry->data.structure.fields[slice_len_index].gen_index = 1;
729 : :
730 : 1065 : entry->data.structure.fields_by_name.put(ptr_field_name, &entry->data.structure.fields[slice_ptr_index]);
731 : 1065 : entry->data.structure.fields_by_name.put(len_field_name, &entry->data.structure.fields[slice_len_index]);
732 : :
733 [ - + + - ]: 1065 : switch (type_requires_comptime(g, ptr_type)) {
734 : 0 : case ReqCompTimeInvalid:
735 : 0 : zig_unreachable();
736 : 959 : case ReqCompTimeNo:
737 : 959 : break;
738 : 106 : case ReqCompTimeYes:
739 : 106 : entry->data.structure.requires_comptime = true;
740 : : }
741 : :
742 [ + + ]: 1065 : if (!type_has_bits(ptr_type)) {
743 : 48 : entry->data.structure.gen_field_count = 1;
744 : 48 : entry->data.structure.fields[slice_ptr_index].gen_index = SIZE_MAX;
745 : 48 : entry->data.structure.fields[slice_len_index].gen_index = 0;
746 : : }
747 : :
748 : 1065 : ZigType *child_type = ptr_type->data.pointer.child_type;
749 [ + + ][ + + ]: 1065 : if (ptr_type->data.pointer.is_const || ptr_type->data.pointer.is_volatile ||
[ + + ]
750 [ + + ]: 619 : ptr_type->data.pointer.explicit_alignment != 0 || ptr_type->data.pointer.allow_zero)
751 : : {
752 : : ZigType *peer_ptr_type = get_pointer_to_type_extra(g, child_type, false, false,
753 : 470 : PtrLenUnknown, 0, 0, 0, false);
754 : 470 : ZigType *peer_slice_type = get_slice_type(g, peer_ptr_type);
755 : :
756 : 470 : entry->size_in_bits = peer_slice_type->size_in_bits;
757 : 470 : entry->abi_size = peer_slice_type->abi_size;
758 : 470 : entry->abi_align = peer_slice_type->abi_align;
759 : :
760 : 470 : *parent_pointer = entry;
761 : 470 : return entry;
762 : : }
763 : :
764 [ + + ]: 595 : if (type_has_bits(ptr_type)) {
765 : 571 : entry->size_in_bits = ptr_type->size_in_bits + g->builtin_types.entry_usize->size_in_bits;
766 : 571 : entry->abi_size = ptr_type->abi_size + g->builtin_types.entry_usize->abi_size;
767 : 571 : entry->abi_align = ptr_type->abi_align;
768 : : } else {
769 : 24 : entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
770 : 24 : entry->abi_size = g->builtin_types.entry_usize->abi_size;
771 : 24 : entry->abi_align = g->builtin_types.entry_usize->abi_align;
772 : : }
773 : :
774 : 595 : *parent_pointer = entry;
775 : 83780 : return entry;
776 : : }
777 : :
778 : 41 : ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name) {
779 : 41 : ZigType *entry = new_type_table_entry(ZigTypeIdOpaque);
780 : :
781 : 41 : buf_init_from_str(&entry->name, full_name);
782 : :
783 [ + + ]: 41 : ZigType *import = scope ? get_scope_import(scope) : nullptr;
784 [ + + ]: 41 : unsigned line = source_node ? (unsigned)(source_node->line + 1) : 0;
785 : :
786 : 41 : entry->llvm_type = LLVMInt8Type();
787 [ + + ][ + + ]: 41 : entry->llvm_di_type = ZigLLVMCreateDebugForwardDeclType(g->dbuilder,
788 : : ZigLLVMTag_DW_structure_type(), full_name,
789 : 20 : import ? ZigLLVMFileToScope(import->data.structure.root_struct->di_file) : nullptr,
790 : 20 : import ? import->data.structure.root_struct->di_file : nullptr,
791 : : line);
792 : 41 : entry->data.opaque.bare_name = bare_name;
793 : :
794 : : // The actual size is unknown, but the value must not be 0 because that
795 : : // is how type_has_bits is determined.
796 : 41 : entry->abi_size = SIZE_MAX;
797 : 41 : entry->size_in_bits = SIZE_MAX;
798 : 41 : entry->abi_align = 1;
799 : :
800 : 41 : return entry;
801 : : }
802 : :
803 : 9488 : ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry) {
804 : 9488 : ZigType *fn_type = fn_entry->type_entry;
805 : 9488 : assert(fn_type->id == ZigTypeIdFn);
806 [ + + ]: 9488 : if (fn_type->data.fn.bound_fn_parent)
807 : 8044 : return fn_type->data.fn.bound_fn_parent;
808 : :
809 : 1444 : ZigType *bound_fn_type = new_type_table_entry(ZigTypeIdBoundFn);
810 : 1444 : bound_fn_type->data.bound_fn.fn_type = fn_type;
811 : :
812 : 1444 : buf_resize(&bound_fn_type->name, 0);
813 : 1444 : buf_appendf(&bound_fn_type->name, "(bound %s)", buf_ptr(&fn_type->name));
814 : :
815 : 1444 : fn_type->data.fn.bound_fn_parent = bound_fn_type;
816 : 1444 : return bound_fn_type;
817 : : }
818 : :
819 : 0 : const char *calling_convention_name(CallingConvention cc) {
820 [ # # # # : 0 : switch (cc) {
# # # ]
821 : 0 : case CallingConventionUnspecified: return "undefined";
822 : 0 : case CallingConventionC: return "ccc";
823 : 0 : case CallingConventionCold: return "coldcc";
824 : 0 : case CallingConventionNaked: return "nakedcc";
825 : 0 : case CallingConventionStdcall: return "stdcallcc";
826 : 0 : case CallingConventionAsync: return "async";
827 : : }
828 : 0 : zig_unreachable();
829 : : }
830 : :
831 : 10759 : static const char *calling_convention_fn_type_str(CallingConvention cc) {
832 [ + + - + : 10759 : switch (cc) {
+ + - ]
833 : 10187 : case CallingConventionUnspecified: return "";
834 : 423 : case CallingConventionC: return "extern ";
835 : 0 : case CallingConventionCold: return "coldcc ";
836 : 11 : case CallingConventionNaked: return "nakedcc ";
837 : 58 : case CallingConventionStdcall: return "stdcallcc ";
838 : 80 : case CallingConventionAsync: return "async ";
839 : : }
840 : 0 : zig_unreachable();
841 : : }
842 : :
843 : 38636 : bool calling_convention_allows_zig_types(CallingConvention cc) {
844 [ + + - ]: 38636 : switch (cc) {
845 : 32267 : case CallingConventionUnspecified:
846 : : case CallingConventionAsync:
847 : 32267 : return true;
848 : 6369 : case CallingConventionC:
849 : : case CallingConventionCold:
850 : : case CallingConventionNaked:
851 : : case CallingConventionStdcall:
852 : 6369 : return false;
853 : : }
854 : 0 : zig_unreachable();
855 : : }
856 : :
857 : 27756 : ZigType *get_stack_trace_type(CodeGen *g) {
858 [ + + ]: 27756 : if (g->stack_trace_type == nullptr) {
859 : 15 : ConstExprValue *stack_trace_type_val = get_builtin_value(g, "StackTrace");
860 : 15 : assert(stack_trace_type_val->type->id == ZigTypeIdMetaType);
861 : :
862 : 15 : g->stack_trace_type = stack_trace_type_val->data.x_type;
863 : 15 : assertNoError(type_resolve(g, g->stack_trace_type, ResolveStatusZeroBitsKnown));
864 : : }
865 : 27756 : return g->stack_trace_type;
866 : : }
867 : :
868 : 103542 : bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {
869 [ + + ]: 103542 : if (fn_type_id->cc == CallingConventionUnspecified) {
870 : 92917 : return handle_is_ptr(fn_type_id->return_type);
871 : : }
872 [ + + ]: 10625 : if (fn_type_id->cc != CallingConventionC) {
873 : 1228 : return false;
874 : : }
875 [ + + ]: 9397 : if (type_is_c_abi_int(g, fn_type_id->return_type)) {
876 : 9336 : return false;
877 : : }
878 [ + - ]: 61 : if (g->zig_target->arch == ZigLLVM_x86_64) {
879 : 61 : X64CABIClass abi_class = type_c_abi_x86_64_class(g, fn_type_id->return_type);
880 : 61 : return abi_class == X64CABIClass_MEMORY;
881 [ # # ]: 0 : } else if (target_is_arm(g->zig_target)) {
882 : 0 : return type_size(g, fn_type_id->return_type) > 16;
883 : : }
884 : 0 : zig_panic("TODO implement C ABI for this architecture. See https://github.com/ziglang/zig/issues/1481");
885 : : }
886 : :
887 : 21768 : ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
888 : : Error err;
889 : 21768 : auto table_entry = g->fn_type_table.maybe_get(fn_type_id);
890 [ + + ]: 21768 : if (table_entry) {
891 : 12932 : return table_entry->value;
892 : : }
893 [ + - ]: 8836 : if (fn_type_id->return_type != nullptr) {
894 [ - + ]: 8836 : if ((err = type_resolve(g, fn_type_id->return_type, ResolveStatusSizeKnown)))
895 : 0 : return g->builtin_types.entry_invalid;
896 : 8836 : assert(fn_type_id->return_type->id != ZigTypeIdOpaque);
897 : : } else {
898 : 0 : zig_panic("TODO implement inferred return types https://github.com/ziglang/zig/issues/447");
899 : : }
900 : :
901 : 8836 : ZigType *fn_type = new_type_table_entry(ZigTypeIdFn);
902 : 8836 : fn_type->data.fn.fn_type_id = *fn_type_id;
903 : :
904 : : // populate the name of the type
905 : 8836 : buf_resize(&fn_type->name, 0);
906 : 8836 : const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);
907 : 8836 : buf_appendf(&fn_type->name, "%s", cc_str);
908 : 8836 : buf_appendf(&fn_type->name, "fn(");
909 [ + + ]: 26734 : for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
910 : 17898 : FnTypeParamInfo *param_info = &fn_type_id->param_info[i];
911 : :
912 : 17898 : ZigType *param_type = param_info->type;
913 [ + + ]: 17898 : const char *comma = (i == 0) ? "" : ", ";
914 [ + + ]: 17898 : const char *noalias_str = param_info->is_noalias ? "noalias " : "";
915 : 17898 : buf_appendf(&fn_type->name, "%s%s%s", comma, noalias_str, buf_ptr(¶m_type->name));
916 : : }
917 : :
918 [ + + ]: 8836 : if (fn_type_id->is_var_args) {
919 [ - + ]: 4 : const char *comma = (fn_type_id->param_count == 0) ? "" : ", ";
920 : 4 : buf_appendf(&fn_type->name, "%s...", comma);
921 : : }
922 : 8836 : buf_appendf(&fn_type->name, ")");
923 [ + + ]: 8836 : if (fn_type_id->alignment != 0) {
924 : 72 : buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment);
925 : : }
926 : 8836 : buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name));
927 : :
928 : : // The fn_type is a pointer; not to be confused with the raw function type.
929 : 8836 : fn_type->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
930 : 8836 : fn_type->abi_size = g->builtin_types.entry_usize->abi_size;
931 : 8836 : fn_type->abi_align = g->builtin_types.entry_usize->abi_align;
932 : :
933 : 8836 : g->fn_type_table.put(&fn_type->data.fn.fn_type_id, fn_type);
934 : :
935 : 21768 : return fn_type;
936 : : }
937 : :
938 : 5608 : static ZigTypeId container_to_type(ContainerKind kind) {
939 [ + + + - ]: 5608 : switch (kind) {
940 : 3922 : case ContainerKindStruct:
941 : 3922 : return ZigTypeIdStruct;
942 : 1109 : case ContainerKindEnum:
943 : 1109 : return ZigTypeIdEnum;
944 : 577 : case ContainerKindUnion:
945 : 577 : return ZigTypeIdUnion;
946 : : }
947 : 0 : zig_unreachable();
948 : : }
949 : :
950 : : // This is like get_partial_container_type except it's for the implicit root struct of files.
951 : 1804 : static ZigType *get_root_container_type(CodeGen *g, const char *full_name, Buf *bare_name,
952 : : RootStruct *root_struct)
953 : : {
954 : 1804 : ZigType *entry = new_type_table_entry(ZigTypeIdStruct);
955 : 1804 : entry->data.structure.decls_scope = create_decls_scope(g, nullptr, nullptr, entry, entry, bare_name);
956 : 1804 : entry->data.structure.root_struct = root_struct;
957 : 1804 : entry->data.structure.layout = ContainerLayoutAuto;
958 : :
959 : 1804 : buf_init_from_str(&entry->name, full_name);
960 : 1804 : return entry;
961 : : }
962 : :
963 : 5608 : ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind,
964 : : AstNode *decl_node, const char *full_name, Buf *bare_name, ContainerLayout layout)
965 : : {
966 : 5608 : ZigTypeId type_id = container_to_type(kind);
967 : 5608 : ZigType *entry = new_container_type_entry(g, type_id, decl_node, scope, bare_name);
968 : :
969 [ + + + - ]: 5608 : switch (kind) {
970 : 3922 : case ContainerKindStruct:
971 : 3922 : entry->data.structure.decl_node = decl_node;
972 : 3922 : entry->data.structure.layout = layout;
973 : 3922 : break;
974 : 1109 : case ContainerKindEnum:
975 : 1109 : entry->data.enumeration.decl_node = decl_node;
976 : 1109 : entry->data.enumeration.layout = layout;
977 : 1109 : break;
978 : 577 : case ContainerKindUnion:
979 : 577 : entry->data.unionation.decl_node = decl_node;
980 : 577 : entry->data.unionation.layout = layout;
981 : 577 : break;
982 : : }
983 : :
984 : 5608 : buf_init_from_str(&entry->name, full_name);
985 : :
986 : 5608 : return entry;
987 : : }
988 : :
989 : 45465 : ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry,
990 : : Buf *type_name, UndefAllowed undef)
991 : : {
992 : 45465 : size_t backward_branch_count = 0;
993 : 45465 : size_t backward_branch_quota = default_backward_branch_quota;
994 : : return ir_eval_const_value(g, scope, node, type_entry,
995 : : &backward_branch_count, &backward_branch_quota,
996 : 45465 : nullptr, nullptr, node, type_name, nullptr, nullptr, undef);
997 : : }
998 : :
999 : 11013 : Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, ZigType *parent_type,
1000 : : ConstExprValue *parent_type_val, bool *is_zero_bits)
1001 : : {
1002 : : Error err;
1003 [ + + ]: 11013 : if (type_val->special != ConstValSpecialLazy) {
1004 : 8950 : assert(type_val->special == ConstValSpecialStatic);
1005 [ + + ][ + + ]: 8950 : if ((type_val->data.x_type->id == ZigTypeIdStruct &&
1006 [ + + ]: 8889 : type_val->data.x_type->data.structure.resolve_loop_flag_zero_bits) ||
1007 [ + + ]: 176 : (type_val->data.x_type->id == ZigTypeIdUnion &&
1008 [ + + ]: 8881 : type_val->data.x_type->data.unionation.resolve_loop_flag_zero_bits) ||
1009 : 8881 : type_val->data.x_type->id == ZigTypeIdPointer)
1010 : : {
1011 : : // Does a struct/union which contains a pointer field to itself have bits? Yes.
1012 : 89 : *is_zero_bits = false;
1013 : 89 : return ErrorNone;
1014 : : }
1015 [ - + ]: 8861 : if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusZeroBitsKnown)))
1016 : 0 : return err;
1017 : 8861 : *is_zero_bits = (type_val->data.x_type->abi_size == 0);
1018 : 8861 : return ErrorNone;
1019 : : }
1020 [ - + + + : 2063 : switch (type_val->data.x_lazy->id) {
- ]
1021 : 0 : case LazyValueIdInvalid:
1022 : : case LazyValueIdAlignOf:
1023 : : case LazyValueIdSizeOf:
1024 : 0 : zig_unreachable();
1025 : 595 : case LazyValueIdPtrType: {
1026 : 595 : LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
1027 : :
1028 [ - + ]: 595 : if (parent_type_val == &lazy_ptr_type->elem_type->value) {
1029 : : // Does a struct which contains a pointer field to itself have bits? Yes.
1030 : 0 : *is_zero_bits = false;
1031 : 0 : return ErrorNone;
1032 : : } else {
1033 [ + - ]: 595 : if (parent_type_val == nullptr) {
1034 : 595 : parent_type_val = type_val;
1035 : : }
1036 : 595 : return type_val_resolve_zero_bits(g, &lazy_ptr_type->elem_type->value, parent_type,
1037 : 595 : parent_type_val, is_zero_bits);
1038 : : }
1039 : : }
1040 : 1257 : case LazyValueIdOptType:
1041 : : case LazyValueIdSliceType:
1042 : : case LazyValueIdErrUnionType:
1043 : 1257 : *is_zero_bits = false;
1044 : 1257 : return ErrorNone;
1045 : 211 : case LazyValueIdFnType: {
1046 : 211 : LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy);
1047 : 211 : *is_zero_bits = lazy_fn_type->is_generic;
1048 : 211 : return ErrorNone;
1049 : : }
1050 : : }
1051 : 0 : zig_unreachable();
1052 : : }
1053 : :
1054 : 8673 : Error type_val_resolve_is_opaque_type(CodeGen *g, ConstExprValue *type_val, bool *is_opaque_type) {
1055 [ + + ]: 8673 : if (type_val->special != ConstValSpecialLazy) {
1056 : 6817 : assert(type_val->special == ConstValSpecialStatic);
1057 : 6817 : *is_opaque_type = (type_val->data.x_type->id == ZigTypeIdOpaque);
1058 : 6817 : return ErrorNone;
1059 : : }
1060 [ - + - ]: 1856 : switch (type_val->data.x_lazy->id) {
1061 : 0 : case LazyValueIdInvalid:
1062 : : case LazyValueIdAlignOf:
1063 : : case LazyValueIdSizeOf:
1064 : 0 : zig_unreachable();
1065 : 1856 : case LazyValueIdSliceType:
1066 : : case LazyValueIdPtrType:
1067 : : case LazyValueIdFnType:
1068 : : case LazyValueIdOptType:
1069 : : case LazyValueIdErrUnionType:
1070 : 1856 : *is_opaque_type = false;
1071 : 1856 : return ErrorNone;
1072 : : }
1073 : 0 : zig_unreachable();
1074 : : }
1075 : :
1076 : 11579 : static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue *type_val) {
1077 [ + + ]: 11579 : if (type_val->special != ConstValSpecialLazy) {
1078 : 9026 : return type_requires_comptime(g, type_val->data.x_type);
1079 : : }
1080 [ - + + + : 2553 : switch (type_val->data.x_lazy->id) {
+ + - ]
1081 : 0 : case LazyValueIdInvalid:
1082 : : case LazyValueIdAlignOf:
1083 : : case LazyValueIdSizeOf:
1084 : 0 : zig_unreachable();
1085 : 881 : case LazyValueIdSliceType: {
1086 : 881 : LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
1087 : 881 : return type_val_resolve_requires_comptime(g, &lazy_slice_type->elem_type->value);
1088 : : }
1089 : 809 : case LazyValueIdPtrType: {
1090 : 809 : LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
1091 : 809 : return type_val_resolve_requires_comptime(g, &lazy_ptr_type->elem_type->value);
1092 : : }
1093 : 519 : case LazyValueIdOptType: {
1094 : 519 : LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy);
1095 : 519 : return type_val_resolve_requires_comptime(g, &lazy_opt_type->payload_type->value);
1096 : : }
1097 : 240 : case LazyValueIdFnType: {
1098 : 240 : LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy);
1099 [ - + ]: 240 : if (lazy_fn_type->is_generic)
1100 : 0 : return ReqCompTimeYes;
1101 [ - - + - ]: 240 : switch (type_val_resolve_requires_comptime(g, &lazy_fn_type->return_type->value)) {
1102 : 0 : case ReqCompTimeInvalid:
1103 : 0 : return ReqCompTimeInvalid;
1104 : 0 : case ReqCompTimeYes:
1105 : 0 : return ReqCompTimeYes;
1106 : 240 : case ReqCompTimeNo:
1107 : 240 : break;
1108 : : }
1109 : 240 : size_t param_count = lazy_fn_type->proto_node->data.fn_proto.params.length;
1110 [ + + ]: 593 : for (size_t i = 0; i < param_count; i += 1) {
1111 : 353 : AstNode *param_node = lazy_fn_type->proto_node->data.fn_proto.params.at(i);
1112 : 353 : bool param_is_var_args = param_node->data.param_decl.is_var_args;
1113 [ - + ]: 353 : if (param_is_var_args) break;
1114 [ - - + - ]: 353 : switch (type_val_resolve_requires_comptime(g, &lazy_fn_type->param_types[i]->value)) {
1115 : 0 : case ReqCompTimeInvalid:
1116 : 0 : return ReqCompTimeInvalid;
1117 : 0 : case ReqCompTimeYes:
1118 : 0 : return ReqCompTimeYes;
1119 : 353 : case ReqCompTimeNo:
1120 : 353 : break;
1121 : : }
1122 : : }
1123 : 240 : return ReqCompTimeNo;
1124 : : }
1125 : 104 : case LazyValueIdErrUnionType: {
1126 : 104 : LazyValueErrUnionType *lazy_err_union_type =
1127 : : reinterpret_cast<LazyValueErrUnionType *>(type_val->data.x_lazy);
1128 : 104 : return type_val_resolve_requires_comptime(g, &lazy_err_union_type->payload_type->value);
1129 : : }
1130 : : }
1131 : 0 : zig_unreachable();
1132 : : }
1133 : :
1134 : 6616 : Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ConstExprValue *type_val,
1135 : : size_t *abi_size, size_t *size_in_bits)
1136 : : {
1137 : : Error err;
1138 : :
1139 : 7095 : start_over:
1140 [ + + ]: 7095 : if (type_val->special != ConstValSpecialLazy) {
1141 : 5340 : assert(type_val->special == ConstValSpecialStatic);
1142 : 5340 : ZigType *ty = type_val->data.x_type;
1143 [ - + ]: 5340 : if ((err = type_resolve(g, ty, ResolveStatusSizeKnown)))
1144 : 0 : return err;
1145 : 5340 : *abi_size = ty->abi_size;
1146 : 5340 : *size_in_bits = ty->size_in_bits;
1147 : 5340 : return ErrorNone;
1148 : : }
1149 [ - + + + : 1755 : switch (type_val->data.x_lazy->id) {
+ - ]
1150 : 0 : case LazyValueIdInvalid:
1151 : : case LazyValueIdAlignOf:
1152 : : case LazyValueIdSizeOf:
1153 : 0 : zig_unreachable();
1154 : 667 : case LazyValueIdSliceType: {
1155 : 667 : LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
1156 : : bool is_zero_bits;
1157 [ - + ]: 667 : if ((err = type_val_resolve_zero_bits(g, &lazy_slice_type->elem_type->value, nullptr,
1158 : 667 : nullptr, &is_zero_bits)))
1159 : : {
1160 : 0 : return err;
1161 : : }
1162 [ - + ]: 667 : if (is_zero_bits) {
1163 : 0 : *abi_size = g->builtin_types.entry_usize->abi_size;
1164 : 0 : *size_in_bits = g->builtin_types.entry_usize->size_in_bits;
1165 : : } else {
1166 : 667 : *abi_size = g->builtin_types.entry_usize->abi_size * 2;
1167 : 667 : *size_in_bits = g->builtin_types.entry_usize->size_in_bits * 2;
1168 : : }
1169 : 667 : return ErrorNone;
1170 : : }
1171 : 398 : case LazyValueIdPtrType: {
1172 : 398 : LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
1173 : : bool is_zero_bits;
1174 [ - + ]: 398 : if ((err = type_val_resolve_zero_bits(g, &lazy_ptr_type->elem_type->value, nullptr,
1175 : 398 : nullptr, &is_zero_bits)))
1176 : : {
1177 : 0 : return err;
1178 : : }
1179 [ - + ]: 398 : if (is_zero_bits) {
1180 : 0 : *abi_size = 0;
1181 : 0 : *size_in_bits = 0;
1182 : : } else {
1183 : 398 : *abi_size = g->builtin_types.entry_usize->abi_size;
1184 : 398 : *size_in_bits = g->builtin_types.entry_usize->size_in_bits;
1185 : : }
1186 : 398 : return ErrorNone;
1187 : : }
1188 : 211 : case LazyValueIdFnType:
1189 : 211 : *abi_size = g->builtin_types.entry_usize->abi_size;
1190 : 211 : *size_in_bits = g->builtin_types.entry_usize->size_in_bits;
1191 : 211 : return ErrorNone;
1192 : 479 : case LazyValueIdOptType:
1193 : : case LazyValueIdErrUnionType:
1194 [ - + ]: 479 : if ((err = ir_resolve_lazy(g, source_node, type_val)))
1195 : 0 : return err;
1196 : 479 : goto start_over;
1197 : : }
1198 : 0 : zig_unreachable();
1199 : : }
1200 : :
1201 : 7999 : Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align) {
1202 : : Error err;
1203 [ + + ]: 7999 : if (type_val->special != ConstValSpecialLazy) {
1204 : 5884 : assert(type_val->special == ConstValSpecialStatic);
1205 : 5884 : ZigType *ty = type_val->data.x_type;
1206 [ + + ]: 5884 : if (ty->id == ZigTypeIdPointer) {
1207 : 14 : *abi_align = g->builtin_types.entry_usize->abi_align;
1208 : 14 : return ErrorNone;
1209 : : }
1210 [ - + ]: 5870 : if ((err = type_resolve(g, ty, ResolveStatusAlignmentKnown)))
1211 : 0 : return err;
1212 : 5870 : *abi_align = ty->abi_align;
1213 : 5870 : return ErrorNone;
1214 : : }
1215 [ - + + + : 2115 : switch (type_val->data.x_lazy->id) {
- ]
1216 : 0 : case LazyValueIdInvalid:
1217 : : case LazyValueIdAlignOf:
1218 : : case LazyValueIdSizeOf:
1219 : 0 : zig_unreachable();
1220 : 1628 : case LazyValueIdSliceType:
1221 : : case LazyValueIdPtrType:
1222 : : case LazyValueIdFnType:
1223 : 1628 : *abi_align = g->builtin_types.entry_usize->abi_align;
1224 : 1628 : return ErrorNone;
1225 : 486 : case LazyValueIdOptType: {
1226 : 486 : LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy);
1227 : 486 : return type_val_resolve_abi_align(g, &lazy_opt_type->payload_type->value, abi_align);
1228 : : }
1229 : 1 : case LazyValueIdErrUnionType: {
1230 : 1 : LazyValueErrUnionType *lazy_err_union_type =
1231 : : reinterpret_cast<LazyValueErrUnionType *>(type_val->data.x_lazy);
1232 : : uint32_t payload_abi_align;
1233 [ - + ]: 1 : if ((err = type_val_resolve_abi_align(g, &lazy_err_union_type->payload_type->value,
1234 : 1 : &payload_abi_align)))
1235 : : {
1236 : 0 : return err;
1237 : : }
1238 [ - + ]: 1 : *abi_align = (payload_abi_align > g->err_tag_type->abi_align) ?
1239 : 0 : payload_abi_align : g->err_tag_type->abi_align;
1240 : 1 : return ErrorNone;
1241 : : }
1242 : : }
1243 : 0 : zig_unreachable();
1244 : : }
1245 : :
1246 : 1119 : static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ConstExprValue *type_val) {
1247 [ + + ]: 1119 : if (type_val->special != ConstValSpecialLazy) {
1248 : 701 : return type_has_one_possible_value(g, type_val->data.x_type);
1249 : : }
1250 [ - + + - : 418 : switch (type_val->data.x_lazy->id) {
- ]
1251 : 0 : case LazyValueIdInvalid:
1252 : : case LazyValueIdAlignOf:
1253 : : case LazyValueIdSizeOf:
1254 : 0 : zig_unreachable();
1255 : 294 : case LazyValueIdSliceType: // it has the len field
1256 : : case LazyValueIdOptType: // it has the optional bit
1257 : : case LazyValueIdFnType:
1258 : 294 : return OnePossibleValueNo;
1259 : 124 : case LazyValueIdPtrType: {
1260 : : Error err;
1261 : : bool zero_bits;
1262 [ - + ]: 124 : if ((err = type_val_resolve_zero_bits(g, type_val, nullptr, nullptr, &zero_bits))) {
1263 : 0 : return OnePossibleValueInvalid;
1264 : : }
1265 [ - + ]: 124 : if (zero_bits) {
1266 : 0 : return OnePossibleValueYes;
1267 : : } else {
1268 : 124 : return OnePossibleValueNo;
1269 : : }
1270 : : }
1271 : 0 : case LazyValueIdErrUnionType: {
1272 : 0 : LazyValueErrUnionType *lazy_err_union_type =
1273 : : reinterpret_cast<LazyValueErrUnionType *>(type_val->data.x_lazy);
1274 [ # # # # ]: 0 : switch (type_val_resolve_has_one_possible_value(g, &lazy_err_union_type->err_set_type->value)) {
1275 : 0 : case OnePossibleValueInvalid:
1276 : 0 : return OnePossibleValueInvalid;
1277 : 0 : case OnePossibleValueNo:
1278 : 0 : return OnePossibleValueNo;
1279 : 0 : case OnePossibleValueYes:
1280 : 0 : return type_val_resolve_has_one_possible_value(g, &lazy_err_union_type->payload_type->value);
1281 : : }
1282 : : }
1283 : : }
1284 : 0 : zig_unreachable();
1285 : : }
1286 : :
1287 : 23800 : ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
1288 : 23800 : ConstExprValue *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type,
1289 : 23800 : nullptr, UndefBad);
1290 [ - + ]: 23800 : if (type_is_invalid(result->type))
1291 : 0 : return g->builtin_types.entry_invalid;
1292 : 23800 : src_assert(result->special == ConstValSpecialStatic, node);
1293 : 23800 : src_assert(result->data.x_type != nullptr, node);
1294 : 23800 : return result->data.x_type;
1295 : : }
1296 : :
1297 : 1923 : ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1298 : 1923 : ZigType *fn_type = new_type_table_entry(ZigTypeIdFn);
1299 : 1923 : buf_resize(&fn_type->name, 0);
1300 : 1923 : const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);
1301 : 1923 : buf_appendf(&fn_type->name, "%s", cc_str);
1302 : 1923 : buf_appendf(&fn_type->name, "fn(");
1303 : 1923 : size_t i = 0;
1304 [ + + ]: 3512 : for (; i < fn_type_id->next_param_index; i += 1) {
1305 [ + + ]: 1589 : const char *comma_str = (i == 0) ? "" : ",";
1306 : 1589 : buf_appendf(&fn_type->name, "%s%s", comma_str,
1307 : 1589 : buf_ptr(&fn_type_id->param_info[i].type->name));
1308 : : }
1309 [ + + ]: 4521 : for (; i < fn_type_id->param_count; i += 1) {
1310 [ + + ]: 2598 : const char *comma_str = (i == 0) ? "" : ",";
1311 : 2598 : buf_appendf(&fn_type->name, "%svar", comma_str);
1312 : : }
1313 : 1923 : buf_appendf(&fn_type->name, ")var");
1314 : :
1315 : 1923 : fn_type->data.fn.fn_type_id = *fn_type_id;
1316 : 1923 : fn_type->data.fn.is_generic = true;
1317 : 1923 : fn_type->abi_size = 0;
1318 : 1923 : fn_type->size_in_bits = 0;
1319 : 1923 : fn_type->abi_align = 0;
1320 : 1923 : return fn_type;
1321 : : }
1322 : :
1323 : 32615 : void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc) {
1324 : 32615 : assert(proto_node->type == NodeTypeFnProto);
1325 : 32615 : AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
1326 : :
1327 [ + + ]: 32615 : if (fn_proto->cc == CallingConventionUnspecified) {
1328 [ + + ][ + + ]: 32286 : bool extern_abi = fn_proto->is_extern || fn_proto->is_export;
1329 [ + + ]: 32286 : fn_type_id->cc = extern_abi ? CallingConventionC : CallingConventionUnspecified;
1330 : : } else {
1331 : 329 : fn_type_id->cc = fn_proto->cc;
1332 : : }
1333 : :
1334 : 32615 : fn_type_id->param_count = fn_proto->params.length;
1335 : 32615 : fn_type_id->param_info = allocate<FnTypeParamInfo>(param_count_alloc);
1336 : 32615 : fn_type_id->next_param_index = 0;
1337 : 32615 : fn_type_id->is_var_args = fn_proto->is_var_args;
1338 : 32615 : }
1339 : :
1340 : 91 : static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_t *result) {
1341 : 91 : ConstExprValue *align_result = analyze_const_value(g, scope, node, get_align_amt_type(g),
1342 : 91 : nullptr, UndefBad);
1343 [ - + ]: 91 : if (type_is_invalid(align_result->type))
1344 : 0 : return false;
1345 : :
1346 : 91 : uint32_t align_bytes = bigint_as_u32(&align_result->data.x_bigint);
1347 [ - + ]: 91 : if (align_bytes == 0) {
1348 : 0 : add_node_error(g, node, buf_sprintf("alignment must be >= 1"));
1349 : 0 : return false;
1350 : : }
1351 [ - + ]: 91 : if (!is_power_of_2(align_bytes)) {
1352 : 0 : add_node_error(g, node, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes));
1353 : 0 : return false;
1354 : : }
1355 : :
1356 : 91 : *result = align_bytes;
1357 : 91 : return true;
1358 : : }
1359 : :
1360 : 5 : static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **out_buffer) {
1361 : 5 : ZigType *ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
1362 : 5 : PtrLenUnknown, 0, 0, 0, false);
1363 : 5 : ZigType *str_type = get_slice_type(g, ptr_type);
1364 : 5 : ConstExprValue *result_val = analyze_const_value(g, scope, node, str_type, nullptr, UndefBad);
1365 [ - + ]: 5 : if (type_is_invalid(result_val->type))
1366 : 0 : return false;
1367 : :
1368 : 5 : ConstExprValue *ptr_field = &result_val->data.x_struct.fields[slice_ptr_index];
1369 : 5 : ConstExprValue *len_field = &result_val->data.x_struct.fields[slice_len_index];
1370 : :
1371 : 5 : assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);
1372 : 5 : ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;
1373 [ + - ]: 5 : if (array_val->data.x_array.special == ConstArraySpecialBuf) {
1374 : 5 : *out_buffer = array_val->data.x_array.data.s_buf;
1375 : 5 : return true;
1376 : : }
1377 : 0 : expand_undef_array(g, array_val);
1378 : 0 : size_t len = bigint_as_usize(&len_field->data.x_bigint);
1379 : 0 : Buf *result = buf_alloc();
1380 : 0 : buf_resize(result, len);
1381 [ # # ]: 0 : for (size_t i = 0; i < len; i += 1) {
1382 : 0 : size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i;
1383 : 0 : ConstExprValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index];
1384 [ # # ]: 0 : if (char_val->special == ConstValSpecialUndef) {
1385 : 0 : add_node_error(g, node, buf_sprintf("use of undefined value"));
1386 : 0 : return false;
1387 : : }
1388 : 0 : uint64_t big_c = bigint_as_u64(&char_val->data.x_bigint);
1389 : 0 : assert(big_c <= UINT8_MAX);
1390 : 0 : uint8_t c = (uint8_t)big_c;
1391 : 0 : buf_ptr(result)[i] = c;
1392 : : }
1393 : 0 : *out_buffer = result;
1394 : 0 : return true;
1395 : : }
1396 : :
1397 : 973 : static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType *type_entry,
1398 : : AstNode *source_node)
1399 : : {
1400 : : Error err;
1401 [ - - + + : 973 : switch (type_entry->id) {
+ - - +
- ]
1402 : 0 : case ZigTypeIdInvalid:
1403 : 0 : zig_unreachable();
1404 : 0 : case ZigTypeIdMetaType:
1405 : : case ZigTypeIdUnreachable:
1406 : : case ZigTypeIdComptimeFloat:
1407 : : case ZigTypeIdComptimeInt:
1408 : : case ZigTypeIdEnumLiteral:
1409 : : case ZigTypeIdUndefined:
1410 : : case ZigTypeIdNull:
1411 : : case ZigTypeIdErrorUnion:
1412 : : case ZigTypeIdErrorSet:
1413 : : case ZigTypeIdBoundFn:
1414 : : case ZigTypeIdArgTuple:
1415 : : case ZigTypeIdOpaque:
1416 : : case ZigTypeIdFnFrame:
1417 : : case ZigTypeIdAnyFrame:
1418 : 0 : add_node_error(g, source_node,
1419 : : buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
1420 : : buf_ptr(&type_entry->name)));
1421 : 0 : return ErrorSemanticAnalyzeFail;
1422 : 852 : case ZigTypeIdVoid:
1423 : : case ZigTypeIdBool:
1424 : : case ZigTypeIdInt:
1425 : : case ZigTypeIdFloat:
1426 : : case ZigTypeIdPointer:
1427 : : case ZigTypeIdFn:
1428 : : case ZigTypeIdVector:
1429 : 852 : return ErrorNone;
1430 : 64 : case ZigTypeIdArray: {
1431 : 64 : ZigType *elem_type = type_entry->data.array.child_type;
1432 [ - + ]: 64 : if ((err = emit_error_unless_type_allowed_in_packed_struct(g, elem_type, source_node)))
1433 : 0 : return err;
1434 : : // TODO revisit this when doing https://github.com/ziglang/zig/issues/1512
1435 [ + - ]: 64 : if (type_size(g, type_entry) * 8 == type_size_bits(g, type_entry))
1436 : 64 : return ErrorNone;
1437 : 0 : add_node_error(g, source_node,
1438 : : buf_sprintf("array of '%s' not allowed in packed struct due to padding bits",
1439 : : buf_ptr(&elem_type->name)));
1440 : 0 : return ErrorSemanticAnalyzeFail;
1441 : : }
1442 : 29 : case ZigTypeIdStruct:
1443 [ + - - ]: 29 : switch (type_entry->data.structure.layout) {
1444 : 29 : case ContainerLayoutPacked:
1445 : : case ContainerLayoutExtern:
1446 : 29 : return ErrorNone;
1447 : 0 : case ContainerLayoutAuto:
1448 : 0 : add_node_error(g, source_node,
1449 : : buf_sprintf("non-packed, non-extern struct '%s' not allowed in packed struct; no guaranteed in-memory representation",
1450 : : buf_ptr(&type_entry->name)));
1451 : 0 : return ErrorSemanticAnalyzeFail;
1452 : : }
1453 : 0 : zig_unreachable();
1454 : 0 : case ZigTypeIdUnion:
1455 [ # # # ]: 0 : switch (type_entry->data.unionation.layout) {
1456 : 0 : case ContainerLayoutPacked:
1457 : : case ContainerLayoutExtern:
1458 : 0 : return ErrorNone;
1459 : 0 : case ContainerLayoutAuto:
1460 : 0 : add_node_error(g, source_node,
1461 : : buf_sprintf("non-packed, non-extern union '%s' not allowed in packed struct; no guaranteed in-memory representation",
1462 : : buf_ptr(&type_entry->name)));
1463 : 0 : return ErrorSemanticAnalyzeFail;
1464 : : }
1465 : 0 : zig_unreachable();
1466 : 0 : case ZigTypeIdOptional:
1467 [ # # ]: 0 : if (get_codegen_ptr_type(type_entry) != nullptr) {
1468 : 0 : return ErrorNone;
1469 : : } else {
1470 : 0 : add_node_error(g, source_node,
1471 : : buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
1472 : : buf_ptr(&type_entry->name)));
1473 : 0 : return ErrorSemanticAnalyzeFail;
1474 : : }
1475 : 28 : case ZigTypeIdEnum: {
1476 : 28 : AstNode *decl_node = type_entry->data.enumeration.decl_node;
1477 [ + - ]: 28 : if (decl_node->data.container_decl.init_arg_expr != nullptr) {
1478 : 28 : return ErrorNone;
1479 : : }
1480 : 0 : ErrorMsg *msg = add_node_error(g, source_node,
1481 : : buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
1482 : 0 : buf_ptr(&type_entry->name)));
1483 : 0 : add_error_note(g, msg, decl_node,
1484 : : buf_sprintf("enum declaration does not specify an integer tag type"));
1485 : 0 : return ErrorSemanticAnalyzeFail;
1486 : : }
1487 : : }
1488 : 0 : zig_unreachable();
1489 : : }
1490 : :
1491 : 3299 : bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
1492 [ - - + + : 3299 : switch (type_entry->id) {
+ + + + +
+ + + +
- ]
1493 : 0 : case ZigTypeIdInvalid:
1494 : 0 : zig_unreachable();
1495 : 0 : case ZigTypeIdMetaType:
1496 : : case ZigTypeIdComptimeFloat:
1497 : : case ZigTypeIdComptimeInt:
1498 : : case ZigTypeIdEnumLiteral:
1499 : : case ZigTypeIdUndefined:
1500 : : case ZigTypeIdNull:
1501 : : case ZigTypeIdErrorUnion:
1502 : : case ZigTypeIdErrorSet:
1503 : : case ZigTypeIdBoundFn:
1504 : : case ZigTypeIdArgTuple:
1505 : : case ZigTypeIdVoid:
1506 : : case ZigTypeIdFnFrame:
1507 : : case ZigTypeIdAnyFrame:
1508 : 0 : return false;
1509 : 17 : case ZigTypeIdOpaque:
1510 : : case ZigTypeIdUnreachable:
1511 : : case ZigTypeIdBool:
1512 : 17 : return true;
1513 : 1995 : case ZigTypeIdInt:
1514 [ + - ]: 1995 : switch (type_entry->data.integral.bit_count) {
1515 : 1995 : case 8:
1516 : : case 16:
1517 : : case 32:
1518 : : case 64:
1519 : : case 128:
1520 : 1995 : return true;
1521 : 0 : default:
1522 : 0 : return false;
1523 : : }
1524 : 18 : case ZigTypeIdVector:
1525 : 18 : return type_allowed_in_extern(g, type_entry->data.vector.elem_type);
1526 : 604 : case ZigTypeIdFloat:
1527 : 604 : return true;
1528 : 93 : case ZigTypeIdArray:
1529 : 93 : return type_allowed_in_extern(g, type_entry->data.array.child_type);
1530 : 35 : case ZigTypeIdFn:
1531 [ + + ][ + - ]: 35 : return type_entry->data.fn.fn_type_id.cc == CallingConventionC ||
1532 : 35 : type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall;
1533 : 324 : case ZigTypeIdPointer:
1534 [ - + ]: 324 : if (type_size(g, type_entry) == 0)
1535 : 0 : return false;
1536 : 324 : return true;
1537 : 55 : case ZigTypeIdStruct:
1538 [ - + ][ # # ]: 55 : return type_entry->data.structure.layout == ContainerLayoutExtern || type_entry->data.structure.layout == ContainerLayoutPacked;
1539 : 127 : case ZigTypeIdOptional:
1540 : : {
1541 : 127 : ZigType *child_type = type_entry->data.maybe.child_type;
1542 [ + + ][ - + ]: 127 : if (child_type->id != ZigTypeIdPointer && child_type->id != ZigTypeIdFn) {
1543 : 0 : return false;
1544 : : }
1545 : 127 : return type_allowed_in_extern(g, child_type);
1546 : : }
1547 : 8 : case ZigTypeIdEnum:
1548 [ + - ][ + - ]: 8 : return type_entry->data.enumeration.layout == ContainerLayoutExtern || type_entry->data.enumeration.layout == ContainerLayoutPacked;
1549 : 23 : case ZigTypeIdUnion:
1550 [ - + ][ # # ]: 23 : return type_entry->data.unionation.layout == ContainerLayoutExtern || type_entry->data.unionation.layout == ContainerLayoutPacked;
1551 : : }
1552 : 0 : zig_unreachable();
1553 : : }
1554 : :
1555 : 2092 : ZigType *get_auto_err_set_type(CodeGen *g, ZigFn *fn_entry) {
1556 : 2092 : ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);
1557 : 2092 : buf_resize(&err_set_type->name, 0);
1558 : 2092 : buf_appendf(&err_set_type->name, "@typeOf(%s).ReturnType.ErrorSet", buf_ptr(&fn_entry->symbol_name));
1559 : 2092 : err_set_type->data.error_set.err_count = 0;
1560 : 2092 : err_set_type->data.error_set.errors = nullptr;
1561 : 2092 : err_set_type->data.error_set.infer_fn = fn_entry;
1562 : 2092 : err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits;
1563 : 2092 : err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align;
1564 : 2092 : err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size;
1565 : :
1566 : 2092 : return err_set_type;
1567 : : }
1568 : :
1569 : 14007 : static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope, ZigFn *fn_entry) {
1570 : 14007 : assert(proto_node->type == NodeTypeFnProto);
1571 : 14007 : AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
1572 : : Error err;
1573 : :
1574 : 14007 : FnTypeId fn_type_id = {0};
1575 : 14007 : init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length);
1576 : :
1577 [ + + ]: 23373 : for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) {
1578 : 11232 : AstNode *param_node = fn_proto->params.at(fn_type_id.next_param_index);
1579 : 11232 : assert(param_node->type == NodeTypeParamDecl);
1580 : :
1581 : 11232 : bool param_is_comptime = param_node->data.param_decl.is_comptime;
1582 : 11232 : bool param_is_var_args = param_node->data.param_decl.is_var_args;
1583 : :
1584 [ + + ]: 11232 : if (param_is_comptime) {
1585 [ - + ]: 1231 : if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
1586 : 0 : add_node_error(g, param_node,
1587 : : buf_sprintf("comptime parameter not allowed in function with calling convention '%s'",
1588 : : calling_convention_name(fn_type_id.cc)));
1589 : 0 : return g->builtin_types.entry_invalid;
1590 : : }
1591 [ + + ]: 1231 : if (param_node->data.param_decl.type != nullptr) {
1592 : 1223 : ZigType *type_entry = analyze_type_expr(g, child_scope, param_node->data.param_decl.type);
1593 [ - + ]: 1223 : if (type_is_invalid(type_entry)) {
1594 : 0 : return g->builtin_types.entry_invalid;
1595 : : }
1596 : 1223 : FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index];
1597 : 1223 : param_info->type = type_entry;
1598 : 1223 : param_info->is_noalias = param_node->data.param_decl.is_noalias;
1599 : 1223 : fn_type_id.next_param_index += 1;
1600 : : }
1601 : :
1602 : 1231 : return get_generic_fn_type(g, &fn_type_id);
1603 [ + + ]: 10001 : } else if (param_is_var_args) {
1604 [ + + ]: 88 : if (fn_type_id.cc == CallingConventionC) {
1605 : 4 : fn_type_id.param_count = fn_type_id.next_param_index;
1606 : 4 : continue;
1607 [ + - ]: 84 : } else if (calling_convention_allows_zig_types(fn_type_id.cc)) {
1608 : 84 : return get_generic_fn_type(g, &fn_type_id);
1609 : : } else {
1610 : 0 : add_node_error(g, param_node,
1611 : : buf_sprintf("var args not allowed in function with calling convention '%s'",
1612 : : calling_convention_name(fn_type_id.cc)));
1613 : 0 : return g->builtin_types.entry_invalid;
1614 : : }
1615 [ + + ]: 9913 : } else if (param_node->data.param_decl.var_token != nullptr) {
1616 [ - + ]: 551 : if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
1617 : 0 : add_node_error(g, param_node,
1618 : : buf_sprintf("parameter of type 'var' not allowed in function with calling convention '%s'",
1619 : : calling_convention_name(fn_type_id.cc)));
1620 : 0 : return g->builtin_types.entry_invalid;
1621 : : }
1622 : 551 : return get_generic_fn_type(g, &fn_type_id);
1623 : : }
1624 : :
1625 : 9362 : ZigType *type_entry = analyze_type_expr(g, child_scope, param_node->data.param_decl.type);
1626 [ - + ]: 9362 : if (type_is_invalid(type_entry)) {
1627 : 0 : return g->builtin_types.entry_invalid;
1628 : : }
1629 [ + + ]: 9362 : if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
1630 [ - + ]: 1074 : if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
1631 : 0 : return g->builtin_types.entry_invalid;
1632 [ - + ]: 1074 : if (!type_has_bits(type_entry)) {
1633 : 0 : add_node_error(g, param_node->data.param_decl.type,
1634 : : buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'",
1635 : : buf_ptr(&type_entry->name), calling_convention_name(fn_type_id.cc)));
1636 : 0 : return g->builtin_types.entry_invalid;
1637 : : }
1638 : : }
1639 : :
1640 [ + + ][ - + ]: 9362 : if (!calling_convention_allows_zig_types(fn_type_id.cc) && !type_allowed_in_extern(g, type_entry)) {
[ - + ]
1641 : 0 : add_node_error(g, param_node->data.param_decl.type,
1642 : : buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'",
1643 : : buf_ptr(&type_entry->name),
1644 : : calling_convention_name(fn_type_id.cc)));
1645 : 0 : return g->builtin_types.entry_invalid;
1646 : : }
1647 : :
1648 [ - - + - ]: 9362 : switch (type_entry->id) {
1649 : 0 : case ZigTypeIdInvalid:
1650 : 0 : zig_unreachable();
1651 : 0 : case ZigTypeIdUnreachable:
1652 : : case ZigTypeIdUndefined:
1653 : : case ZigTypeIdNull:
1654 : : case ZigTypeIdArgTuple:
1655 : : case ZigTypeIdOpaque:
1656 : 0 : add_node_error(g, param_node->data.param_decl.type,
1657 : : buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name)));
1658 : 0 : return g->builtin_types.entry_invalid;
1659 : 9362 : case ZigTypeIdComptimeFloat:
1660 : : case ZigTypeIdComptimeInt:
1661 : : case ZigTypeIdEnumLiteral:
1662 : : case ZigTypeIdBoundFn:
1663 : : case ZigTypeIdMetaType:
1664 : : case ZigTypeIdVoid:
1665 : : case ZigTypeIdBool:
1666 : : case ZigTypeIdInt:
1667 : : case ZigTypeIdFloat:
1668 : : case ZigTypeIdPointer:
1669 : : case ZigTypeIdArray:
1670 : : case ZigTypeIdStruct:
1671 : : case ZigTypeIdOptional:
1672 : : case ZigTypeIdErrorUnion:
1673 : : case ZigTypeIdErrorSet:
1674 : : case ZigTypeIdEnum:
1675 : : case ZigTypeIdUnion:
1676 : : case ZigTypeIdFn:
1677 : : case ZigTypeIdVector:
1678 : : case ZigTypeIdFnFrame:
1679 : : case ZigTypeIdAnyFrame:
1680 [ + - - - ]: 9362 : switch (type_requires_comptime(g, type_entry)) {
1681 : 9362 : case ReqCompTimeNo:
1682 : 9362 : break;
1683 : 0 : case ReqCompTimeYes:
1684 : 0 : add_node_error(g, param_node->data.param_decl.type,
1685 : : buf_sprintf("parameter of type '%s' must be declared comptime",
1686 : : buf_ptr(&type_entry->name)));
1687 : 0 : return g->builtin_types.entry_invalid;
1688 : 0 : case ReqCompTimeInvalid:
1689 : 0 : return g->builtin_types.entry_invalid;
1690 : : }
1691 : 9362 : break;
1692 : : }
1693 : 9362 : FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index];
1694 : 9362 : param_info->type = type_entry;
1695 : 9362 : param_info->is_noalias = param_node->data.param_decl.is_noalias;
1696 : : }
1697 : :
1698 [ + + ]: 12141 : if (fn_proto->align_expr != nullptr) {
1699 [ - + ]: 48 : if (!analyze_const_align(g, child_scope, fn_proto->align_expr, &fn_type_id.alignment)) {
1700 : 0 : return g->builtin_types.entry_invalid;
1701 : : }
1702 : : }
1703 : :
1704 [ - + ]: 12141 : if (fn_proto->return_var_token != nullptr) {
1705 [ # # ]: 0 : if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
1706 : 0 : add_node_error(g, fn_proto->return_type,
1707 : : buf_sprintf("return type 'var' not allowed in function with calling convention '%s'",
1708 : : calling_convention_name(fn_type_id.cc)));
1709 : 0 : return g->builtin_types.entry_invalid;
1710 : : }
1711 : 0 : add_node_error(g, proto_node,
1712 : : buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447"));
1713 : 0 : return g->builtin_types.entry_invalid;
1714 : : }
1715 : :
1716 : 12141 : ZigType *specified_return_type = analyze_type_expr(g, child_scope, fn_proto->return_type);
1717 [ - + ]: 12141 : if (type_is_invalid(specified_return_type)) {
1718 : 0 : fn_type_id.return_type = g->builtin_types.entry_invalid;
1719 : 0 : return g->builtin_types.entry_invalid;
1720 : : }
1721 : :
1722 [ + + ]: 12141 : if (fn_proto->auto_err_set) {
1723 : 960 : ZigType *inferred_err_set_type = get_auto_err_set_type(g, fn_entry);
1724 [ - + ]: 960 : if ((err = type_resolve(g, specified_return_type, ResolveStatusSizeKnown)))
1725 : 0 : return g->builtin_types.entry_invalid;
1726 : 960 : fn_type_id.return_type = get_error_union_type(g, inferred_err_set_type, specified_return_type);
1727 : : } else {
1728 : 11181 : fn_type_id.return_type = specified_return_type;
1729 : : }
1730 : :
1731 [ + + ][ + + ]: 12141 : if (!calling_convention_allows_zig_types(fn_type_id.cc) &&
[ + + ]
1732 : 4147 : fn_type_id.return_type->id != ZigTypeIdVoid)
1733 : : {
1734 [ - + ]: 606 : if ((err = type_resolve(g, fn_type_id.return_type, ResolveStatusSizeKnown)))
1735 : 0 : return g->builtin_types.entry_invalid;
1736 [ - + ]: 606 : if (!type_allowed_in_extern(g, fn_type_id.return_type)) {
1737 : 0 : add_node_error(g, fn_proto->return_type,
1738 : : buf_sprintf("return type '%s' not allowed in function with calling convention '%s'",
1739 : 0 : buf_ptr(&fn_type_id.return_type->name),
1740 : : calling_convention_name(fn_type_id.cc)));
1741 : 0 : return g->builtin_types.entry_invalid;
1742 : : }
1743 : : }
1744 : :
1745 [ - - + - ]: 12141 : switch (fn_type_id.return_type->id) {
1746 : 0 : case ZigTypeIdInvalid:
1747 : 0 : zig_unreachable();
1748 : :
1749 : 0 : case ZigTypeIdUndefined:
1750 : : case ZigTypeIdNull:
1751 : : case ZigTypeIdArgTuple:
1752 : : case ZigTypeIdOpaque:
1753 : 0 : add_node_error(g, fn_proto->return_type,
1754 : 0 : buf_sprintf("return type '%s' not allowed", buf_ptr(&fn_type_id.return_type->name)));
1755 : 0 : return g->builtin_types.entry_invalid;
1756 : :
1757 : 12141 : case ZigTypeIdComptimeFloat:
1758 : : case ZigTypeIdComptimeInt:
1759 : : case ZigTypeIdEnumLiteral:
1760 : : case ZigTypeIdBoundFn:
1761 : : case ZigTypeIdMetaType:
1762 : : case ZigTypeIdUnreachable:
1763 : : case ZigTypeIdVoid:
1764 : : case ZigTypeIdBool:
1765 : : case ZigTypeIdInt:
1766 : : case ZigTypeIdFloat:
1767 : : case ZigTypeIdPointer:
1768 : : case ZigTypeIdArray:
1769 : : case ZigTypeIdStruct:
1770 : : case ZigTypeIdOptional:
1771 : : case ZigTypeIdErrorUnion:
1772 : : case ZigTypeIdErrorSet:
1773 : : case ZigTypeIdEnum:
1774 : : case ZigTypeIdUnion:
1775 : : case ZigTypeIdFn:
1776 : : case ZigTypeIdVector:
1777 : : case ZigTypeIdFnFrame:
1778 : : case ZigTypeIdAnyFrame:
1779 [ - + + - ]: 12141 : switch (type_requires_comptime(g, fn_type_id.return_type)) {
1780 : 0 : case ReqCompTimeInvalid:
1781 : 0 : return g->builtin_types.entry_invalid;
1782 : 33 : case ReqCompTimeYes:
1783 : 33 : return get_generic_fn_type(g, &fn_type_id);
1784 : 12108 : case ReqCompTimeNo:
1785 : 12108 : break;
1786 : : }
1787 : 12108 : break;
1788 : : }
1789 : :
1790 : 14007 : return get_fn_type(g, &fn_type_id);
1791 : : }
1792 : :
1793 : 48855341 : bool type_is_invalid(ZigType *type_entry) {
1794 [ - + + + : 48855341 : switch (type_entry->id) {
+ ]
1795 : 0 : case ZigTypeIdInvalid:
1796 : 0 : return true;
1797 : 1871068 : case ZigTypeIdStruct:
1798 : 1871068 : return type_entry->data.structure.resolve_status == ResolveStatusInvalid;
1799 : 97234 : case ZigTypeIdUnion:
1800 : 97234 : return type_entry->data.unionation.resolve_status == ResolveStatusInvalid;
1801 : 1678811 : case ZigTypeIdEnum:
1802 : 1678811 : return type_entry->data.enumeration.resolve_status == ResolveStatusInvalid;
1803 : 45208228 : default:
1804 : 45208228 : return false;
1805 : : }
1806 : : zig_unreachable();
1807 : : }
1808 : :
1809 : : struct SrcField {
1810 : : const char *name;
1811 : : ZigType *ty;
1812 : : unsigned align;
1813 : : };
1814 : :
1815 : 1016 : static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fields[], size_t field_count,
1816 : : unsigned min_abi_align)
1817 : : {
1818 : 1016 : ZigType *struct_type = new_type_table_entry(ZigTypeIdStruct);
1819 : :
1820 : 1016 : buf_init_from_str(&struct_type->name, type_name);
1821 : :
1822 : 1016 : struct_type->data.structure.src_field_count = field_count;
1823 : 1016 : struct_type->data.structure.gen_field_count = 0;
1824 : 1016 : struct_type->data.structure.resolve_status = ResolveStatusSizeKnown;
1825 : 1016 : struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
1826 : 1016 : struct_type->data.structure.fields_by_name.init(field_count);
1827 : :
1828 : 1016 : size_t abi_align = min_abi_align;
1829 [ + + ]: 12024 : for (size_t i = 0; i < field_count; i += 1) {
1830 : 11008 : TypeStructField *field = &struct_type->data.structure.fields[i];
1831 : 11008 : field->name = buf_create_from_str(fields[i].name);
1832 : 11008 : field->type_entry = fields[i].ty;
1833 : 11008 : field->src_index = i;
1834 : 11008 : field->align = fields[i].align;
1835 : :
1836 [ + + ]: 11008 : if (type_has_bits(field->type_entry)) {
1837 : 9736 : assert(type_is_resolved(field->type_entry, ResolveStatusSizeKnown));
1838 : 9736 : unsigned field_abi_align = max(field->align, field->type_entry->abi_align);
1839 [ - + ]: 9736 : if (field_abi_align > abi_align) {
1840 : 9736 : abi_align = field_abi_align;
1841 : : }
1842 : : }
1843 : :
1844 : 11008 : auto prev_entry = struct_type->data.structure.fields_by_name.put_unique(field->name, field);
1845 : 11008 : assert(prev_entry == nullptr);
1846 : : }
1847 : :
1848 : 1016 : size_t next_offset = 0;
1849 [ + + ]: 12024 : for (size_t i = 0; i < field_count; i += 1) {
1850 : 11008 : TypeStructField *field = &struct_type->data.structure.fields[i];
1851 [ + + ]: 11008 : if (!type_has_bits(field->type_entry))
1852 : 1272 : continue;
1853 : :
1854 : 9736 : field->offset = next_offset;
1855 : :
1856 : : // find the next non-zero-byte field for offset calculations
1857 : 9736 : size_t next_src_field_index = i + 1;
1858 [ + + ]: 11008 : for (; next_src_field_index < field_count; next_src_field_index += 1) {
1859 [ + + ]: 9992 : if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry))
1860 : 8720 : break;
1861 : : }
1862 : : size_t next_abi_align;
1863 [ + + ]: 9736 : if (next_src_field_index == field_count) {
1864 : 1016 : next_abi_align = abi_align;
1865 : : } else {
1866 : 8720 : next_abi_align = max(fields[next_src_field_index].align,
1867 : 8720 : struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align);
1868 : : }
1869 : 9736 : next_offset = next_field_offset(next_offset, abi_align, field->type_entry->abi_size, next_abi_align);
1870 : : }
1871 : :
1872 : 1016 : struct_type->abi_align = abi_align;
1873 : 1016 : struct_type->abi_size = next_offset;
1874 : 1016 : struct_type->size_in_bits = next_offset * 8;
1875 : :
1876 : 1016 : return struct_type;
1877 : : }
1878 : :
1879 : 27503 : static size_t get_store_size_bytes(size_t size_in_bits) {
1880 : 27503 : return (size_in_bits + 7) / 8;
1881 : : }
1882 : :
1883 : 1689 : static size_t get_abi_align_bytes(size_t size_in_bits, size_t pointer_size_bytes) {
1884 : 1689 : size_t store_size_bytes = get_store_size_bytes(size_in_bits);
1885 [ + + ]: 1689 : if (store_size_bytes >= pointer_size_bytes)
1886 : 209 : return pointer_size_bytes;
1887 : 1480 : return round_to_next_power_of_2(store_size_bytes);
1888 : : }
1889 : :
1890 : 1689 : static size_t get_abi_size_bytes(size_t size_in_bits, size_t pointer_size_bytes) {
1891 : 1689 : size_t store_size_bytes = get_store_size_bytes(size_in_bits);
1892 : 1689 : size_t abi_align = get_abi_align_bytes(size_in_bits, pointer_size_bytes);
1893 : 1689 : return align_forward(store_size_bytes, abi_align);
1894 : : }
1895 : :
1896 : 71404 : ZigType *resolve_struct_field_type(CodeGen *g, TypeStructField *struct_field) {
1897 : : Error err;
1898 [ + + ]: 71404 : if (struct_field->type_entry == nullptr) {
1899 [ - + ]: 7051 : if ((err = ir_resolve_lazy(g, struct_field->decl_node, struct_field->type_val))) {
1900 : 0 : return nullptr;
1901 : : }
1902 : 7051 : struct_field->type_entry = struct_field->type_val->data.x_type;
1903 : : }
1904 : 71404 : return struct_field->type_entry;
1905 : : }
1906 : :
1907 : 140841 : static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
1908 : 140841 : assert(struct_type->id == ZigTypeIdStruct);
1909 : :
1910 : : Error err;
1911 : :
1912 [ - + ]: 140841 : if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
1913 : 0 : return ErrorSemanticAnalyzeFail;
1914 [ + + ]: 140841 : if (struct_type->data.structure.resolve_status >= ResolveStatusSizeKnown)
1915 : 135116 : return ErrorNone;
1916 : :
1917 [ - + ]: 5725 : if ((err = resolve_struct_alignment(g, struct_type)))
1918 : 0 : return err;
1919 : :
1920 : 5725 : AstNode *decl_node = struct_type->data.structure.decl_node;
1921 : :
1922 [ - + ]: 5725 : if (struct_type->data.structure.resolve_loop_flag_other) {
1923 [ # # ]: 0 : if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) {
1924 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1925 : 0 : add_node_error(g, decl_node,
1926 : : buf_sprintf("struct '%s' depends on itself", buf_ptr(&struct_type->name)));
1927 : : }
1928 : 0 : return ErrorSemanticAnalyzeFail;
1929 : : }
1930 : :
1931 [ + + ][ + - ]: 5725 : assert(struct_type->data.structure.fields || struct_type->data.structure.src_field_count == 0);
1932 : 5725 : assert(decl_node->type == NodeTypeContainerDecl);
1933 : :
1934 : 5725 : size_t field_count = struct_type->data.structure.src_field_count;
1935 : :
1936 : 5725 : bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked);
1937 : 5725 : struct_type->data.structure.resolve_loop_flag_other = true;
1938 : :
1939 [ + + ]: 5725 : uint32_t *host_int_bytes = packed ? allocate<uint32_t>(struct_type->data.structure.gen_field_count) : nullptr;
1940 : :
1941 : 5725 : size_t packed_bits_offset = 0;
1942 : 5725 : size_t next_offset = 0;
1943 : 5725 : size_t first_packed_bits_offset_misalign = SIZE_MAX;
1944 : 5725 : size_t gen_field_index = 0;
1945 : 5725 : size_t size_in_bits = 0;
1946 : 5725 : size_t abi_align = struct_type->abi_align;
1947 : :
1948 : : // Calculate offsets
1949 [ + + ]: 12776 : for (size_t i = 0; i < field_count; i += 1) {
1950 : 7051 : TypeStructField *field = &struct_type->data.structure.fields[i];
1951 [ + + ]: 7051 : if (field->gen_index == SIZE_MAX)
1952 : 417 : continue;
1953 : :
1954 : 6634 : field->gen_index = gen_field_index;
1955 : 6634 : field->offset = next_offset;
1956 : :
1957 [ + + ]: 6634 : if (packed) {
1958 : 909 : ZigType *field_type = resolve_struct_field_type(g, field);
1959 [ - + ]: 909 : if (field_type == nullptr) {
1960 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1961 : 0 : return err;
1962 : : }
1963 [ - + ]: 909 : if ((err = type_resolve(g, field->type_entry, ResolveStatusSizeKnown))) {
1964 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1965 : 0 : return err;
1966 : : }
1967 [ - + ]: 909 : if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field->type_entry, field->decl_node))) {
1968 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
1969 : 0 : return err;
1970 : : }
1971 : :
1972 : 909 : size_t field_size_in_bits = type_size_bits(g, field_type);
1973 : 909 : size_t next_packed_bits_offset = packed_bits_offset + field_size_in_bits;
1974 : :
1975 : 909 : size_in_bits += field_size_in_bits;
1976 : :
1977 [ + + ]: 909 : if (first_packed_bits_offset_misalign != SIZE_MAX) {
1978 : : // this field is not byte-aligned; it is part of the previous field with a bit offset
1979 : 206 : field->bit_offset_in_host = packed_bits_offset - first_packed_bits_offset_misalign;
1980 : :
1981 : 206 : size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign;
1982 : 206 : size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes);
1983 [ + + ]: 206 : if (full_abi_size * 8 == full_bit_count) {
1984 : : // next field recovers ABI alignment
1985 : 119 : host_int_bytes[gen_field_index] = full_abi_size;
1986 : 119 : gen_field_index += 1;
1987 : : // TODO: https://github.com/ziglang/zig/issues/1512
1988 : 119 : next_offset = next_field_offset(next_offset, abi_align, full_abi_size, 1);
1989 : 119 : size_in_bits = next_offset * 8;
1990 : :
1991 : 206 : first_packed_bits_offset_misalign = SIZE_MAX;
1992 : : }
1993 [ + + ]: 703 : } else if (get_abi_size_bytes(field_type->size_in_bits, g->pointer_size_bytes) * 8 != field_size_in_bits) {
1994 : 167 : first_packed_bits_offset_misalign = packed_bits_offset;
1995 : 167 : field->bit_offset_in_host = 0;
1996 : : } else {
1997 : : // This is a byte-aligned field (both start and end) in a packed struct.
1998 : 536 : host_int_bytes[gen_field_index] = field_type->size_in_bits / 8;
1999 : 536 : field->bit_offset_in_host = 0;
2000 : 536 : gen_field_index += 1;
2001 : : // TODO: https://github.com/ziglang/zig/issues/1512
2002 : 536 : next_offset = next_field_offset(next_offset, abi_align, field_type->size_in_bits / 8, 1);
2003 : 536 : size_in_bits = next_offset * 8;
2004 : : }
2005 : 909 : packed_bits_offset = next_packed_bits_offset;
2006 : : } else {
2007 : : size_t field_abi_size;
2008 : : size_t field_size_in_bits;
2009 [ - + ]: 5725 : if ((err = type_val_resolve_abi_size(g, field->decl_node, field->type_val,
2010 : 5725 : &field_abi_size, &field_size_in_bits)))
2011 : : {
2012 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2013 : 0 : return err;
2014 : : }
2015 : :
2016 : 5725 : gen_field_index += 1;
2017 : 5725 : size_t next_src_field_index = i + 1;
2018 [ + + ]: 5935 : for (; next_src_field_index < field_count; next_src_field_index += 1) {
2019 [ + + ]: 3647 : if (struct_type->data.structure.fields[next_src_field_index].gen_index != SIZE_MAX) {
2020 : 3437 : break;
2021 : : }
2022 : : }
2023 [ + + ]: 5725 : size_t next_align = (next_src_field_index == field_count) ?
2024 : 3437 : abi_align : struct_type->data.structure.fields[next_src_field_index].align;
2025 : 5725 : next_offset = next_field_offset(next_offset, abi_align, field_abi_size, next_align);
2026 : 5725 : size_in_bits = next_offset * 8;
2027 : : }
2028 : : }
2029 [ + + ]: 5725 : if (first_packed_bits_offset_misalign != SIZE_MAX) {
2030 : 48 : size_t full_bit_count = packed_bits_offset - first_packed_bits_offset_misalign;
2031 : 48 : size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes);
2032 : 48 : next_offset = next_field_offset(next_offset, abi_align, full_abi_size, abi_align);
2033 : 48 : host_int_bytes[gen_field_index] = full_abi_size;
2034 : 48 : gen_field_index += 1;
2035 : : }
2036 : :
2037 : 5725 : struct_type->abi_size = next_offset;
2038 : 5725 : struct_type->size_in_bits = size_in_bits;
2039 : 5725 : struct_type->data.structure.resolve_status = ResolveStatusSizeKnown;
2040 : 5725 : struct_type->data.structure.gen_field_count = (uint32_t)gen_field_index;
2041 : 5725 : struct_type->data.structure.resolve_loop_flag_other = false;
2042 : 5725 : struct_type->data.structure.host_int_bytes = host_int_bytes;
2043 : :
2044 : :
2045 : : // Resolve types for fields
2046 [ + + ]: 12776 : for (size_t i = 0; i < field_count; i += 1) {
2047 : 7051 : TypeStructField *field = &struct_type->data.structure.fields[i];
2048 : 7051 : ZigType *field_type = resolve_struct_field_type(g, field);
2049 [ - + ]: 7051 : if (field_type == nullptr) {
2050 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2051 : 0 : return err;
2052 : : }
2053 : :
2054 [ - + ]: 7051 : if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) {
2055 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2056 : 0 : return err;
2057 : : }
2058 : :
2059 [ + + - + ]: 8072 : if (struct_type->data.structure.layout == ContainerLayoutExtern &&
[ - + ]
2060 : 1021 : !type_allowed_in_extern(g, field_type))
2061 : : {
2062 : 0 : add_node_error(g, field->decl_node,
2063 : : buf_sprintf("extern structs cannot contain fields of type '%s'",
2064 : : buf_ptr(&field_type->name)));
2065 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2066 : 0 : return ErrorSemanticAnalyzeFail;
2067 : : }
2068 : : }
2069 : :
2070 : 5725 : return ErrorNone;
2071 : : }
2072 : :
2073 : 1940 : static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
2074 : 1940 : assert(union_type->id == ZigTypeIdUnion);
2075 : :
2076 : : Error err;
2077 : :
2078 [ - + ]: 1940 : if (union_type->data.unionation.resolve_status == ResolveStatusInvalid)
2079 : 0 : return ErrorSemanticAnalyzeFail;
2080 [ + + ]: 1940 : if (union_type->data.unionation.resolve_status >= ResolveStatusAlignmentKnown)
2081 : 1387 : return ErrorNone;
2082 [ - + ]: 553 : if ((err = resolve_union_zero_bits(g, union_type)))
2083 : 0 : return err;
2084 [ + + ]: 553 : if (union_type->data.unionation.resolve_status >= ResolveStatusAlignmentKnown)
2085 : 8 : return ErrorNone;
2086 : :
2087 : 545 : AstNode *decl_node = union_type->data.structure.decl_node;
2088 : :
2089 [ - + ]: 545 : if (union_type->data.unionation.resolve_loop_flag_other) {
2090 [ # # ]: 0 : if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {
2091 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2092 : 0 : add_node_error(g, decl_node,
2093 : : buf_sprintf("union '%s' depends on itself", buf_ptr(&union_type->name)));
2094 : : }
2095 : 0 : return ErrorSemanticAnalyzeFail;
2096 : : }
2097 : :
2098 : : // set temporary flag
2099 : 545 : union_type->data.unionation.resolve_loop_flag_other = true;
2100 : :
2101 : 545 : TypeUnionField *most_aligned_union_member = nullptr;
2102 : 545 : uint32_t field_count = union_type->data.unionation.src_field_count;
2103 : 545 : bool packed = union_type->data.unionation.layout == ContainerLayoutPacked;
2104 : :
2105 [ + + ]: 2869 : for (uint32_t i = 0; i < field_count; i += 1) {
2106 : 2324 : TypeUnionField *field = &union_type->data.unionation.fields[i];
2107 [ + + ]: 2324 : if (field->gen_index == UINT32_MAX)
2108 : 1141 : continue;
2109 : :
2110 : 1183 : AstNode *align_expr = field->decl_node->data.struct_field.align_expr;
2111 [ - + ]: 1183 : if (align_expr != nullptr) {
2112 [ # # ]: 0 : if (!analyze_const_align(g, &union_type->data.unionation.decls_scope->base, align_expr,
2113 : : &field->align))
2114 : : {
2115 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2116 : 0 : return err;
2117 : : }
2118 : 0 : add_node_error(g, field->decl_node,
2119 : : buf_create_from_str("TODO implement field alignment syntax for unions. https://github.com/ziglang/zig/issues/3125"));
2120 [ + + ]: 1183 : } else if (packed) {
2121 : 32 : field->align = 1;
2122 [ - + ]: 1151 : } else if (field->type_entry != nullptr) {
2123 [ # # ]: 0 : if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) {
2124 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2125 : 0 : return err;
2126 : : }
2127 : 0 : field->align = field->type_entry->abi_align;
2128 : : } else {
2129 [ - + ]: 1151 : if ((err = type_val_resolve_abi_align(g, field->type_val, &field->align))) {
2130 [ # # ]: 0 : if (g->trace_err != nullptr) {
2131 : 0 : g->trace_err = add_error_note(g, g->trace_err, field->decl_node,
2132 : : buf_create_from_str("while checking this field"));
2133 : : }
2134 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2135 : 0 : return err;
2136 : : }
2137 [ - + ]: 1151 : if (union_type->data.unionation.resolve_status == ResolveStatusInvalid)
2138 : 0 : return ErrorSemanticAnalyzeFail;
2139 : : }
2140 : :
2141 [ + + ][ + + ]: 1183 : if (most_aligned_union_member == nullptr || field->align > most_aligned_union_member->align) {
2142 : 610 : most_aligned_union_member = field;
2143 : : }
2144 : : }
2145 : :
2146 : : // unset temporary flag
2147 : 545 : union_type->data.unionation.resolve_loop_flag_other = false;
2148 : 545 : union_type->data.unionation.resolve_status = ResolveStatusAlignmentKnown;
2149 : 545 : union_type->data.unionation.most_aligned_union_member = most_aligned_union_member;
2150 : :
2151 : 545 : ZigType *tag_type = union_type->data.unionation.tag_type;
2152 [ + + ][ + + ]: 545 : if (tag_type != nullptr && type_has_bits(tag_type)) {
[ + + ]
2153 [ - + ]: 401 : if ((err = type_resolve(g, tag_type, ResolveStatusAlignmentKnown))) {
2154 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2155 : 0 : return ErrorSemanticAnalyzeFail;
2156 : : }
2157 [ + + ]: 401 : if (most_aligned_union_member == nullptr) {
2158 : 24 : union_type->abi_align = tag_type->abi_align;
2159 : 24 : union_type->data.unionation.gen_tag_index = SIZE_MAX;
2160 : 24 : union_type->data.unionation.gen_union_index = SIZE_MAX;
2161 [ - + ]: 377 : } else if (tag_type->abi_align > most_aligned_union_member->align) {
2162 : 0 : union_type->abi_align = tag_type->abi_align;
2163 : 0 : union_type->data.unionation.gen_tag_index = 0;
2164 : 0 : union_type->data.unionation.gen_union_index = 1;
2165 : : } else {
2166 : 377 : union_type->abi_align = most_aligned_union_member->align;
2167 : 377 : union_type->data.unionation.gen_union_index = 0;
2168 : 401 : union_type->data.unionation.gen_tag_index = 1;
2169 : : }
2170 : : } else {
2171 : 144 : assert(most_aligned_union_member != nullptr);
2172 : 144 : union_type->abi_align = most_aligned_union_member->align;
2173 : 144 : union_type->data.unionation.gen_union_index = SIZE_MAX;
2174 : 144 : union_type->data.unionation.gen_tag_index = SIZE_MAX;
2175 : : }
2176 : :
2177 : 545 : return ErrorNone;
2178 : : }
2179 : :
2180 : 5954 : ZigType *resolve_union_field_type(CodeGen *g, TypeUnionField *union_field) {
2181 : : Error err;
2182 [ + + ]: 5954 : if (union_field->type_entry == nullptr) {
2183 [ - + ]: 1614 : if ((err = ir_resolve_lazy(g, union_field->decl_node, union_field->type_val))) {
2184 : 0 : return nullptr;
2185 : : }
2186 : 1614 : union_field->type_entry = union_field->type_val->data.x_type;
2187 : : }
2188 : 5954 : return union_field->type_entry;
2189 : : }
2190 : :
2191 : 18466 : static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
2192 : 18466 : assert(union_type->id == ZigTypeIdUnion);
2193 : :
2194 : : Error err;
2195 : :
2196 [ - + ]: 18466 : if (union_type->data.unionation.resolve_status == ResolveStatusInvalid)
2197 : 0 : return ErrorSemanticAnalyzeFail;
2198 [ + + ]: 18466 : if (union_type->data.unionation.resolve_status >= ResolveStatusSizeKnown)
2199 : 17913 : return ErrorNone;
2200 : :
2201 [ - + ]: 553 : if ((err = resolve_union_alignment(g, union_type)))
2202 : 0 : return err;
2203 : :
2204 : 553 : AstNode *decl_node = union_type->data.unionation.decl_node;
2205 : :
2206 : :
2207 : 553 : assert(decl_node->type == NodeTypeContainerDecl);
2208 : :
2209 : 553 : uint32_t field_count = union_type->data.unionation.src_field_count;
2210 : 553 : TypeUnionField *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member;
2211 : :
2212 : 553 : assert(union_type->data.unionation.fields);
2213 : :
2214 : 553 : size_t union_abi_size = 0;
2215 : 553 : size_t union_size_in_bits = 0;
2216 : :
2217 [ - + ]: 553 : if (union_type->data.unionation.resolve_loop_flag_other) {
2218 [ # # ]: 0 : if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {
2219 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2220 : 0 : add_node_error(g, decl_node,
2221 : : buf_sprintf("union '%s' depends on itself", buf_ptr(&union_type->name)));
2222 : : }
2223 : 0 : return ErrorSemanticAnalyzeFail;
2224 : : }
2225 : :
2226 : : // set temporary flag
2227 : 553 : union_type->data.unionation.resolve_loop_flag_other = true;
2228 : :
2229 [ + + ]: 2893 : for (uint32_t i = 0; i < field_count; i += 1) {
2230 : 2340 : TypeUnionField *union_field = &union_type->data.unionation.fields[i];
2231 : 2340 : ZigType *field_type = resolve_union_field_type(g, union_field);
2232 [ - + ]: 2340 : if (field_type == nullptr) {
2233 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2234 : 0 : return ErrorSemanticAnalyzeFail;
2235 : : }
2236 : :
2237 [ - + ]: 2340 : if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) {
2238 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2239 : 0 : return ErrorSemanticAnalyzeFail;
2240 : : }
2241 : :
2242 [ - + ]: 2340 : if (type_is_invalid(union_type))
2243 : 0 : return ErrorSemanticAnalyzeFail;
2244 : :
2245 [ + + ]: 2340 : if (!type_has_bits(field_type))
2246 : 1172 : continue;
2247 : :
2248 : 1168 : union_abi_size = max(union_abi_size, field_type->abi_size);
2249 : 1168 : union_size_in_bits = max(union_size_in_bits, field_type->size_in_bits);
2250 : : }
2251 : :
2252 : : // The union itself for now has to be treated as being independently aligned.
2253 : : // See https://github.com/ziglang/zig/issues/2166.
2254 [ + + ]: 553 : if (most_aligned_union_member != nullptr) {
2255 : 521 : union_abi_size = align_forward(union_abi_size, most_aligned_union_member->align);
2256 : : }
2257 : :
2258 : : // unset temporary flag
2259 : 553 : union_type->data.unionation.resolve_loop_flag_other = false;
2260 : 553 : union_type->data.unionation.resolve_status = ResolveStatusSizeKnown;
2261 : 553 : union_type->data.unionation.union_abi_size = union_abi_size;
2262 : :
2263 : 553 : ZigType *tag_type = union_type->data.unionation.tag_type;
2264 [ + + ][ + + ]: 553 : if (tag_type != nullptr && type_has_bits(tag_type)) {
[ + + ]
2265 [ - + ]: 409 : if ((err = type_resolve(g, tag_type, ResolveStatusSizeKnown))) {
2266 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2267 : 0 : return ErrorSemanticAnalyzeFail;
2268 : : }
2269 [ + + ]: 409 : if (most_aligned_union_member == nullptr) {
2270 : 32 : union_type->abi_size = tag_type->abi_size;
2271 : 32 : union_type->size_in_bits = tag_type->size_in_bits;
2272 : : } else {
2273 : : size_t field_sizes[2];
2274 : : size_t field_aligns[2];
2275 : 377 : field_sizes[union_type->data.unionation.gen_tag_index] = tag_type->abi_size;
2276 : 377 : field_aligns[union_type->data.unionation.gen_tag_index] = tag_type->abi_align;
2277 : 377 : field_sizes[union_type->data.unionation.gen_union_index] = union_abi_size;
2278 : 377 : field_aligns[union_type->data.unionation.gen_union_index] = most_aligned_union_member->align;
2279 : 377 : size_t field2_offset = next_field_offset(0, union_type->abi_align, field_sizes[0], field_aligns[1]);
2280 : 377 : union_type->abi_size = next_field_offset(field2_offset, union_type->abi_align, field_sizes[1], union_type->abi_align);
2281 : 409 : union_type->size_in_bits = union_type->abi_size * 8;
2282 : : }
2283 : : } else {
2284 : 144 : union_type->abi_size = union_abi_size;
2285 : 144 : union_type->size_in_bits = union_size_in_bits;
2286 : : }
2287 : :
2288 : 553 : return ErrorNone;
2289 : : }
2290 : :
2291 : 0 : static bool type_is_valid_extern_enum_tag(CodeGen *g, ZigType *ty) {
2292 : : // Only integer types are allowed by the C ABI
2293 [ # # ]: 0 : if(ty->id != ZigTypeIdInt)
2294 : 0 : return false;
2295 : :
2296 : : // According to the ANSI C standard the enumeration type should be either a
2297 : : // signed char, a signed integer or an unsigned one. But GCC/Clang allow
2298 : : // other integral types as a compiler extension so let's accomodate them
2299 : : // aswell.
2300 : 0 : return type_allowed_in_extern(g, ty);
2301 : : }
2302 : :
2303 : 436790 : static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
2304 : 436790 : assert(enum_type->id == ZigTypeIdEnum);
2305 : :
2306 [ - + ]: 436790 : if (enum_type->data.enumeration.resolve_status == ResolveStatusInvalid)
2307 : 0 : return ErrorSemanticAnalyzeFail;
2308 [ + + ]: 436790 : if (enum_type->data.enumeration.resolve_status >= ResolveStatusZeroBitsKnown)
2309 : 435681 : return ErrorNone;
2310 : :
2311 : 1109 : AstNode *decl_node = enum_type->data.enumeration.decl_node;
2312 : 1109 : assert(decl_node->type == NodeTypeContainerDecl);
2313 : :
2314 [ - + ]: 1109 : if (enum_type->data.enumeration.resolve_loop_flag) {
2315 [ # # ]: 0 : if (enum_type->data.enumeration.resolve_status != ResolveStatusInvalid) {
2316 : 0 : enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2317 : 0 : add_node_error(g, decl_node,
2318 : : buf_sprintf("enum '%s' depends on itself",
2319 : : buf_ptr(&enum_type->name)));
2320 : : }
2321 : 0 : return ErrorSemanticAnalyzeFail;
2322 : : }
2323 : :
2324 : 1109 : enum_type->data.enumeration.resolve_loop_flag = true;
2325 : :
2326 : 1109 : assert(!enum_type->data.enumeration.fields);
2327 : 1109 : uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length;
2328 [ - + ]: 1109 : if (field_count == 0) {
2329 : 0 : add_node_error(g, decl_node, buf_sprintf("enums must have 1 or more fields"));
2330 : :
2331 : 0 : enum_type->data.enumeration.src_field_count = field_count;
2332 : 0 : enum_type->data.enumeration.fields = nullptr;
2333 : 0 : enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2334 : 0 : return ErrorSemanticAnalyzeFail;
2335 : : }
2336 : :
2337 : 1109 : enum_type->data.enumeration.src_field_count = field_count;
2338 : 1109 : enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
2339 : 1109 : enum_type->data.enumeration.fields_by_name.init(field_count);
2340 : :
2341 : 1109 : Scope *scope = &enum_type->data.enumeration.decls_scope->base;
2342 : :
2343 : 1109 : HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};
2344 : 1109 : occupied_tag_values.init(field_count);
2345 : :
2346 : : ZigType *tag_int_type;
2347 [ + + ]: 1109 : if (enum_type->data.enumeration.layout == ContainerLayoutExtern) {
2348 : 24 : tag_int_type = get_c_int_type(g, CIntTypeInt);
2349 [ + + ][ + + ]: 1085 : } else if (enum_type->data.enumeration.layout == ContainerLayoutAuto && field_count == 1) {
2350 : 72 : tag_int_type = g->builtin_types.entry_num_lit_int;
2351 : : } else {
2352 : 1013 : tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
2353 : : }
2354 : :
2355 : 1109 : enum_type->size_in_bits = tag_int_type->size_in_bits;
2356 : 1109 : enum_type->abi_size = tag_int_type->abi_size;
2357 : 1109 : enum_type->abi_align = tag_int_type->abi_align;
2358 : :
2359 [ + + ]: 1109 : if (decl_node->data.container_decl.init_arg_expr != nullptr) {
2360 : 112 : ZigType *wanted_tag_int_type = analyze_type_expr(g, scope, decl_node->data.container_decl.init_arg_expr);
2361 [ - + ]: 112 : if (type_is_invalid(wanted_tag_int_type)) {
2362 : 0 : enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2363 [ - + ]: 112 : } else if (wanted_tag_int_type->id != ZigTypeIdInt) {
2364 : 0 : enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2365 : 0 : add_node_error(g, decl_node->data.container_decl.init_arg_expr,
2366 : : buf_sprintf("expected integer, found '%s'", buf_ptr(&wanted_tag_int_type->name)));
2367 [ - + # # ]: 112 : } else if (enum_type->data.enumeration.layout == ContainerLayoutExtern &&
[ - + ]
2368 : 0 : !type_is_valid_extern_enum_tag(g, wanted_tag_int_type)) {
2369 : 0 : enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2370 : 0 : ErrorMsg *msg = add_node_error(g, decl_node->data.container_decl.init_arg_expr,
2371 : : buf_sprintf("'%s' is not a valid tag type for an extern enum",
2372 : 0 : buf_ptr(&wanted_tag_int_type->name)));
2373 : 0 : add_error_note(g, msg, decl_node->data.container_decl.init_arg_expr,
2374 : : buf_sprintf("any integral type of size 8, 16, 32, 64 or 128 bit is valid"));
2375 : : } else {
2376 : 112 : tag_int_type = wanted_tag_int_type;
2377 : : }
2378 : : }
2379 : :
2380 : 1109 : enum_type->data.enumeration.tag_int_type = tag_int_type;
2381 : 1109 : enum_type->size_in_bits = tag_int_type->size_in_bits;
2382 : 1109 : enum_type->abi_size = tag_int_type->abi_size;
2383 : 1109 : enum_type->abi_align = tag_int_type->abi_align;
2384 : :
2385 : : BigInt bi_one;
2386 : 1109 : bigint_init_unsigned(&bi_one, 1);
2387 : :
2388 : 1109 : TypeEnumField *last_enum_field = nullptr;
2389 : :
2390 [ + + ]: 12141 : for (uint32_t field_i = 0; field_i < field_count; field_i += 1) {
2391 : 11032 : AstNode *field_node = decl_node->data.container_decl.fields.at(field_i);
2392 : 11032 : TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i];
2393 : 11032 : type_enum_field->name = field_node->data.struct_field.name;
2394 : 11032 : type_enum_field->decl_index = field_i;
2395 : 11032 : type_enum_field->decl_node = field_node;
2396 : :
2397 [ - + ]: 11032 : if (field_node->data.struct_field.type != nullptr) {
2398 : 0 : ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.type,
2399 : 0 : buf_sprintf("structs and unions, not enums, support field types"));
2400 : 0 : add_error_note(g, msg, decl_node,
2401 : : buf_sprintf("consider 'union(enum)' here"));
2402 [ - + ]: 11032 : } else if (field_node->data.struct_field.align_expr != nullptr) {
2403 : 0 : ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.align_expr,
2404 : 0 : buf_sprintf("structs and unions, not enums, support field alignment"));
2405 : 0 : add_error_note(g, msg, decl_node,
2406 : : buf_sprintf("consider 'union(enum)' here"));
2407 : : }
2408 : :
2409 : 11032 : auto field_entry = enum_type->data.enumeration.fields_by_name.put_unique(type_enum_field->name, type_enum_field);
2410 [ - + ]: 11032 : if (field_entry != nullptr) {
2411 : 0 : ErrorMsg *msg = add_node_error(g, field_node,
2412 : 0 : buf_sprintf("duplicate enum field: '%s'", buf_ptr(type_enum_field->name)));
2413 : 0 : add_error_note(g, msg, field_entry->value->decl_node, buf_sprintf("other field here"));
2414 : 0 : enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2415 : 0 : continue;
2416 : : }
2417 : :
2418 : 11032 : AstNode *tag_value = field_node->data.struct_field.value;
2419 : :
2420 [ + + ]: 11032 : if (tag_value != nullptr) {
2421 : : // A user-specified value is available
2422 : : ConstExprValue *result = analyze_const_value(g, scope, tag_value, tag_int_type,
2423 : 608 : nullptr, UndefBad);
2424 [ - + ]: 608 : if (type_is_invalid(result->type)) {
2425 : 0 : enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2426 : 0 : continue;
2427 : : }
2428 : :
2429 : 608 : assert(result->special != ConstValSpecialRuntime);
2430 [ + - ][ + + ]: 608 : assert(result->type->id == ZigTypeIdInt || result->type->id == ZigTypeIdComptimeInt);
2431 : :
2432 : 608 : bigint_init_bigint(&type_enum_field->value, &result->data.x_bigint);
2433 : : } else {
2434 : : // No value was explicitly specified: allocate the last value + 1
2435 : : // or, if this is the first element, zero
2436 [ + + ]: 10424 : if (last_enum_field != nullptr) {
2437 : 9395 : bigint_add(&type_enum_field->value, &last_enum_field->value, &bi_one);
2438 : : } else {
2439 : 1029 : bigint_init_unsigned(&type_enum_field->value, 0);
2440 : : }
2441 : :
2442 : : // Make sure we can represent this number with tag_int_type
2443 [ - + ]: 10424 : if (!bigint_fits_in_bits(&type_enum_field->value,
2444 : : tag_int_type->size_in_bits,
2445 : 10424 : tag_int_type->data.integral.is_signed)) {
2446 : 0 : enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2447 : :
2448 : 0 : Buf *val_buf = buf_alloc();
2449 : 0 : bigint_append_buf(val_buf, &type_enum_field->value, 10);
2450 : 0 : add_node_error(g, field_node,
2451 : : buf_sprintf("enumeration value %s too large for type '%s'",
2452 : : buf_ptr(val_buf), buf_ptr(&tag_int_type->name)));
2453 : :
2454 : 0 : break;
2455 : : }
2456 : : }
2457 : :
2458 : : // Make sure the value is unique
2459 : 11032 : auto entry = occupied_tag_values.put_unique(type_enum_field->value, field_node);
2460 [ - + ]: 11032 : if (entry != nullptr) {
2461 : 0 : enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
2462 : :
2463 : 0 : Buf *val_buf = buf_alloc();
2464 : 0 : bigint_append_buf(val_buf, &type_enum_field->value, 10);
2465 : :
2466 : 0 : ErrorMsg *msg = add_node_error(g, field_node,
2467 : 0 : buf_sprintf("enum tag value %s already taken", buf_ptr(val_buf)));
2468 : 0 : add_error_note(g, msg, entry->value,
2469 : : buf_sprintf("other occurrence here"));
2470 : : }
2471 : :
2472 : 11032 : last_enum_field = type_enum_field;
2473 : : }
2474 : :
2475 [ - + ]: 1109 : if (enum_type->data.enumeration.resolve_status == ResolveStatusInvalid)
2476 : 0 : return ErrorSemanticAnalyzeFail;
2477 : :
2478 : 1109 : enum_type->data.enumeration.resolve_loop_flag = false;
2479 : 1109 : enum_type->data.enumeration.resolve_status = ResolveStatusSizeKnown;
2480 : :
2481 : 436790 : return ErrorNone;
2482 : : }
2483 : :
2484 : 321827 : static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2485 : 321827 : assert(struct_type->id == ZigTypeIdStruct);
2486 : :
2487 : : Error err;
2488 : :
2489 [ - + ]: 321827 : if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
2490 : 0 : return ErrorSemanticAnalyzeFail;
2491 [ + + ]: 321827 : if (struct_type->data.structure.resolve_status >= ResolveStatusZeroBitsKnown)
2492 : 316102 : return ErrorNone;
2493 : :
2494 : 5725 : AstNode *decl_node = struct_type->data.structure.decl_node;
2495 : 5725 : assert(decl_node->type == NodeTypeContainerDecl);
2496 : :
2497 [ - + ]: 5725 : if (struct_type->data.structure.resolve_loop_flag_zero_bits) {
2498 [ # # ]: 0 : if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) {
2499 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2500 : 0 : add_node_error(g, decl_node,
2501 : : buf_sprintf("struct '%s' depends on itself",
2502 : : buf_ptr(&struct_type->name)));
2503 : : }
2504 : 0 : return ErrorSemanticAnalyzeFail;
2505 : : }
2506 : :
2507 : 5725 : struct_type->data.structure.resolve_loop_flag_zero_bits = true;
2508 : :
2509 : 5725 : assert(!struct_type->data.structure.fields);
2510 : 5725 : size_t field_count = decl_node->data.container_decl.fields.length;
2511 : 5725 : struct_type->data.structure.src_field_count = (uint32_t)field_count;
2512 : 5725 : struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
2513 : 5725 : struct_type->data.structure.fields_by_name.init(field_count);
2514 : :
2515 : 5725 : Scope *scope = &struct_type->data.structure.decls_scope->base;
2516 : :
2517 : 5725 : size_t gen_field_index = 0;
2518 [ + + ]: 12776 : for (size_t i = 0; i < field_count; i += 1) {
2519 : 7051 : AstNode *field_node = decl_node->data.container_decl.fields.at(i);
2520 : 7051 : TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
2521 : 7051 : type_struct_field->name = field_node->data.struct_field.name;
2522 : 7051 : type_struct_field->decl_node = field_node;
2523 : :
2524 [ - + ]: 7051 : if (field_node->data.struct_field.type == nullptr) {
2525 : 0 : add_node_error(g, field_node, buf_sprintf("struct field missing type"));
2526 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2527 : 0 : return ErrorSemanticAnalyzeFail;
2528 : : }
2529 : :
2530 : 7051 : auto field_entry = struct_type->data.structure.fields_by_name.put_unique(type_struct_field->name, type_struct_field);
2531 [ - + ]: 7051 : if (field_entry != nullptr) {
2532 : 0 : ErrorMsg *msg = add_node_error(g, field_node,
2533 : 0 : buf_sprintf("duplicate struct field: '%s'", buf_ptr(type_struct_field->name)));
2534 : 0 : add_error_note(g, msg, field_entry->value->decl_node, buf_sprintf("other field here"));
2535 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2536 : 0 : return ErrorSemanticAnalyzeFail;
2537 : : }
2538 : :
2539 : 7051 : ConstExprValue *field_type_val = analyze_const_value(g, scope,
2540 : 7051 : field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef);
2541 [ - + ]: 7051 : if (type_is_invalid(field_type_val->type)) {
2542 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2543 : 0 : return ErrorSemanticAnalyzeFail;
2544 : : }
2545 : 7051 : assert(field_type_val->special != ConstValSpecialRuntime);
2546 : 7051 : type_struct_field->type_val = field_type_val;
2547 [ - + ]: 7051 : if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
2548 : 0 : return ErrorSemanticAnalyzeFail;
2549 : :
2550 : : bool field_is_opaque_type;
2551 [ - + ]: 7051 : if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) {
2552 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2553 : 0 : return ErrorSemanticAnalyzeFail;
2554 : : }
2555 [ - + ]: 7051 : if (field_is_opaque_type) {
2556 : 0 : add_node_error(g, field_node->data.struct_field.type,
2557 : : buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in structs"));
2558 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2559 : 0 : return ErrorSemanticAnalyzeFail;
2560 : : }
2561 : :
2562 : 7051 : type_struct_field->src_index = i;
2563 : 7051 : type_struct_field->gen_index = SIZE_MAX;
2564 : :
2565 [ + - + - ]: 7051 : switch (type_val_resolve_requires_comptime(g, field_type_val)) {
2566 : 504 : case ReqCompTimeYes:
2567 : 504 : struct_type->data.structure.requires_comptime = true;
2568 : 504 : break;
2569 : 0 : case ReqCompTimeInvalid:
2570 [ # # ]: 0 : if (g->trace_err != nullptr) {
2571 : 0 : g->trace_err = add_error_note(g, g->trace_err, field_node,
2572 : : buf_create_from_str("while checking this field"));
2573 : : }
2574 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2575 : 0 : return ErrorSemanticAnalyzeFail;
2576 : 6547 : case ReqCompTimeNo:
2577 : 6547 : break;
2578 : : }
2579 : :
2580 : : bool field_is_zero_bits;
2581 [ - + ]: 7051 : if ((err = type_val_resolve_zero_bits(g, field_type_val, struct_type, nullptr, &field_is_zero_bits))) {
2582 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2583 : 0 : return ErrorSemanticAnalyzeFail;
2584 : : }
2585 [ + + ]: 7051 : if (field_is_zero_bits)
2586 : 417 : continue;
2587 : :
2588 : 6634 : type_struct_field->gen_index = gen_field_index;
2589 : 6634 : gen_field_index += 1;
2590 : : }
2591 : :
2592 : 5725 : struct_type->data.structure.resolve_loop_flag_zero_bits = false;
2593 : 5725 : struct_type->data.structure.gen_field_count = (uint32_t)gen_field_index;
2594 [ + + ]: 5725 : if (gen_field_index != 0) {
2595 : 2573 : struct_type->abi_size = SIZE_MAX;
2596 : 2573 : struct_type->size_in_bits = SIZE_MAX;
2597 : : }
2598 : :
2599 [ - + ]: 5725 : if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
2600 : 0 : return ErrorSemanticAnalyzeFail;
2601 : :
2602 : 5725 : struct_type->data.structure.resolve_status = ResolveStatusZeroBitsKnown;
2603 : 5725 : return ErrorNone;
2604 : : }
2605 : :
2606 : 106250 : static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
2607 : 106250 : assert(struct_type->id == ZigTypeIdStruct);
2608 : :
2609 : : Error err;
2610 : :
2611 [ - + ]: 106250 : if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
2612 : 0 : return ErrorSemanticAnalyzeFail;
2613 [ + + ]: 106250 : if (struct_type->data.structure.resolve_status >= ResolveStatusAlignmentKnown)
2614 : 100525 : return ErrorNone;
2615 [ - + ]: 5725 : if ((err = resolve_struct_zero_bits(g, struct_type)))
2616 : 0 : return err;
2617 [ - + ]: 5725 : if (struct_type->data.structure.resolve_status >= ResolveStatusAlignmentKnown)
2618 : 0 : return ErrorNone;
2619 : :
2620 : 5725 : AstNode *decl_node = struct_type->data.structure.decl_node;
2621 : :
2622 [ - + ]: 5725 : if (struct_type->data.structure.resolve_loop_flag_other) {
2623 [ # # ]: 0 : if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) {
2624 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2625 : 0 : add_node_error(g, decl_node,
2626 : : buf_sprintf("struct '%s' depends on itself", buf_ptr(&struct_type->name)));
2627 : : }
2628 : 0 : return ErrorSemanticAnalyzeFail;
2629 : : }
2630 : :
2631 : 5725 : struct_type->data.structure.resolve_loop_flag_other = true;
2632 : 5725 : assert(decl_node->type == NodeTypeContainerDecl);
2633 : :
2634 : 5725 : size_t field_count = struct_type->data.structure.src_field_count;
2635 : 5725 : bool packed = struct_type->data.structure.layout == ContainerLayoutPacked;
2636 : :
2637 [ + + ]: 12776 : for (size_t i = 0; i < field_count; i += 1) {
2638 : 7051 : TypeStructField *field = &struct_type->data.structure.fields[i];
2639 [ + + ]: 7051 : if (field->gen_index == SIZE_MAX)
2640 : 417 : continue;
2641 : :
2642 : 6634 : AstNode *align_expr = field->decl_node->data.struct_field.align_expr;
2643 [ + + ]: 6634 : if (align_expr != nullptr) {
2644 [ - + ]: 8 : if (!analyze_const_align(g, &struct_type->data.structure.decls_scope->base, align_expr,
2645 : : &field->align))
2646 : : {
2647 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2648 : 0 : return err;
2649 : : }
2650 [ + + ]: 6626 : } else if (packed) {
2651 : 909 : field->align = 1;
2652 : : } else {
2653 [ - + ]: 5717 : if ((err = type_val_resolve_abi_align(g, field->type_val, &field->align))) {
2654 [ # # ]: 0 : if (g->trace_err != nullptr) {
2655 : 0 : g->trace_err = add_error_note(g, g->trace_err, field->decl_node,
2656 : : buf_create_from_str("while checking this field"));
2657 : : }
2658 : 0 : struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2659 : 0 : return err;
2660 : : }
2661 [ - + ]: 5717 : if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
2662 : 0 : return ErrorSemanticAnalyzeFail;
2663 : : }
2664 : :
2665 [ + + ]: 6634 : if (field->align > struct_type->abi_align) {
2666 : 2949 : struct_type->abi_align = field->align;
2667 : : }
2668 : : }
2669 : :
2670 [ + + ]: 5725 : if (!type_has_bits(struct_type)) {
2671 : 3152 : assert(struct_type->abi_align == 0);
2672 : : }
2673 : :
2674 : 5725 : struct_type->data.structure.resolve_loop_flag_other = false;
2675 : :
2676 [ - + ]: 5725 : if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) {
2677 : 0 : return ErrorSemanticAnalyzeFail;
2678 : : }
2679 : :
2680 : 5725 : struct_type->data.structure.resolve_status = ResolveStatusAlignmentKnown;
2681 : 5725 : return ErrorNone;
2682 : : }
2683 : :
2684 : 18964 : static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
2685 : 18964 : assert(union_type->id == ZigTypeIdUnion);
2686 : :
2687 : : Error err;
2688 : :
2689 [ - + ]: 18964 : if (union_type->data.unionation.resolve_status == ResolveStatusInvalid)
2690 : 0 : return ErrorSemanticAnalyzeFail;
2691 : :
2692 [ + + ]: 18964 : if (union_type->data.unionation.resolve_status >= ResolveStatusZeroBitsKnown)
2693 : 18387 : return ErrorNone;
2694 : :
2695 : 577 : AstNode *decl_node = union_type->data.unionation.decl_node;
2696 : 577 : assert(decl_node->type == NodeTypeContainerDecl);
2697 : :
2698 [ - + ]: 577 : if (union_type->data.unionation.resolve_loop_flag_zero_bits) {
2699 [ # # ]: 0 : if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {
2700 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2701 : 0 : add_node_error(g, decl_node,
2702 : : buf_sprintf("union '%s' depends on itself",
2703 : : buf_ptr(&union_type->name)));
2704 : : }
2705 : 0 : return ErrorSemanticAnalyzeFail;
2706 : : }
2707 : :
2708 : 577 : union_type->data.unionation.resolve_loop_flag_zero_bits = true;
2709 : :
2710 : 577 : assert(union_type->data.unionation.fields == nullptr);
2711 : 577 : uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length;
2712 [ - + ]: 577 : if (field_count == 0) {
2713 : 0 : add_node_error(g, decl_node, buf_sprintf("unions must have 1 or more fields"));
2714 : 0 : union_type->data.unionation.src_field_count = field_count;
2715 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2716 : 0 : return ErrorSemanticAnalyzeFail;
2717 : : }
2718 : 577 : union_type->data.unionation.src_field_count = field_count;
2719 : 577 : union_type->data.unionation.fields = allocate<TypeUnionField>(field_count);
2720 : 577 : union_type->data.unionation.fields_by_name.init(field_count);
2721 : :
2722 : 577 : Scope *scope = &union_type->data.unionation.decls_scope->base;
2723 : :
2724 : 577 : HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};
2725 : :
2726 : 577 : AstNode *enum_type_node = decl_node->data.container_decl.init_arg_expr;
2727 [ + + ][ + + ]: 577 : union_type->data.unionation.have_explicit_tag_type = decl_node->data.container_decl.auto_enum ||
2728 : : enum_type_node != nullptr;
2729 : 577 : bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);
2730 [ + + ][ + + ]: 577 : bool want_safety = (field_count >= 2) && (auto_layout || enum_type_node != nullptr) && !(g->build_mode == BuildModeFastRelease || g->build_mode == BuildModeSmallRelease);
[ - + ][ + - ]
[ + - ]
2731 : : ZigType *tag_type;
2732 [ + + ][ + + ]: 577 : bool create_enum_type = decl_node->data.container_decl.auto_enum || (enum_type_node == nullptr && want_safety);
[ + + ]
2733 : : bool *covered_enum_fields;
2734 : : ZigLLVMDIEnumerator **di_enumerators;
2735 [ + + ]: 577 : if (create_enum_type) {
2736 : 410 : occupied_tag_values.init(field_count);
2737 : :
2738 : 410 : di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
2739 : :
2740 : : ZigType *tag_int_type;
2741 [ + + ]: 410 : if (enum_type_node != nullptr) {
2742 : 16 : tag_int_type = analyze_type_expr(g, scope, enum_type_node);
2743 [ - + ]: 16 : if (type_is_invalid(tag_int_type)) {
2744 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2745 : 0 : return ErrorSemanticAnalyzeFail;
2746 : : }
2747 [ - + ]: 16 : if (tag_int_type->id != ZigTypeIdInt) {
2748 : 0 : add_node_error(g, enum_type_node,
2749 : : buf_sprintf("expected integer tag type, found '%s'", buf_ptr(&tag_int_type->name)));
2750 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2751 : 0 : return ErrorSemanticAnalyzeFail;
2752 : : }
2753 [ + - ][ + + ]: 394 : } else if (auto_layout && field_count == 1) {
2754 : 40 : tag_int_type = g->builtin_types.entry_num_lit_int;
2755 : : } else {
2756 : 354 : tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
2757 : : }
2758 : :
2759 : 410 : tag_type = new_type_table_entry(ZigTypeIdEnum);
2760 : 410 : buf_resize(&tag_type->name, 0);
2761 : 410 : buf_appendf(&tag_type->name, "@TagType(%s)", buf_ptr(&union_type->name));
2762 : 410 : tag_type->llvm_type = tag_int_type->llvm_type;
2763 : 410 : tag_type->llvm_di_type = tag_int_type->llvm_di_type;
2764 : 410 : tag_type->abi_size = tag_int_type->abi_size;
2765 : 410 : tag_type->abi_align = tag_int_type->abi_align;
2766 : 410 : tag_type->size_in_bits = tag_int_type->size_in_bits;
2767 : :
2768 : 410 : tag_type->data.enumeration.tag_int_type = tag_int_type;
2769 : 410 : tag_type->data.enumeration.resolve_status = ResolveStatusSizeKnown;
2770 : 410 : tag_type->data.enumeration.decl_node = decl_node;
2771 : 410 : tag_type->data.enumeration.layout = ContainerLayoutAuto;
2772 : 410 : tag_type->data.enumeration.src_field_count = field_count;
2773 : 410 : tag_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
2774 : 410 : tag_type->data.enumeration.fields_by_name.init(field_count);
2775 : 410 : tag_type->data.enumeration.decls_scope = union_type->data.unionation.decls_scope;
2776 [ + + ]: 167 : } else if (enum_type_node != nullptr) {
2777 : 47 : ZigType *enum_type = analyze_type_expr(g, scope, enum_type_node);
2778 [ - + ]: 47 : if (type_is_invalid(enum_type)) {
2779 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2780 : 0 : return ErrorSemanticAnalyzeFail;
2781 : : }
2782 [ - + ]: 47 : if (enum_type->id != ZigTypeIdEnum) {
2783 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2784 : 0 : add_node_error(g, enum_type_node,
2785 : : buf_sprintf("expected enum tag type, found '%s'", buf_ptr(&enum_type->name)));
2786 : 0 : return ErrorSemanticAnalyzeFail;
2787 : : }
2788 [ - + ]: 47 : if ((err = type_resolve(g, enum_type, ResolveStatusAlignmentKnown))) {
2789 : 0 : assert(g->errors.length != 0);
2790 : 0 : return err;
2791 : : }
2792 : 47 : tag_type = enum_type;
2793 : 47 : covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);
2794 : : } else {
2795 : 120 : tag_type = nullptr;
2796 : : }
2797 : 577 : union_type->data.unionation.tag_type = tag_type;
2798 : :
2799 : 577 : uint32_t gen_field_index = 0;
2800 [ + + ]: 2941 : for (uint32_t i = 0; i < field_count; i += 1) {
2801 : 2364 : AstNode *field_node = decl_node->data.container_decl.fields.at(i);
2802 : 2364 : Buf *field_name = field_node->data.struct_field.name;
2803 : 2364 : TypeUnionField *union_field = &union_type->data.unionation.fields[i];
2804 : 2364 : union_field->name = field_node->data.struct_field.name;
2805 : 2364 : union_field->decl_node = field_node;
2806 : 2364 : union_field->gen_index = UINT32_MAX;
2807 : :
2808 : 2364 : auto field_entry = union_type->data.unionation.fields_by_name.put_unique(union_field->name, union_field);
2809 [ - + ]: 2364 : if (field_entry != nullptr) {
2810 : 0 : ErrorMsg *msg = add_node_error(g, field_node,
2811 : 0 : buf_sprintf("duplicate union field: '%s'", buf_ptr(union_field->name)));
2812 : 0 : add_error_note(g, msg, field_entry->value->decl_node, buf_sprintf("other field here"));
2813 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2814 : 0 : return ErrorSemanticAnalyzeFail;
2815 : : }
2816 : :
2817 : : bool field_is_zero_bits;
2818 [ + + ]: 2364 : if (field_node->data.struct_field.type == nullptr) {
2819 [ + + ][ + - ]: 742 : if (decl_node->data.container_decl.auto_enum ||
2820 : 16 : decl_node->data.container_decl.init_arg_expr != nullptr)
2821 : : {
2822 : 742 : union_field->type_entry = g->builtin_types.entry_void;
2823 : 742 : field_is_zero_bits = true;
2824 : : } else {
2825 : 0 : add_node_error(g, field_node, buf_sprintf("union field missing type"));
2826 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2827 : 0 : return ErrorSemanticAnalyzeFail;
2828 : : }
2829 : : } else {
2830 : 1622 : ConstExprValue *field_type_val = analyze_const_value(g, scope,
2831 : 1622 : field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef);
2832 [ - + ]: 1622 : if (type_is_invalid(field_type_val->type)) {
2833 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2834 : 0 : return ErrorSemanticAnalyzeFail;
2835 : : }
2836 : 1622 : assert(field_type_val->special != ConstValSpecialRuntime);
2837 : 1622 : union_field->type_val = field_type_val;
2838 [ - + ]: 1622 : if (union_type->data.unionation.resolve_status == ResolveStatusInvalid)
2839 : 0 : return ErrorSemanticAnalyzeFail;
2840 : :
2841 : : bool field_is_opaque_type;
2842 [ - + ]: 1622 : if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) {
2843 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2844 : 0 : return ErrorSemanticAnalyzeFail;
2845 : : }
2846 [ - + ]: 1622 : if (field_is_opaque_type) {
2847 : 0 : add_node_error(g, field_node->data.struct_field.type,
2848 : : buf_create_from_str(
2849 : : "opaque types have unknown size and therefore cannot be directly embedded in unions"));
2850 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2851 : 0 : return ErrorSemanticAnalyzeFail;
2852 : : }
2853 : :
2854 [ - + + - ]: 1622 : switch (type_val_resolve_requires_comptime(g, field_type_val)) {
2855 : 0 : case ReqCompTimeInvalid:
2856 [ # # ]: 0 : if (g->trace_err != nullptr) {
2857 : 0 : g->trace_err = add_error_note(g, g->trace_err, field_node,
2858 : : buf_create_from_str("while checking this field"));
2859 : : }
2860 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2861 : 0 : return ErrorSemanticAnalyzeFail;
2862 : 255 : case ReqCompTimeYes:
2863 : 255 : union_type->data.unionation.requires_comptime = true;
2864 : 255 : break;
2865 : 1367 : case ReqCompTimeNo:
2866 : 1367 : break;
2867 : : }
2868 : :
2869 [ - + ]: 1622 : if ((err = type_val_resolve_zero_bits(g, field_type_val, union_type, nullptr, &field_is_zero_bits))) {
2870 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2871 : 1622 : return ErrorSemanticAnalyzeFail;
2872 : : }
2873 : : }
2874 : :
2875 [ + + ][ - + ]: 2364 : if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) {
2876 : 0 : ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value,
2877 : 0 : buf_create_from_str("untagged union field assignment"));
2878 : 0 : add_error_note(g, msg, decl_node, buf_create_from_str("consider 'union(enum)' here"));
2879 : : }
2880 : :
2881 [ + + ]: 2364 : if (create_enum_type) {
2882 : 1682 : di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(field_name), i);
2883 : 1682 : union_field->enum_field = &tag_type->data.enumeration.fields[i];
2884 : 1682 : union_field->enum_field->name = field_name;
2885 : 1682 : union_field->enum_field->decl_index = i;
2886 : 1682 : union_field->enum_field->decl_node = field_node;
2887 : :
2888 : 1682 : auto prev_entry = tag_type->data.enumeration.fields_by_name.put_unique(union_field->enum_field->name, union_field->enum_field);
2889 : 1682 : assert(prev_entry == nullptr); // caught by union de-duplicator above
2890 : :
2891 : 1682 : AstNode *tag_value = field_node->data.struct_field.value;
2892 : : // In this first pass we resolve explicit tag values.
2893 : : // In a second pass we will fill in the unspecified ones.
2894 [ + + ]: 1682 : if (tag_value != nullptr) {
2895 : 64 : ZigType *tag_int_type = tag_type->data.enumeration.tag_int_type;
2896 : 64 : ConstExprValue *result = analyze_const_value(g, scope, tag_value, tag_int_type,
2897 : 64 : nullptr, UndefBad);
2898 [ - + ]: 64 : if (type_is_invalid(result->type)) {
2899 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2900 : 0 : return ErrorSemanticAnalyzeFail;
2901 : : }
2902 : 64 : assert(result->special != ConstValSpecialRuntime);
2903 : 64 : assert(result->type->id == ZigTypeIdInt);
2904 : 64 : auto entry = occupied_tag_values.put_unique(result->data.x_bigint, tag_value);
2905 [ + - ]: 64 : if (entry == nullptr) {
2906 : 64 : bigint_init_bigint(&union_field->enum_field->value, &result->data.x_bigint);
2907 : : } else {
2908 : 0 : Buf *val_buf = buf_alloc();
2909 : 0 : bigint_append_buf(val_buf, &result->data.x_bigint, 10);
2910 : :
2911 : 0 : ErrorMsg *msg = add_node_error(g, tag_value,
2912 : 0 : buf_sprintf("enum tag value %s already taken", buf_ptr(val_buf)));
2913 : 0 : add_error_note(g, msg, entry->value,
2914 : : buf_sprintf("other occurrence here"));
2915 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2916 : 1682 : return ErrorSemanticAnalyzeFail;
2917 : : }
2918 : : }
2919 [ + + ]: 682 : } else if (enum_type_node != nullptr) {
2920 : 470 : union_field->enum_field = find_enum_type_field(tag_type, field_name);
2921 [ - + ]: 470 : if (union_field->enum_field == nullptr) {
2922 : 0 : ErrorMsg *msg = add_node_error(g, field_node,
2923 : 0 : buf_sprintf("enum field not found: '%s'", buf_ptr(field_name)));
2924 : 0 : add_error_note(g, msg, tag_type->data.enumeration.decl_node,
2925 : : buf_sprintf("enum declared here"));
2926 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2927 : 0 : return ErrorSemanticAnalyzeFail;
2928 : : }
2929 : 470 : covered_enum_fields[union_field->enum_field->decl_index] = true;
2930 : : } else {
2931 : 212 : union_field->enum_field = allocate<TypeEnumField>(1);
2932 : 212 : union_field->enum_field->name = field_name;
2933 : 212 : union_field->enum_field->decl_index = i;
2934 : 212 : bigint_init_unsigned(&union_field->enum_field->value, i);
2935 : : }
2936 : 2364 : assert(union_field->enum_field != nullptr);
2937 : :
2938 [ + + ]: 2364 : if (field_is_zero_bits)
2939 : 1181 : continue;
2940 : :
2941 : 1183 : union_field->gen_index = gen_field_index;
2942 : 1183 : gen_field_index += 1;
2943 : : }
2944 : :
2945 [ + + ][ + + ]: 577 : bool src_have_tag = decl_node->data.container_decl.auto_enum ||
2946 : 216 : decl_node->data.container_decl.init_arg_expr != nullptr;
2947 : :
2948 [ + + ][ - + ]: 577 : if (src_have_tag && union_type->data.unionation.layout != ContainerLayoutAuto) {
2949 : : const char *qual_str;
2950 [ # # # # ]: 0 : switch (union_type->data.unionation.layout) {
2951 : 0 : case ContainerLayoutAuto:
2952 : 0 : zig_unreachable();
2953 : 0 : case ContainerLayoutPacked:
2954 : 0 : qual_str = "packed";
2955 : 0 : break;
2956 : 0 : case ContainerLayoutExtern:
2957 : 0 : qual_str = "extern";
2958 : 0 : break;
2959 : : }
2960 [ # # ]: 0 : AstNode *source_node = (decl_node->data.container_decl.init_arg_expr != nullptr) ?
2961 : : decl_node->data.container_decl.init_arg_expr : decl_node;
2962 : 0 : add_node_error(g, source_node,
2963 : : buf_sprintf("%s union does not support enum tag type", qual_str));
2964 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2965 : 0 : return ErrorSemanticAnalyzeFail;
2966 : : }
2967 : :
2968 [ + + ]: 577 : if (create_enum_type) {
2969 : : // Now iterate again and populate the unspecified tag values
2970 : 410 : uint32_t next_maybe_unoccupied_index = 0;
2971 : :
2972 [ + + ]: 2092 : for (uint32_t field_i = 0; field_i < field_count; field_i += 1) {
2973 : 1682 : AstNode *field_node = decl_node->data.container_decl.fields.at(field_i);
2974 : 1682 : TypeUnionField *union_field = &union_type->data.unionation.fields[field_i];
2975 : 1682 : AstNode *tag_value = field_node->data.struct_field.value;
2976 : :
2977 [ + + ]: 1682 : if (tag_value == nullptr) {
2978 [ + + ]: 1618 : if (occupied_tag_values.size() == 0) {
2979 : 1578 : bigint_init_unsigned(&union_field->enum_field->value, next_maybe_unoccupied_index);
2980 : 1578 : next_maybe_unoccupied_index += 1;
2981 : : } else {
2982 : : BigInt proposed_value;
2983 : : for (;;) {
2984 : 40 : bigint_init_unsigned(&proposed_value, next_maybe_unoccupied_index);
2985 : 40 : next_maybe_unoccupied_index += 1;
2986 : 40 : auto entry = occupied_tag_values.put_unique(proposed_value, field_node);
2987 [ - + ]: 40 : if (entry != nullptr) {
2988 : 0 : continue;
2989 : : }
2990 : 40 : break;
2991 : 0 : }
2992 : 1618 : bigint_init_bigint(&union_field->enum_field->value, &proposed_value);
2993 : : }
2994 : : }
2995 : : }
2996 [ + + ]: 167 : } else if (enum_type_node != nullptr) {
2997 [ + + ]: 517 : for (uint32_t i = 0; i < tag_type->data.enumeration.src_field_count; i += 1) {
2998 : 470 : TypeEnumField *enum_field = &tag_type->data.enumeration.fields[i];
2999 [ - + ]: 470 : if (!covered_enum_fields[i]) {
3000 : 0 : AstNode *enum_decl_node = tag_type->data.enumeration.decl_node;
3001 : 0 : AstNode *field_node = enum_decl_node->data.container_decl.fields.at(i);
3002 : 0 : ErrorMsg *msg = add_node_error(g, decl_node,
3003 : 0 : buf_sprintf("enum field missing: '%s'", buf_ptr(enum_field->name)));
3004 : 0 : add_error_note(g, msg, field_node,
3005 : : buf_sprintf("declared here"));
3006 : 0 : union_type->data.unionation.resolve_status = ResolveStatusInvalid;
3007 : : }
3008 : : }
3009 : : }
3010 : :
3011 [ - + ]: 577 : if (union_type->data.unionation.resolve_status == ResolveStatusInvalid) {
3012 : 0 : return ErrorSemanticAnalyzeFail;
3013 : : }
3014 : :
3015 : 577 : union_type->data.unionation.resolve_loop_flag_zero_bits = false;
3016 : :
3017 : 577 : union_type->data.unionation.gen_field_count = gen_field_index;
3018 [ + + ][ + + ]: 577 : bool zero_bits = gen_field_index == 0 && (field_count < 2 || !src_have_tag);
[ + + ]
3019 [ + + ]: 577 : if (!zero_bits) {
3020 : 545 : union_type->abi_size = SIZE_MAX;
3021 : 545 : union_type->size_in_bits = SIZE_MAX;
3022 : : }
3023 [ + + ]: 577 : union_type->data.unionation.resolve_status = zero_bits ? ResolveStatusSizeKnown : ResolveStatusZeroBitsKnown;
3024 : :
3025 : 18964 : return ErrorNone;
3026 : : }
3027 : :
3028 : 16200 : static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, bool is_test) {
3029 : 16200 : buf_resize(buf, 0);
3030 : :
3031 : 16200 : Scope *scope = tld->parent_scope;
3032 [ - + ]: 16200 : while (scope->id != ScopeIdDecls) {
3033 : 0 : scope = scope->parent;
3034 : : }
3035 : 16200 : ScopeDecls *decls_scope = reinterpret_cast<ScopeDecls *>(scope);
3036 : 16200 : buf_append_buf(buf, &decls_scope->container_type->name);
3037 [ + + ]: 16200 : if (buf_len(buf) != 0) buf_append_char(buf, NAMESPACE_SEP_CHAR);
3038 [ + + ]: 16200 : if (is_test) {
3039 : 5880 : buf_append_str(buf, "test \"");
3040 : 5880 : buf_append_buf(buf, tld->name);
3041 : 5880 : buf_append_char(buf, '"');
3042 : : } else {
3043 : 10320 : buf_append_buf(buf, tld->name);
3044 : : }
3045 : 16200 : }
3046 : :
3047 : 35275 : ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value) {
3048 : 35275 : ZigFn *fn_entry = allocate<ZigFn>(1);
3049 : :
3050 : 35275 : fn_entry->prealloc_backward_branch_quota = default_backward_branch_quota;
3051 : :
3052 : 35275 : fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;
3053 : 35275 : fn_entry->analyzed_executable.backward_branch_quota = &fn_entry->prealloc_backward_branch_quota;
3054 : 35275 : fn_entry->analyzed_executable.fn_entry = fn_entry;
3055 : 35275 : fn_entry->ir_executable.fn_entry = fn_entry;
3056 : 35275 : fn_entry->fn_inline = inline_value;
3057 : :
3058 : 35275 : return fn_entry;
3059 : : }
3060 : :
3061 : 29395 : ZigFn *create_fn(CodeGen *g, AstNode *proto_node) {
3062 : 29395 : assert(proto_node->type == NodeTypeFnProto);
3063 : 29395 : AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
3064 : :
3065 : 29395 : ZigFn *fn_entry = create_fn_raw(g, fn_proto->fn_inline);
3066 : :
3067 : 29395 : fn_entry->proto_node = proto_node;
3068 [ + + ]: 29395 : fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr :
3069 : 29263 : proto_node->data.fn_proto.fn_def_node->data.fn_def.body;
3070 : :
3071 : 29395 : fn_entry->analyzed_executable.source_node = fn_entry->body_node;
3072 : :
3073 : 29395 : return fn_entry;
3074 : : }
3075 : :
3076 : 14007 : static bool scope_is_root_decls(Scope *scope) {
3077 [ + - ]: 14007 : while (scope) {
3078 [ + - ]: 14007 : if (scope->id == ScopeIdDecls) {
3079 : 14007 : ScopeDecls *scope_decls = (ScopeDecls *)scope;
3080 : 14007 : return is_top_level_struct(scope_decls->container_type);
3081 : : }
3082 : 0 : scope = scope->parent;
3083 : : }
3084 : 0 : zig_unreachable();
3085 : : }
3086 : :
3087 : 15 : void typecheck_panic_fn(CodeGen *g, TldFn *tld_fn, ZigFn *panic_fn) {
3088 : 15 : ConstExprValue *panic_fn_type_val = get_builtin_value(g, "PanicFn");
3089 : 15 : assert(panic_fn_type_val != nullptr);
3090 : 15 : assert(panic_fn_type_val->type->id == ZigTypeIdMetaType);
3091 : 15 : ZigType *panic_fn_type = panic_fn_type_val->data.x_type;
3092 : :
3093 : 15 : AstNode *fake_decl = allocate<AstNode>(1);
3094 : 15 : *fake_decl = *panic_fn->proto_node;
3095 : 15 : fake_decl->type = NodeTypeSymbol;
3096 : 15 : fake_decl->data.symbol_expr.symbol = tld_fn->base.name;
3097 : :
3098 : : // call this for the side effects of casting to panic_fn_type
3099 : 15 : analyze_const_value(g, tld_fn->base.parent_scope, fake_decl, panic_fn_type, nullptr, UndefBad);
3100 : 15 : }
3101 : :
3102 : 5888 : ZigType *get_test_fn_type(CodeGen *g) {
3103 [ + + ]: 5888 : if (g->test_fn_type)
3104 : 5880 : return g->test_fn_type;
3105 : :
3106 : 8 : FnTypeId fn_type_id = {0};
3107 : 8 : fn_type_id.return_type = get_error_union_type(g, g->builtin_types.entry_global_error_set,
3108 : : g->builtin_types.entry_void);
3109 : 8 : g->test_fn_type = get_fn_type(g, &fn_type_id);
3110 : 5888 : return g->test_fn_type;
3111 : : }
3112 : :
3113 : 24 : void add_var_export(CodeGen *g, ZigVar *var, Buf *symbol_name, GlobalLinkageId linkage) {
3114 : 24 : GlobalExport *global_export = var->export_list.add_one();
3115 : 24 : memset(global_export, 0, sizeof(GlobalExport));
3116 : 24 : buf_init_from_buf(&global_export->name, symbol_name);
3117 : 24 : global_export->linkage = linkage;
3118 : 24 : }
3119 : :
3120 : 4003 : void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc) {
3121 [ + + ]: 4003 : if (ccc) {
3122 [ + + ][ + - ]: 3990 : if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) {
[ + + ]
3123 : 4 : g->have_c_main = true;
3124 [ - + ][ # # ]: 3986 : } else if (buf_eql_str(symbol_name, "WinMain") &&
[ - + ]
3125 : 0 : g->zig_target->os == OsWindows)
3126 : : {
3127 : 0 : g->have_winmain = true;
3128 [ + + ][ + - ]: 3986 : } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") &&
[ + + ]
3129 : 2 : g->zig_target->os == OsWindows)
3130 : : {
3131 : 2 : g->have_winmain_crt_startup = true;
3132 [ - + ][ # # ]: 3984 : } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") &&
[ - + ]
3133 : 0 : g->zig_target->os == OsWindows)
3134 : : {
3135 : 0 : g->have_dllmain_crt_startup = true;
3136 : : }
3137 : : }
3138 : :
3139 : 4003 : GlobalExport *fn_export = fn_table_entry->export_list.add_one();
3140 : 4003 : memset(fn_export, 0, sizeof(GlobalExport));
3141 : 4003 : buf_init_from_buf(&fn_export->name, symbol_name);
3142 : 4003 : fn_export->linkage = linkage;
3143 : 4003 : }
3144 : :
3145 : 19887 : static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
3146 : 19887 : ZigType *import = tld_fn->base.import;
3147 : 19887 : AstNode *source_node = tld_fn->base.source_node;
3148 [ + + ]: 19887 : if (source_node->type == NodeTypeFnProto) {
3149 : 14007 : AstNodeFnProto *fn_proto = &source_node->data.fn_proto;
3150 : :
3151 : 14007 : AstNode *fn_def_node = fn_proto->fn_def_node;
3152 : :
3153 : 14007 : ZigFn *fn_table_entry = create_fn(g, source_node);
3154 : 14007 : tld_fn->fn_entry = fn_table_entry;
3155 : :
3156 : 14007 : bool is_extern = (fn_table_entry->body_node == nullptr);
3157 [ + + ][ + + ]: 14007 : if (fn_proto->is_export || is_extern) {
3158 : 3687 : buf_init_from_buf(&fn_table_entry->symbol_name, tld_fn->base.name);
3159 : : } else {
3160 : 10320 : get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, false);
3161 : : }
3162 : :
3163 [ + + ]: 14007 : if (fn_proto->is_export) {
3164 [ - + ][ # # ]: 3555 : bool ccc = (fn_proto->cc == CallingConventionUnspecified || fn_proto->cc == CallingConventionC);
3165 : 3555 : add_fn_export(g, fn_table_entry, &fn_table_entry->symbol_name, GlobalLinkageIdStrong, ccc);
3166 : : }
3167 : :
3168 [ + + ]: 14007 : if (!is_extern) {
3169 : 13875 : fn_table_entry->fndef_scope = create_fndef_scope(g,
3170 : : fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry);
3171 : :
3172 [ + + ]: 26789 : for (size_t i = 0; i < fn_proto->params.length; i += 1) {
3173 : 12914 : AstNode *param_node = fn_proto->params.at(i);
3174 : 12914 : assert(param_node->type == NodeTypeParamDecl);
3175 [ - + ]: 12914 : if (param_node->data.param_decl.name == nullptr) {
3176 : 0 : add_node_error(g, param_node, buf_sprintf("missing parameter name"));
3177 : : }
3178 : : }
3179 : : } else {
3180 : 132 : fn_table_entry->inferred_async_node = inferred_async_none;
3181 : 132 : g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base);
3182 : : }
3183 : :
3184 [ + + ]: 14007 : Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope;
3185 : :
3186 : 14007 : fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry);
3187 : :
3188 [ - + ]: 14007 : if (fn_proto->section_expr != nullptr) {
3189 : 0 : analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name);
3190 : : }
3191 : :
3192 [ - + ]: 14007 : if (fn_table_entry->type_entry->id == ZigTypeIdInvalid) {
3193 : 0 : tld_fn->base.resolution = TldResolutionInvalid;
3194 : 0 : return;
3195 : : }
3196 : :
3197 [ + + ]: 14007 : if (!fn_table_entry->type_entry->data.fn.is_generic) {
3198 [ + + ]: 12108 : if (fn_def_node)
3199 : 11976 : g->fn_defs.append(fn_table_entry);
3200 : : }
3201 : :
3202 : : // if the calling convention implies that it cannot be async, we save that for later
3203 : : // and leave the value to be nullptr to indicate that we have not emitted possible
3204 : : // compile errors for improperly calling async functions.
3205 [ + + ]: 14007 : if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync) {
3206 : 128 : fn_table_entry->inferred_async_node = fn_table_entry->proto_node;
3207 : : }
3208 : :
3209 [ + + ][ + + ]: 20050 : if (scope_is_root_decls(tld_fn->base.parent_scope) &&
[ + + ]
3210 [ + + ]: 6043 : (import == g->root_import || import->data.structure.root_struct->package == g->panic_package))
3211 : : {
3212 [ + + ][ + + ]: 3593 : if (g->have_pub_main && buf_eql_str(tld_fn->base.name, "main")) {
[ + + ]
3213 : 1 : g->main_fn = fn_table_entry;
3214 [ + + ]: 3731 : } else if ((import->data.structure.root_struct->package == g->panic_package || g->have_pub_panic) &&
[ + + + + ]
[ + + ]
3215 : 139 : buf_eql_str(tld_fn->base.name, "panic"))
3216 : : {
3217 : 15 : g->panic_fn = fn_table_entry;
3218 : 14007 : g->panic_tld_fn = tld_fn;
3219 : : }
3220 : : }
3221 [ + - ]: 5880 : } else if (source_node->type == NodeTypeTestDecl) {
3222 : 5880 : ZigFn *fn_table_entry = create_fn_raw(g, FnInlineAuto);
3223 : :
3224 : 5880 : get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, true);
3225 : :
3226 : 5880 : tld_fn->fn_entry = fn_table_entry;
3227 : :
3228 : 5880 : fn_table_entry->proto_node = source_node;
3229 : 5880 : fn_table_entry->fndef_scope = create_fndef_scope(g, source_node, tld_fn->base.parent_scope, fn_table_entry);
3230 : 5880 : fn_table_entry->type_entry = get_test_fn_type(g);
3231 : 5880 : fn_table_entry->body_node = source_node->data.test_decl.body;
3232 : 5880 : fn_table_entry->is_test = true;
3233 : :
3234 : 5880 : g->fn_defs.append(fn_table_entry);
3235 : 5880 : g->test_fns.append(fn_table_entry);
3236 : :
3237 : : } else {
3238 : 0 : zig_unreachable();
3239 : : }
3240 : : }
3241 : :
3242 : 95 : static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) {
3243 : 95 : assert(tld_comptime->base.source_node->type == NodeTypeCompTime);
3244 : 95 : AstNode *expr_node = tld_comptime->base.source_node->data.comptime_expr.expr;
3245 : 95 : analyze_const_value(g, tld_comptime->base.parent_scope, expr_node, g->builtin_types.entry_void,
3246 : : nullptr, UndefBad);
3247 : 95 : }
3248 : :
3249 : 62920 : static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
3250 : 62920 : bool is_export = false;
3251 [ + + ]: 62920 : if (tld->id == TldIdVar) {
3252 : 38234 : assert(tld->source_node->type == NodeTypeVariableDeclaration);
3253 : 38234 : is_export = tld->source_node->data.variable_declaration.is_export;
3254 [ + + ]: 24686 : } else if (tld->id == TldIdFn) {
3255 : 24537 : assert(tld->source_node->type == NodeTypeFnProto);
3256 : 24537 : is_export = tld->source_node->data.fn_proto.is_export;
3257 : :
3258 [ + + ][ - + ]: 24537 : if (!is_export && !tld->source_node->data.fn_proto.is_extern &&
[ + + ]
3259 : 19237 : tld->source_node->data.fn_proto.fn_def_node == nullptr)
3260 : : {
3261 : 0 : add_node_error(g, tld->source_node, buf_sprintf("non-extern function has no body"));
3262 : 0 : return;
3263 : : }
3264 [ + - ]: 149 : } else if (tld->id == TldIdUsingNamespace) {
3265 : 149 : g->resolve_queue.append(tld);
3266 : : }
3267 [ + + ]: 62920 : if (is_export) {
3268 : 3577 : g->resolve_queue.append(tld);
3269 : :
3270 : 3577 : auto entry = g->exported_symbol_names.put_unique(tld->name, tld);
3271 [ - + ]: 3577 : if (entry) {
3272 : 0 : AstNode *other_source_node = entry->value->source_node;
3273 : 0 : ErrorMsg *msg = add_node_error(g, tld->source_node,
3274 : 0 : buf_sprintf("exported symbol collision: '%s'", buf_ptr(tld->name)));
3275 : 3577 : add_error_note(g, msg, other_source_node, buf_sprintf("other symbol here"));
3276 : : }
3277 : : }
3278 : :
3279 [ + + ]: 62920 : if (tld->name != nullptr) {
3280 : 62771 : auto entry = decls_scope->decl_table.put_unique(tld->name, tld);
3281 [ - + ]: 62771 : if (entry) {
3282 : 0 : Tld *other_tld = entry->value;
3283 : 0 : ErrorMsg *msg = add_node_error(g, tld->source_node, buf_sprintf("redefinition of '%s'", buf_ptr(tld->name)));
3284 : 0 : add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition is here"));
3285 : 0 : return;
3286 : : }
3287 : :
3288 : : ZigType *type;
3289 [ - + ]: 62771 : if (get_primitive_type(g, tld->name, &type) != ErrorPrimitiveTypeNotFound) {
3290 : 62771 : add_node_error(g, tld->source_node,
3291 : : buf_sprintf("declaration shadows primitive type '%s'", buf_ptr(tld->name)));
3292 : : }
3293 : : }
3294 : : }
3295 : :
3296 : 8753 : static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
3297 : 8753 : assert(node->type == NodeTypeTestDecl);
3298 : :
3299 [ + + ]: 8753 : if (!g->is_test_build)
3300 : 812 : return;
3301 : :
3302 : 7941 : ZigType *import = get_scope_import(&decls_scope->base);
3303 [ + + ]: 7941 : if (import->data.structure.root_struct->package != g->root_package)
3304 : 2061 : return;
3305 : :
3306 : 5880 : Buf *decl_name_buf = node->data.test_decl.name;
3307 : :
3308 [ + - ]: 11760 : Buf *test_name = g->test_name_prefix ?
3309 : 5880 : buf_sprintf("%s%s", buf_ptr(g->test_name_prefix), buf_ptr(decl_name_buf)) : decl_name_buf;
3310 : :
3311 [ - + ][ # # ]: 5880 : if (g->test_filter != nullptr && strstr(buf_ptr(test_name), buf_ptr(g->test_filter)) == nullptr) {
[ - + ]
3312 : 0 : return;
3313 : : }
3314 : :
3315 : 5880 : TldFn *tld_fn = allocate<TldFn>(1);
3316 : 5880 : init_tld(&tld_fn->base, TldIdFn, test_name, VisibModPrivate, node, &decls_scope->base);
3317 : 5880 : g->resolve_queue.append(&tld_fn->base);
3318 : : }
3319 : :
3320 : 95 : static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
3321 : 95 : assert(node->type == NodeTypeCompTime);
3322 : :
3323 : 95 : TldCompTime *tld_comptime = allocate<TldCompTime>(1);
3324 : 95 : init_tld(&tld_comptime->base, TldIdCompTime, nullptr, VisibModPrivate, node, &decls_scope->base);
3325 : 95 : g->resolve_queue.append(&tld_comptime->base);
3326 : 95 : }
3327 : :
3328 : 76307 : void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node,
3329 : : Scope *parent_scope)
3330 : : {
3331 : 76307 : tld->id = id;
3332 : 76307 : tld->name = name;
3333 : 76307 : tld->visib_mod = visib_mod;
3334 : 76307 : tld->source_node = source_node;
3335 [ + - ]: 76307 : tld->import = source_node ? source_node->owner : nullptr;
3336 : 76307 : tld->parent_scope = parent_scope;
3337 : 76307 : }
3338 : :
3339 : 8 : void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value) {
3340 : 8 : Tld *tld = get_container_scope(g->compile_var_import)->decl_table.get(name);
3341 : 8 : resolve_top_level_decl(g, tld, tld->source_node, false);
3342 : 8 : assert(tld->id == TldIdVar);
3343 : 8 : TldVar *tld_var = (TldVar *)tld;
3344 : 8 : tld_var->var->const_value = value;
3345 : 8 : tld_var->var->var_type = value->type;
3346 : 8 : tld_var->var->align_bytes = get_abi_alignment(g, value->type);
3347 : 8 : }
3348 : :
3349 : 95094 : void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
3350 [ - + + + : 95094 : switch (node->type) {
+ + + -
- ]
3351 : 0 : case NodeTypeContainerDecl:
3352 [ # # ]: 0 : for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) {
3353 : 0 : AstNode *child = node->data.container_decl.decls.at(i);
3354 : 0 : scan_decls(g, decls_scope, child);
3355 : : }
3356 : 0 : break;
3357 : 23326 : case NodeTypeFnDef:
3358 : 23326 : scan_decls(g, decls_scope, node->data.fn_def.fn_proto);
3359 : 23326 : break;
3360 : 38234 : case NodeTypeVariableDeclaration:
3361 : : {
3362 : 38234 : Buf *name = node->data.variable_declaration.symbol;
3363 : 38234 : VisibMod visib_mod = node->data.variable_declaration.visib_mod;
3364 : 38234 : TldVar *tld_var = allocate<TldVar>(1);
3365 : 38234 : init_tld(&tld_var->base, TldIdVar, name, visib_mod, node, &decls_scope->base);
3366 : 38234 : tld_var->extern_lib_name = node->data.variable_declaration.lib_name;
3367 : 38234 : add_top_level_decl(g, decls_scope, &tld_var->base);
3368 : 38234 : break;
3369 : : }
3370 : 24537 : case NodeTypeFnProto:
3371 : : {
3372 : : // if the name is missing, we immediately announce an error
3373 : 24537 : Buf *fn_name = node->data.fn_proto.name;
3374 [ - + ]: 24537 : if (fn_name == nullptr) {
3375 : 0 : add_node_error(g, node, buf_sprintf("missing function name"));
3376 : 0 : break;
3377 : : }
3378 : :
3379 : 24537 : VisibMod visib_mod = node->data.fn_proto.visib_mod;
3380 : 24537 : TldFn *tld_fn = allocate<TldFn>(1);
3381 : 24537 : init_tld(&tld_fn->base, TldIdFn, fn_name, visib_mod, node, &decls_scope->base);
3382 : 24537 : tld_fn->extern_lib_name = node->data.fn_proto.lib_name;
3383 : 24537 : add_top_level_decl(g, decls_scope, &tld_fn->base);
3384 : :
3385 : 24537 : break;
3386 : : }
3387 : 149 : case NodeTypeUsingNamespace: {
3388 : 149 : VisibMod visib_mod = node->data.using_namespace.visib_mod;
3389 : 149 : TldUsingNamespace *tld_using_namespace = allocate<TldUsingNamespace>(1);
3390 : 149 : init_tld(&tld_using_namespace->base, TldIdUsingNamespace, nullptr, visib_mod, node, &decls_scope->base);
3391 : 149 : add_top_level_decl(g, decls_scope, &tld_using_namespace->base);
3392 : 149 : decls_scope->use_decls.append(tld_using_namespace);
3393 : 149 : break;
3394 : : }
3395 : 8753 : case NodeTypeTestDecl:
3396 : 8753 : preview_test_decl(g, node, decls_scope);
3397 : 8753 : break;
3398 : 95 : case NodeTypeCompTime:
3399 : 95 : preview_comptime_decl(g, node, decls_scope);
3400 : 95 : break;
3401 : 0 : case NodeTypeParamDecl:
3402 : : case NodeTypeReturnExpr:
3403 : : case NodeTypeDefer:
3404 : : case NodeTypeBlock:
3405 : : case NodeTypeGroupedExpr:
3406 : : case NodeTypeBinOpExpr:
3407 : : case NodeTypeCatchExpr:
3408 : : case NodeTypeFnCallExpr:
3409 : : case NodeTypeArrayAccessExpr:
3410 : : case NodeTypeSliceExpr:
3411 : : case NodeTypeFloatLiteral:
3412 : : case NodeTypeIntLiteral:
3413 : : case NodeTypeStringLiteral:
3414 : : case NodeTypeCharLiteral:
3415 : : case NodeTypeBoolLiteral:
3416 : : case NodeTypeNullLiteral:
3417 : : case NodeTypeUndefinedLiteral:
3418 : : case NodeTypeSymbol:
3419 : : case NodeTypePrefixOpExpr:
3420 : : case NodeTypePointerType:
3421 : : case NodeTypeIfBoolExpr:
3422 : : case NodeTypeWhileExpr:
3423 : : case NodeTypeForExpr:
3424 : : case NodeTypeSwitchExpr:
3425 : : case NodeTypeSwitchProng:
3426 : : case NodeTypeSwitchRange:
3427 : : case NodeTypeBreak:
3428 : : case NodeTypeContinue:
3429 : : case NodeTypeUnreachable:
3430 : : case NodeTypeAsmExpr:
3431 : : case NodeTypeFieldAccessExpr:
3432 : : case NodeTypePtrDeref:
3433 : : case NodeTypeUnwrapOptional:
3434 : : case NodeTypeStructField:
3435 : : case NodeTypeContainerInitExpr:
3436 : : case NodeTypeStructValueField:
3437 : : case NodeTypeArrayType:
3438 : : case NodeTypeInferredArrayType:
3439 : : case NodeTypeErrorType:
3440 : : case NodeTypeIfErrorExpr:
3441 : : case NodeTypeIfOptional:
3442 : : case NodeTypeErrorSetDecl:
3443 : : case NodeTypeResume:
3444 : : case NodeTypeAwaitExpr:
3445 : : case NodeTypeSuspend:
3446 : : case NodeTypeEnumLiteral:
3447 : : case NodeTypeAnyFrameType:
3448 : 0 : zig_unreachable();
3449 : : }
3450 : 95094 : }
3451 : :
3452 : 7411 : static Error resolve_decl_container(CodeGen *g, TldContainer *tld_container) {
3453 : 7411 : ZigType *type_entry = tld_container->type_entry;
3454 : 7411 : assert(type_entry);
3455 : :
3456 [ + + + - ]: 7411 : switch (type_entry->id) {
3457 : 5725 : case ZigTypeIdStruct:
3458 : 5725 : return resolve_struct_type(g, tld_container->type_entry);
3459 : 1109 : case ZigTypeIdEnum:
3460 : 1109 : return resolve_enum_zero_bits(g, tld_container->type_entry);
3461 : 577 : case ZigTypeIdUnion:
3462 : 577 : return resolve_union_type(g, tld_container->type_entry);
3463 : 0 : default:
3464 : 0 : zig_unreachable();
3465 : : }
3466 : : }
3467 : :
3468 : 899 : ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry) {
3469 [ - - + - ]: 899 : switch (type_entry->id) {
3470 : 0 : case ZigTypeIdInvalid:
3471 : 0 : return g->builtin_types.entry_invalid;
3472 : 0 : case ZigTypeIdUnreachable:
3473 : : case ZigTypeIdUndefined:
3474 : : case ZigTypeIdNull:
3475 : : case ZigTypeIdArgTuple:
3476 : : case ZigTypeIdOpaque:
3477 : 0 : add_node_error(g, source_node, buf_sprintf("variable of type '%s' not allowed",
3478 : : buf_ptr(&type_entry->name)));
3479 : 0 : return g->builtin_types.entry_invalid;
3480 : 899 : case ZigTypeIdComptimeFloat:
3481 : : case ZigTypeIdComptimeInt:
3482 : : case ZigTypeIdEnumLiteral:
3483 : : case ZigTypeIdMetaType:
3484 : : case ZigTypeIdVoid:
3485 : : case ZigTypeIdBool:
3486 : : case ZigTypeIdInt:
3487 : : case ZigTypeIdFloat:
3488 : : case ZigTypeIdPointer:
3489 : : case ZigTypeIdArray:
3490 : : case ZigTypeIdStruct:
3491 : : case ZigTypeIdOptional:
3492 : : case ZigTypeIdErrorUnion:
3493 : : case ZigTypeIdErrorSet:
3494 : : case ZigTypeIdEnum:
3495 : : case ZigTypeIdUnion:
3496 : : case ZigTypeIdFn:
3497 : : case ZigTypeIdBoundFn:
3498 : : case ZigTypeIdVector:
3499 : : case ZigTypeIdFnFrame:
3500 : : case ZigTypeIdAnyFrame:
3501 : 899 : return type_entry;
3502 : : }
3503 : 0 : zig_unreachable();
3504 : : }
3505 : :
3506 : : // Set name to nullptr to make the variable anonymous (not visible to programmer).
3507 : : // TODO merge with definition of add_local_var in ir.cpp
3508 : 141497 : ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name,
3509 : : bool is_const, ConstExprValue *const_value, Tld *src_tld, ZigType *var_type)
3510 : : {
3511 : : Error err;
3512 : 141497 : assert(const_value != nullptr);
3513 : 141497 : assert(var_type != nullptr);
3514 : :
3515 : 141497 : ZigVar *variable_entry = allocate<ZigVar>(1);
3516 : 141497 : variable_entry->const_value = const_value;
3517 : 141497 : variable_entry->var_type = var_type;
3518 : 141497 : variable_entry->parent_scope = parent_scope;
3519 : 141497 : variable_entry->shadowable = false;
3520 : 141497 : variable_entry->mem_slot_index = SIZE_MAX;
3521 : 141497 : variable_entry->src_arg_index = SIZE_MAX;
3522 : :
3523 : 141497 : assert(name);
3524 : 141497 : buf_init_from_buf(&variable_entry->name, name);
3525 : :
3526 [ - + ]: 141497 : if ((err = type_resolve(g, var_type, ResolveStatusAlignmentKnown))) {
3527 : 0 : variable_entry->var_type = g->builtin_types.entry_invalid;
3528 : : } else {
3529 : 141497 : variable_entry->align_bytes = get_abi_alignment(g, var_type);
3530 : :
3531 : 141497 : ZigVar *existing_var = find_variable(g, parent_scope, name, nullptr);
3532 [ - + ][ + + ]: 141497 : if (existing_var && !existing_var->shadowable) {
3533 [ # # ][ # # ]: 0 : if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) {
[ # # ]
3534 : 0 : ErrorMsg *msg = add_node_error(g, source_node,
3535 : 0 : buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
3536 : 0 : add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
3537 : : }
3538 : 0 : variable_entry->var_type = g->builtin_types.entry_invalid;
3539 : : } else {
3540 : : ZigType *type;
3541 [ - + ]: 141497 : if (get_primitive_type(g, name, &type) != ErrorPrimitiveTypeNotFound) {
3542 : 0 : add_node_error(g, source_node,
3543 : : buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name)));
3544 : 0 : variable_entry->var_type = g->builtin_types.entry_invalid;
3545 : : } else {
3546 : 141497 : Scope *search_scope = nullptr;
3547 [ + + ]: 141497 : if (src_tld == nullptr) {
3548 : 129601 : search_scope = parent_scope;
3549 [ + - ][ + + ]: 11896 : } else if (src_tld->parent_scope != nullptr && src_tld->parent_scope->parent != nullptr) {
3550 : 2079 : search_scope = src_tld->parent_scope->parent;
3551 : : }
3552 [ + + ]: 141497 : if (search_scope != nullptr) {
3553 : 131680 : Tld *tld = find_decl(g, search_scope, name);
3554 [ - + ]: 131680 : if (tld != nullptr) {
3555 : 0 : ErrorMsg *msg = add_node_error(g, source_node,
3556 : 0 : buf_sprintf("redefinition of '%s'", buf_ptr(name)));
3557 : 0 : add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here"));
3558 : 141497 : variable_entry->var_type = g->builtin_types.entry_invalid;
3559 : : }
3560 : : }
3561 : : }
3562 : : }
3563 : : }
3564 : :
3565 : : Scope *child_scope;
3566 [ + - ][ + + ]: 141497 : if (source_node && source_node->type == NodeTypeParamDecl) {
3567 : 129601 : child_scope = create_var_scope(g, source_node, parent_scope, variable_entry);
3568 : : } else {
3569 : : // it's already in the decls table
3570 : 11896 : child_scope = parent_scope;
3571 : : }
3572 : :
3573 : :
3574 : 141497 : variable_entry->src_is_const = is_const;
3575 : 141497 : variable_entry->gen_is_const = is_const;
3576 : 141497 : variable_entry->decl_node = source_node;
3577 : 141497 : variable_entry->child_scope = child_scope;
3578 : :
3579 : :
3580 : 141497 : return variable_entry;
3581 : : }
3582 : :
3583 : 11896 : static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
3584 : 11896 : AstNode *source_node = tld_var->base.source_node;
3585 : 11896 : AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration;
3586 : :
3587 : 11896 : bool is_const = var_decl->is_const;
3588 : 11896 : bool is_extern = var_decl->is_extern;
3589 : 11896 : bool is_export = var_decl->is_export;
3590 : 11896 : bool is_thread_local = var_decl->threadlocal_tok != nullptr;
3591 : :
3592 : 11896 : ZigType *explicit_type = nullptr;
3593 [ + + ]: 11896 : if (var_decl->type) {
3594 [ - + ]: 899 : if (tld_var->analyzing_type) {
3595 : 0 : add_node_error(g, var_decl->type,
3596 : : buf_sprintf("type of '%s' depends on itself", buf_ptr(tld_var->base.name)));
3597 : 0 : explicit_type = g->builtin_types.entry_invalid;
3598 : : } else {
3599 : 899 : tld_var->analyzing_type = true;
3600 : 899 : ZigType *proposed_type = analyze_type_expr(g, tld_var->base.parent_scope, var_decl->type);
3601 : 899 : explicit_type = validate_var_type(g, var_decl->type, proposed_type);
3602 : : }
3603 : : }
3604 : :
3605 [ + + ][ + - ]: 11896 : assert(!is_export || !is_extern);
3606 : :
3607 : 11896 : ConstExprValue *init_value = nullptr;
3608 : :
3609 : : // TODO more validation for types that can't be used for export/extern variables
3610 : 11896 : ZigType *implicit_type = nullptr;
3611 [ - + ][ + + ]: 11896 : if (explicit_type && explicit_type->id == ZigTypeIdInvalid) {
3612 : 0 : implicit_type = explicit_type;
3613 [ + - ]: 11896 : } else if (var_decl->expr) {
3614 [ + + ]: 11896 : init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type,
3615 : : var_decl->symbol, allow_lazy ? LazyOk : UndefOk);
3616 : 11896 : assert(init_value);
3617 : 11896 : implicit_type = init_value->type;
3618 : :
3619 [ - + ]: 11896 : if (implicit_type->id == ZigTypeIdUnreachable) {
3620 : 0 : add_node_error(g, source_node, buf_sprintf("variable initialization is unreachable"));
3621 : 0 : implicit_type = g->builtin_types.entry_invalid;
3622 [ + + ][ - + ]: 11896 : } else if ((!is_const || is_extern) &&
[ + - ]
3623 [ + - ]: 1010 : (implicit_type->id == ZigTypeIdComptimeFloat ||
3624 [ - + ]: 1010 : implicit_type->id == ZigTypeIdComptimeInt ||
3625 : 1010 : implicit_type->id == ZigTypeIdEnumLiteral))
3626 : : {
3627 : 0 : add_node_error(g, source_node, buf_sprintf("unable to infer variable type"));
3628 : 0 : implicit_type = g->builtin_types.entry_invalid;
3629 [ - + ]: 11896 : } else if (implicit_type->id == ZigTypeIdNull) {
3630 : 0 : add_node_error(g, source_node, buf_sprintf("unable to infer variable type"));
3631 : 0 : implicit_type = g->builtin_types.entry_invalid;
3632 [ + + ][ - + ]: 11896 : } else if (implicit_type->id == ZigTypeIdMetaType && !is_const) {
3633 : 0 : add_node_error(g, source_node, buf_sprintf("variable of type 'type' must be constant"));
3634 : 0 : implicit_type = g->builtin_types.entry_invalid;
3635 : : }
3636 [ + - ][ + - ]: 11896 : assert(implicit_type->id == ZigTypeIdInvalid || init_value->special != ConstValSpecialRuntime);
3637 [ # # ]: 0 : } else if (!is_extern) {
3638 : 0 : add_node_error(g, source_node, buf_sprintf("variables must be initialized"));
3639 : 0 : implicit_type = g->builtin_types.entry_invalid;
3640 : : }
3641 : :
3642 [ + + ]: 11896 : ZigType *type = explicit_type ? explicit_type : implicit_type;
3643 : 11896 : assert(type != nullptr); // should have been caught by the parser
3644 : :
3645 [ - + ]: 11896 : ConstExprValue *init_val = (init_value != nullptr) ? init_value : create_const_runtime(type);
3646 : :
3647 : 11896 : tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, var_decl->symbol,
3648 : : is_const, init_val, &tld_var->base, type);
3649 : 11896 : tld_var->var->is_thread_local = is_thread_local;
3650 : :
3651 [ - + ][ - + ]: 11896 : if (implicit_type != nullptr && type_is_invalid(implicit_type)) {
[ + - ]
3652 : 0 : tld_var->var->var_type = g->builtin_types.entry_invalid;
3653 : : }
3654 : :
3655 [ + + ]: 11896 : if (var_decl->align_expr != nullptr) {
3656 [ - + ]: 35 : if (!analyze_const_align(g, tld_var->base.parent_scope, var_decl->align_expr, &tld_var->var->align_bytes)) {
3657 : 0 : tld_var->var->var_type = g->builtin_types.entry_invalid;
3658 : : }
3659 : : }
3660 : :
3661 [ + + ]: 11896 : if (var_decl->section_expr != nullptr) {
3662 [ - + ]: 5 : if (!analyze_const_string(g, tld_var->base.parent_scope, var_decl->section_expr, &tld_var->section_name)) {
3663 : 0 : tld_var->section_name = nullptr;
3664 : : }
3665 : : }
3666 : :
3667 [ + + ][ - + ]: 11896 : if (is_thread_local && is_const) {
3668 : 0 : add_node_error(g, source_node, buf_sprintf("threadlocal variable cannot be constant"));
3669 : : }
3670 : :
3671 [ + + ]: 11896 : if (is_export) {
3672 : 22 : add_var_export(g, tld_var->var, &tld_var->var->name, GlobalLinkageIdStrong);
3673 : : }
3674 : :
3675 : 11896 : g->global_vars.append(tld_var);
3676 : 11896 : }
3677 : :
3678 : 340 : static void add_symbols_from_container(CodeGen *g, TldUsingNamespace *src_using_namespace,
3679 : : TldUsingNamespace *dst_using_namespace, ScopeDecls* dest_decls_scope)
3680 : : {
3681 [ + + ][ + + ]: 340 : if (src_using_namespace->base.resolution == TldResolutionUnresolved ||
3682 : 315 : src_using_namespace->base.resolution == TldResolutionResolving)
3683 : : {
3684 : 179 : assert(src_using_namespace->base.parent_scope->id == ScopeIdDecls);
3685 : 179 : ScopeDecls *src_decls_scope = (ScopeDecls *)src_using_namespace->base.parent_scope;
3686 : 179 : preview_use_decl(g, src_using_namespace, src_decls_scope);
3687 [ + + ]: 179 : if (src_using_namespace != dst_using_namespace) {
3688 : 30 : resolve_use_decl(g, src_using_namespace, src_decls_scope);
3689 : : }
3690 : : }
3691 : :
3692 : 340 : ConstExprValue *use_expr = src_using_namespace->using_namespace_value;
3693 [ - + ]: 340 : if (type_is_invalid(use_expr->type)) {
3694 : 0 : dest_decls_scope->any_imports_failed = true;
3695 : 0 : return;
3696 : : }
3697 : :
3698 : 340 : dst_using_namespace->base.resolution = TldResolutionOk;
3699 : :
3700 : 340 : assert(use_expr->special != ConstValSpecialRuntime);
3701 : :
3702 : : // The source scope for the imported symbols
3703 : 340 : ScopeDecls *src_scope = get_container_scope(use_expr->data.x_type);
3704 : : // The top-level container where the symbols are defined, it's used in the
3705 : : // loop below in order to exclude the ones coming from an import statement
3706 : 340 : ZigType *src_import = get_scope_import(&src_scope->base);
3707 : 340 : assert(src_import != nullptr);
3708 : :
3709 [ - + ]: 340 : if (src_scope->any_imports_failed) {
3710 : 0 : dest_decls_scope->any_imports_failed = true;
3711 : : }
3712 : :
3713 : 340 : auto it = src_scope->decl_table.entry_iterator();
3714 : : for (;;) {
3715 : 185215 : auto *entry = it.next();
3716 [ + + ]: 185215 : if (!entry)
3717 : 340 : break;
3718 : :
3719 : 184875 : Buf *target_tld_name = entry->key;
3720 : 184875 : Tld *target_tld = entry->value;
3721 : :
3722 [ + + ]: 184875 : if (target_tld->visib_mod == VisibModPrivate) {
3723 : 100722 : continue;
3724 : : }
3725 : :
3726 [ + + ]: 183774 : if (target_tld->import != src_import) {
3727 : 99621 : continue;
3728 : : }
3729 : :
3730 : 84153 : auto existing_entry = dest_decls_scope->decl_table.put_unique(target_tld_name, target_tld);
3731 [ + + ]: 84153 : if (existing_entry) {
3732 : 14115 : Tld *existing_decl = existing_entry->value;
3733 [ - + ]: 14115 : if (existing_decl != target_tld) {
3734 : 0 : ErrorMsg *msg = add_node_error(g, dst_using_namespace->base.source_node,
3735 : : buf_sprintf("import of '%s' overrides existing definition",
3736 : 0 : buf_ptr(target_tld_name)));
3737 : 0 : add_error_note(g, msg, existing_decl->source_node, buf_sprintf("previous definition here"));
3738 : 84153 : add_error_note(g, msg, target_tld->source_node, buf_sprintf("imported definition here"));
3739 : : }
3740 : : }
3741 : 184875 : }
3742 : :
3743 [ + + ]: 617 : for (size_t i = 0; i < src_scope->use_decls.length; i += 1) {
3744 : 277 : TldUsingNamespace *tld_using_namespace = src_scope->use_decls.at(i);
3745 [ + + ]: 277 : if (tld_using_namespace->base.visib_mod != VisibModPrivate)
3746 : 191 : add_symbols_from_container(g, tld_using_namespace, dst_using_namespace, dest_decls_scope);
3747 : : }
3748 : : }
3749 : :
3750 : 154 : static void resolve_use_decl(CodeGen *g, TldUsingNamespace *tld_using_namespace, ScopeDecls *dest_decls_scope) {
3751 [ + + ][ - + ]: 154 : if (tld_using_namespace->base.resolution == TldResolutionOk ||
3752 : 149 : tld_using_namespace->base.resolution == TldResolutionInvalid)
3753 : : {
3754 : 5 : return;
3755 : : }
3756 : 149 : add_symbols_from_container(g, tld_using_namespace, tld_using_namespace, dest_decls_scope);
3757 : : }
3758 : :
3759 : 303 : static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, ScopeDecls *dest_decls_scope) {
3760 [ + - ][ + - ]: 303 : if (using_namespace->base.resolution == TldResolutionOk ||
3761 [ + + ]: 303 : using_namespace->base.resolution == TldResolutionInvalid ||
3762 : 303 : using_namespace->using_namespace_value != nullptr)
3763 : : {
3764 : 149 : return;
3765 : : }
3766 : :
3767 : 154 : using_namespace->base.resolution = TldResolutionResolving;
3768 : 154 : assert(using_namespace->base.source_node->type == NodeTypeUsingNamespace);
3769 : 308 : ConstExprValue *result = analyze_const_value(g, &dest_decls_scope->base,
3770 : 154 : using_namespace->base.source_node->data.using_namespace.expr, g->builtin_types.entry_type,
3771 : 154 : nullptr, UndefBad);
3772 : 154 : using_namespace->using_namespace_value = result;
3773 : :
3774 [ - + ]: 154 : if (type_is_invalid(result->type)) {
3775 : 0 : dest_decls_scope->any_imports_failed = true;
3776 : 0 : using_namespace->base.resolution = TldResolutionInvalid;
3777 : 0 : using_namespace->using_namespace_value = &g->invalid_instruction->value;
3778 : 0 : return;
3779 : : }
3780 : :
3781 [ - + ]: 154 : if (!is_container(result->data.x_type)) {
3782 : 0 : add_node_error(g, using_namespace->base.source_node,
3783 : 0 : buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&result->data.x_type->name)));
3784 : 0 : dest_decls_scope->any_imports_failed = true;
3785 : 0 : using_namespace->base.resolution = TldResolutionInvalid;
3786 : 0 : using_namespace->using_namespace_value = &g->invalid_instruction->value;
3787 : 0 : return;
3788 : : }
3789 : : }
3790 : :
3791 : 129033 : void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool allow_lazy) {
3792 [ + + ][ + + ]: 129033 : bool want_resolve_lazy = tld->resolution == TldResolutionOkLazy && !allow_lazy;
3793 [ + + ][ + + ]: 129033 : if (tld->resolution != TldResolutionUnresolved && !want_resolve_lazy)
3794 : 89672 : return;
3795 : :
3796 : 39361 : tld->resolution = TldResolutionResolving;
3797 : :
3798 [ + + + + : 39361 : switch (tld->id) {
+ - ]
3799 : 11960 : case TldIdVar: {
3800 : 11960 : TldVar *tld_var = (TldVar *)tld;
3801 [ + + ]: 11960 : if (want_resolve_lazy) {
3802 : 64 : ir_resolve_lazy(g, source_node, tld_var->var->const_value);
3803 : : } else {
3804 : 11896 : resolve_decl_var(g, tld_var, allow_lazy);
3805 : : }
3806 [ + + ]: 11960 : tld->resolution = allow_lazy ? TldResolutionOkLazy : TldResolutionOk;
3807 : 11960 : break;
3808 : : }
3809 : 19887 : case TldIdFn: {
3810 : 19887 : TldFn *tld_fn = (TldFn *)tld;
3811 : 19887 : resolve_decl_fn(g, tld_fn);
3812 : :
3813 : 19887 : tld->resolution = TldResolutionOk;
3814 : 19887 : break;
3815 : : }
3816 : 7411 : case TldIdContainer: {
3817 : 7411 : TldContainer *tld_container = (TldContainer *)tld;
3818 : 7411 : resolve_decl_container(g, tld_container);
3819 : :
3820 : 7411 : tld->resolution = TldResolutionOk;
3821 : 7411 : break;
3822 : : }
3823 : 95 : case TldIdCompTime: {
3824 : 95 : TldCompTime *tld_comptime = (TldCompTime *)tld;
3825 : 95 : resolve_decl_comptime(g, tld_comptime);
3826 : :
3827 : 95 : tld->resolution = TldResolutionOk;
3828 : 95 : break;
3829 : : }
3830 : 8 : case TldIdUsingNamespace: {
3831 : 8 : TldUsingNamespace *tld_using_namespace = (TldUsingNamespace *)tld;
3832 : 8 : assert(tld_using_namespace->base.parent_scope->id == ScopeIdDecls);
3833 : 8 : ScopeDecls *dest_decls_scope = (ScopeDecls *)tld_using_namespace->base.parent_scope;
3834 : 8 : preview_use_decl(g, tld_using_namespace, dest_decls_scope);
3835 : 8 : resolve_use_decl(g, tld_using_namespace, dest_decls_scope);
3836 : :
3837 : 8 : tld->resolution = TldResolutionOk;
3838 : 8 : break;
3839 : : }
3840 : : }
3841 : :
3842 [ - + ][ # # ]: 39361 : if (g->trace_err != nullptr && source_node != nullptr && !source_node->already_traced_this_node) {
[ # # ]
3843 : 0 : g->trace_err = add_error_note(g, g->trace_err, source_node, buf_create_from_str("referenced here"));
3844 : 0 : source_node->already_traced_this_node = true;
3845 : : }
3846 : : }
3847 : :
3848 : 462295 : Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) {
3849 : : // resolve all the using_namespace decls
3850 [ + + ]: 467915 : for (size_t i = 0; i < decls_scope->use_decls.length; i += 1) {
3851 : 5620 : TldUsingNamespace *tld_using_namespace = decls_scope->use_decls.at(i);
3852 [ + + ]: 5620 : if (tld_using_namespace->base.resolution == TldResolutionUnresolved) {
3853 : 116 : preview_use_decl(g, tld_using_namespace, decls_scope);
3854 : 116 : resolve_use_decl(g, tld_using_namespace, decls_scope);
3855 : : }
3856 : : }
3857 : :
3858 : 462295 : auto entry = decls_scope->decl_table.maybe_get(name);
3859 [ + + ]: 462295 : return (entry == nullptr) ? nullptr : entry->value;
3860 : : }
3861 : :
3862 : 388546 : Tld *find_decl(CodeGen *g, Scope *scope, Buf *name) {
3863 [ + + ]: 3864807 : while (scope) {
3864 [ + + ]: 3575661 : if (scope->id == ScopeIdDecls) {
3865 : 424380 : ScopeDecls *decls_scope = (ScopeDecls *)scope;
3866 : :
3867 : 424380 : Tld *result = find_container_decl(g, decls_scope, name);
3868 [ + + ]: 424380 : if (result != nullptr)
3869 : 424380 : return result;
3870 : : }
3871 : 3476261 : scope = scope->parent;
3872 : : }
3873 : 289146 : return nullptr;
3874 : : }
3875 : :
3876 : 1337840 : ZigVar *find_variable(CodeGen *g, Scope *scope, Buf *name, ScopeFnDef **crossed_fndef_scope) {
3877 : 1337840 : ScopeFnDef *my_crossed_fndef_scope = nullptr;
3878 [ + + ]: 10507272 : while (scope) {
3879 [ + + ]: 10124085 : if (scope->id == ScopeIdVarDecl) {
3880 : 6325838 : ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
3881 [ + + ]: 6325838 : if (buf_eql_buf(name, &var_scope->var->name)) {
3882 [ + + ]: 848809 : if (crossed_fndef_scope != nullptr)
3883 : 833624 : *crossed_fndef_scope = my_crossed_fndef_scope;
3884 : 6325838 : return var_scope->var;
3885 : : }
3886 [ + + ]: 3798247 : } else if (scope->id == ScopeIdDecls) {
3887 : 545785 : ScopeDecls *decls_scope = (ScopeDecls *)scope;
3888 : 545785 : auto entry = decls_scope->decl_table.maybe_get(name);
3889 [ + + ]: 545785 : if (entry) {
3890 : 217153 : Tld *tld = entry->value;
3891 [ + + ]: 217153 : if (tld->id == TldIdVar) {
3892 : 154137 : TldVar *tld_var = (TldVar *)tld;
3893 [ + + ]: 154137 : if (tld_var->var) {
3894 [ + - ]: 105844 : if (crossed_fndef_scope != nullptr)
3895 : 105844 : *crossed_fndef_scope = nullptr;
3896 : 545785 : return tld_var->var;
3897 : : }
3898 : : }
3899 : : }
3900 [ + + ]: 3252462 : } else if (scope->id == ScopeIdFnDef) {
3901 : 483990 : my_crossed_fndef_scope = (ScopeFnDef *)scope;
3902 : : }
3903 : 9169432 : scope = scope->parent;
3904 : : }
3905 : :
3906 : 383187 : return nullptr;
3907 : : }
3908 : :
3909 : 296472 : ZigFn *scope_fn_entry(Scope *scope) {
3910 [ + + ]: 3182443 : while (scope) {
3911 [ + + ]: 3182164 : if (scope->id == ScopeIdFnDef) {
3912 : 296193 : ScopeFnDef *fn_scope = (ScopeFnDef *)scope;
3913 : 296193 : return fn_scope->fn_entry;
3914 : : }
3915 : 2885971 : scope = scope->parent;
3916 : : }
3917 : 279 : return nullptr;
3918 : : }
3919 : :
3920 : 1713 : ZigPackage *scope_package(Scope *scope) {
3921 : 1713 : ZigType *import = get_scope_import(scope);
3922 : 1713 : assert(is_top_level_struct(import));
3923 : 1713 : return import->data.structure.root_struct->package;
3924 : : }
3925 : :
3926 : 238610 : TypeEnumField *find_enum_type_field(ZigType *enum_type, Buf *name) {
3927 : 238610 : assert(enum_type->id == ZigTypeIdEnum);
3928 [ - + ]: 238610 : if (enum_type->data.enumeration.src_field_count == 0)
3929 : 0 : return nullptr;
3930 : 238610 : auto entry = enum_type->data.enumeration.fields_by_name.maybe_get(name);
3931 [ + + ]: 238610 : if (entry == nullptr)
3932 : 32 : return nullptr;
3933 : 238578 : return entry->value;
3934 : : }
3935 : :
3936 : 100066 : TypeStructField *find_struct_type_field(ZigType *type_entry, Buf *name) {
3937 : 100066 : assert(type_entry->id == ZigTypeIdStruct);
3938 : 100066 : assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown));
3939 [ + + ]: 100066 : if (type_entry->data.structure.src_field_count == 0)
3940 : 40 : return nullptr;
3941 : 100026 : auto entry = type_entry->data.structure.fields_by_name.maybe_get(name);
3942 [ + + ]: 100026 : if (entry == nullptr)
3943 : 9400 : return nullptr;
3944 : 90626 : return entry->value;
3945 : : }
3946 : :
3947 : 5218 : TypeUnionField *find_union_type_field(ZigType *type_entry, Buf *name) {
3948 : 5218 : assert(type_entry->id == ZigTypeIdUnion);
3949 : 5218 : assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown));
3950 [ - + ]: 5218 : if (type_entry->data.unionation.src_field_count == 0)
3951 : 0 : return nullptr;
3952 : 5218 : auto entry = type_entry->data.unionation.fields_by_name.maybe_get(name);
3953 [ + + ]: 5218 : if (entry == nullptr)
3954 : 80 : return nullptr;
3955 : 5138 : return entry->value;
3956 : : }
3957 : :
3958 : 3253 : TypeUnionField *find_union_field_by_tag(ZigType *type_entry, const BigInt *tag) {
3959 : 3253 : assert(type_entry->id == ZigTypeIdUnion);
3960 : 3253 : assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown));
3961 [ + - ]: 26076 : for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) {
3962 : 26076 : TypeUnionField *field = &type_entry->data.unionation.fields[i];
3963 [ + + ]: 26076 : if (bigint_cmp(&field->enum_field->value, tag) == CmpEQ) {
3964 : 3253 : return field;
3965 : : }
3966 : : }
3967 : 0 : return nullptr;
3968 : : }
3969 : :
3970 : 41 : TypeEnumField *find_enum_field_by_tag(ZigType *enum_type, const BigInt *tag) {
3971 : 41 : assert(type_is_resolved(enum_type, ResolveStatusZeroBitsKnown));
3972 [ + - ]: 113 : for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) {
3973 : 113 : TypeEnumField *field = &enum_type->data.enumeration.fields[i];
3974 [ + + ]: 113 : if (bigint_cmp(&field->value, tag) == CmpEQ) {
3975 : 41 : return field;
3976 : : }
3977 : : }
3978 : 0 : return nullptr;
3979 : : }
3980 : :
3981 : :
3982 : 267527 : bool is_container(ZigType *type_entry) {
3983 [ - + + + : 267527 : switch (type_entry->id) {
- ]
3984 : 0 : case ZigTypeIdInvalid:
3985 : 0 : zig_unreachable();
3986 : 161708 : case ZigTypeIdStruct:
3987 : 161708 : return !type_entry->data.structure.is_slice;
3988 : 30802 : case ZigTypeIdEnum:
3989 : : case ZigTypeIdUnion:
3990 : 30802 : return true;
3991 : 75017 : case ZigTypeIdPointer:
3992 : : case ZigTypeIdMetaType:
3993 : : case ZigTypeIdVoid:
3994 : : case ZigTypeIdBool:
3995 : : case ZigTypeIdUnreachable:
3996 : : case ZigTypeIdInt:
3997 : : case ZigTypeIdFloat:
3998 : : case ZigTypeIdArray:
3999 : : case ZigTypeIdComptimeFloat:
4000 : : case ZigTypeIdComptimeInt:
4001 : : case ZigTypeIdEnumLiteral:
4002 : : case ZigTypeIdUndefined:
4003 : : case ZigTypeIdNull:
4004 : : case ZigTypeIdOptional:
4005 : : case ZigTypeIdErrorUnion:
4006 : : case ZigTypeIdErrorSet:
4007 : : case ZigTypeIdFn:
4008 : : case ZigTypeIdBoundFn:
4009 : : case ZigTypeIdArgTuple:
4010 : : case ZigTypeIdOpaque:
4011 : : case ZigTypeIdVector:
4012 : : case ZigTypeIdFnFrame:
4013 : : case ZigTypeIdAnyFrame:
4014 : 75017 : return false;
4015 : : }
4016 : 0 : zig_unreachable();
4017 : : }
4018 : :
4019 : 369056 : bool is_ref(ZigType *type_entry) {
4020 [ + + ][ + - ]: 369056 : return type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.ptr_len == PtrLenSingle;
4021 : : }
4022 : :
4023 : 69066 : bool is_array_ref(ZigType *type_entry) {
4024 [ + + ]: 69066 : ZigType *array = is_ref(type_entry) ?
4025 : 69066 : type_entry->data.pointer.child_type : type_entry;
4026 : 69066 : return array->id == ZigTypeIdArray;
4027 : : }
4028 : :
4029 : 213662 : bool is_container_ref(ZigType *parent_ty) {
4030 [ + + ]: 213662 : ZigType *ty = is_ref(parent_ty) ? parent_ty->data.pointer.child_type : parent_ty;
4031 [ + + ][ + + ]: 213662 : return is_slice(ty) || is_container(ty);
4032 : : }
4033 : :
4034 : 86328 : ZigType *container_ref_type(ZigType *type_entry) {
4035 : 86328 : assert(is_container_ref(type_entry));
4036 [ + + ]: 86328 : return is_ref(type_entry) ?
4037 : 86328 : type_entry->data.pointer.child_type : type_entry;
4038 : : }
4039 : :
4040 : 4060677 : ZigType *get_src_ptr_type(ZigType *type) {
4041 [ + + ]: 4060677 : if (type->id == ZigTypeIdPointer) return type;
4042 [ + + ]: 1854963 : if (type->id == ZigTypeIdFn) return type;
4043 [ + + ]: 1847579 : if (type->id == ZigTypeIdAnyFrame) return type;
4044 [ + + ]: 1845835 : if (type->id == ZigTypeIdOptional) {
4045 [ + + ]: 21342 : if (type->data.maybe.child_type->id == ZigTypeIdPointer) {
4046 [ + + ]: 6147 : return type->data.maybe.child_type->data.pointer.allow_zero ? nullptr : type->data.maybe.child_type;
4047 : : }
4048 [ + + ]: 15195 : if (type->data.maybe.child_type->id == ZigTypeIdFn) return type->data.maybe.child_type;
4049 [ - + ]: 15081 : if (type->data.maybe.child_type->id == ZigTypeIdAnyFrame) return type->data.maybe.child_type;
4050 : : }
4051 : 1839574 : return nullptr;
4052 : : }
4053 : :
4054 : 188880 : ZigType *get_codegen_ptr_type(ZigType *type) {
4055 : 188880 : ZigType *ty = get_src_ptr_type(type);
4056 [ + + ][ + + ]: 188880 : if (ty == nullptr || !type_has_bits(ty))
[ + + ]
4057 : 138544 : return nullptr;
4058 : 50336 : return ty;
4059 : : }
4060 : :
4061 : 57807 : bool type_is_nonnull_ptr(ZigType *type) {
4062 [ + + ][ + + ]: 57807 : return get_codegen_ptr_type(type) == type && !ptr_allows_addr_zero(type);
4063 : : }
4064 : :
4065 : 0 : static uint32_t get_async_frame_align_bytes(CodeGen *g) {
4066 : 0 : uint32_t a = g->pointer_size_bytes * 2;
4067 : : // promises have at least alignment 8 so that we can have 3 extra bits when doing atomicrmw
4068 [ # # ]: 0 : if (a < 8) a = 8;
4069 : 0 : return a;
4070 : : }
4071 : :
4072 : 208607 : uint32_t get_ptr_align(CodeGen *g, ZigType *type) {
4073 : 208607 : ZigType *ptr_type = get_src_ptr_type(type);
4074 [ + + ]: 208607 : if (ptr_type->id == ZigTypeIdPointer) {
4075 [ + + ]: 206446 : return (ptr_type->data.pointer.explicit_alignment == 0) ?
4076 : 206446 : get_abi_alignment(g, ptr_type->data.pointer.child_type) : ptr_type->data.pointer.explicit_alignment;
4077 [ + - ]: 2161 : } else if (ptr_type->id == ZigTypeIdFn) {
4078 : : // I tried making this use LLVMABIAlignmentOfType but it trips this assertion in LLVM:
4079 : : // "Cannot getTypeInfo() on a type that is unsized!"
4080 : : // when getting the alignment of `?extern fn() void`.
4081 : : // See http://lists.llvm.org/pipermail/llvm-dev/2018-September/126142.html
4082 [ + + ]: 2161 : return (ptr_type->data.fn.fn_type_id.alignment == 0) ? 1 : ptr_type->data.fn.fn_type_id.alignment;
4083 [ # # ]: 0 : } else if (ptr_type->id == ZigTypeIdAnyFrame) {
4084 : 0 : return get_async_frame_align_bytes(g);
4085 : : } else {
4086 : 0 : zig_unreachable();
4087 : : }
4088 : : }
4089 : :
4090 : 3552 : bool get_ptr_const(ZigType *type) {
4091 : 3552 : ZigType *ptr_type = get_src_ptr_type(type);
4092 [ + + ]: 3552 : if (ptr_type->id == ZigTypeIdPointer) {
4093 : 3482 : return ptr_type->data.pointer.is_const;
4094 [ + - ]: 70 : } else if (ptr_type->id == ZigTypeIdFn) {
4095 : 70 : return true;
4096 [ # # ]: 0 : } else if (ptr_type->id == ZigTypeIdAnyFrame) {
4097 : 0 : return true;
4098 : : } else {
4099 : 0 : zig_unreachable();
4100 : : }
4101 : : }
4102 : :
4103 : 27702 : AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index) {
4104 [ + + ]: 27702 : if (fn_entry->param_source_nodes)
4105 : 18503 : return fn_entry->param_source_nodes[index];
4106 [ + - ]: 9199 : else if (fn_entry->proto_node)
4107 : 9199 : return fn_entry->proto_node->data.fn_proto.params.at(index);
4108 : : else
4109 : 0 : return nullptr;
4110 : : }
4111 : :
4112 : 24304 : static void define_local_param_variables(CodeGen *g, ZigFn *fn_table_entry) {
4113 : 24304 : ZigType *fn_type = fn_table_entry->type_entry;
4114 : 24304 : assert(!fn_type->data.fn.is_generic);
4115 : 24304 : FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
4116 [ + + ]: 51534 : for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
4117 : 27230 : FnTypeParamInfo *param_info = &fn_type_id->param_info[i];
4118 : 27230 : AstNode *param_decl_node = get_param_decl_node(fn_table_entry, i);
4119 : : Buf *param_name;
4120 [ + + ][ + - ]: 27230 : bool is_var_args = param_decl_node && param_decl_node->data.param_decl.is_var_args;
4121 [ + - ][ + + ]: 27230 : if (param_decl_node && !is_var_args) {
4122 : 23912 : param_name = param_decl_node->data.param_decl.name;
4123 : : } else {
4124 : 3318 : param_name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
4125 : : }
4126 [ - + ]: 27230 : if (param_name == nullptr) {
4127 : 0 : continue;
4128 : : }
4129 : :
4130 : 27230 : ZigType *param_type = param_info->type;
4131 : 27230 : bool is_noalias = param_info->is_noalias;
4132 : :
4133 [ + + ][ - + ]: 27230 : if (is_noalias && get_codegen_ptr_type(param_type) == nullptr) {
[ - + ]
4134 : 0 : add_node_error(g, param_decl_node, buf_sprintf("noalias on non-pointer parameter"));
4135 : : }
4136 : :
4137 : 27230 : ZigVar *var = add_variable(g, param_decl_node, fn_table_entry->child_scope,
4138 : 27230 : param_name, true, create_const_runtime(param_type), nullptr, param_type);
4139 : 27230 : var->src_arg_index = i;
4140 : 27230 : fn_table_entry->child_scope = var->child_scope;
4141 [ + + ][ + - ]: 27230 : var->shadowable = var->shadowable || is_var_args;
4142 : :
4143 [ + + ]: 27230 : if (type_has_bits(param_type)) {
4144 : 27054 : fn_table_entry->variable_list.append(var);
4145 : : }
4146 : : }
4147 : 24304 : }
4148 : :
4149 : 16912 : bool resolve_inferred_error_set(CodeGen *g, ZigType *err_set_type, AstNode *source_node) {
4150 : 16912 : assert(err_set_type->id == ZigTypeIdErrorSet);
4151 : 16912 : ZigFn *infer_fn = err_set_type->data.error_set.infer_fn;
4152 [ + + ]: 16912 : if (infer_fn != nullptr) {
4153 [ - + ]: 1091 : if (infer_fn->anal_state == FnAnalStateInvalid) {
4154 : 0 : return false;
4155 [ + - ]: 1091 : } else if (infer_fn->anal_state == FnAnalStateReady) {
4156 : 1091 : analyze_fn_body(g, infer_fn);
4157 [ - + ]: 1091 : if (err_set_type->data.error_set.infer_fn != nullptr) {
4158 : 0 : assert(g->errors.length != 0);
4159 : 0 : return false;
4160 : : }
4161 : : } else {
4162 : 0 : add_node_error(g, source_node,
4163 : : buf_sprintf("cannot resolve inferred error set '%s': function '%s' not fully analyzed yet",
4164 : 0 : buf_ptr(&err_set_type->name), buf_ptr(&err_set_type->data.error_set.infer_fn->symbol_name)));
4165 : 0 : return false;
4166 : : }
4167 : : }
4168 : 16912 : return true;
4169 : : }
4170 : :
4171 : 2960 : static void resolve_async_fn_frame(CodeGen *g, ZigFn *fn) {
4172 : 2960 : ZigType *frame_type = get_fn_frame_type(g, fn);
4173 : : Error err;
4174 [ - + ]: 2960 : if ((err = type_resolve(g, frame_type, ResolveStatusSizeKnown))) {
4175 [ # # ][ # # ]: 0 : if (g->trace_err != nullptr && frame_type->data.frame.resolve_loop_src_node != nullptr &&
[ # # ]
4176 : 0 : !frame_type->data.frame.reported_loop_err)
4177 : : {
4178 : 0 : frame_type->data.frame.reported_loop_err = true;
4179 : 0 : g->trace_err = add_error_note(g, g->trace_err, frame_type->data.frame.resolve_loop_src_node,
4180 : : buf_sprintf("when analyzing type '%s' here", buf_ptr(&frame_type->name)));
4181 : : }
4182 : 0 : fn->anal_state = FnAnalStateInvalid;
4183 : 0 : return;
4184 : : }
4185 : : }
4186 : :
4187 : 379968 : bool fn_is_async(ZigFn *fn) {
4188 : 379968 : assert(fn->inferred_async_node != nullptr);
4189 : 379968 : assert(fn->inferred_async_node != inferred_async_checking);
4190 : 379968 : return fn->inferred_async_node != inferred_async_none;
4191 : : }
4192 : :
4193 : 0 : void add_async_error_notes(CodeGen *g, ErrorMsg *msg, ZigFn *fn) {
4194 : 0 : assert(fn->inferred_async_node != nullptr);
4195 : 0 : assert(fn->inferred_async_node != inferred_async_checking);
4196 : 0 : assert(fn->inferred_async_node != inferred_async_none);
4197 [ # # ]: 0 : if (fn->inferred_async_fn != nullptr) {
4198 : : ErrorMsg *new_msg;
4199 [ # # ]: 0 : if (fn->inferred_async_node->type == NodeTypeAwaitExpr) {
4200 : 0 : new_msg = add_error_note(g, msg, fn->inferred_async_node,
4201 : : buf_create_from_str("await here is a suspend point"));
4202 : : } else {
4203 : 0 : new_msg = add_error_note(g, msg, fn->inferred_async_node,
4204 : : buf_sprintf("async function call here"));
4205 : : }
4206 : 0 : return add_async_error_notes(g, new_msg, fn->inferred_async_fn);
4207 [ # # ]: 0 : } else if (fn->inferred_async_node->type == NodeTypeFnProto) {
4208 : 0 : add_error_note(g, msg, fn->inferred_async_node,
4209 : : buf_sprintf("async calling convention here"));
4210 [ # # ]: 0 : } else if (fn->inferred_async_node->type == NodeTypeSuspend) {
4211 : 0 : add_error_note(g, msg, fn->inferred_async_node,
4212 : : buf_sprintf("suspends here"));
4213 [ # # ]: 0 : } else if (fn->inferred_async_node->type == NodeTypeAwaitExpr) {
4214 : 0 : add_error_note(g, msg, fn->inferred_async_node,
4215 : : buf_sprintf("await here is a suspend point"));
4216 [ # # ][ # # ]: 0 : } else if (fn->inferred_async_node->type == NodeTypeFnCallExpr &&
4217 : 0 : fn->inferred_async_node->data.fn_call_expr.is_builtin)
4218 : : {
4219 : 0 : add_error_note(g, msg, fn->inferred_async_node,
4220 : : buf_sprintf("@frame() causes function to be async"));
4221 : : } else {
4222 : 0 : add_error_note(g, msg, fn->inferred_async_node,
4223 : : buf_sprintf("suspends here"));
4224 : : }
4225 : : }
4226 : :
4227 : : // ErrorNone - not async
4228 : : // ErrorIsAsync - yes async
4229 : : // ErrorSemanticAnalyzeFail - compile error emitted result is invalid
4230 : 41818 : static Error analyze_callee_async(CodeGen *g, ZigFn *fn, ZigFn *callee, AstNode *call_node,
4231 : : bool must_not_be_async)
4232 : : {
4233 [ + + ]: 41818 : if (callee->type_entry->data.fn.fn_type_id.cc != CallingConventionUnspecified)
4234 : 264 : return ErrorNone;
4235 [ + + ]: 41554 : if (callee->anal_state == FnAnalStateReady) {
4236 : 48 : analyze_fn_body(g, callee);
4237 [ - + ]: 48 : if (callee->anal_state == FnAnalStateInvalid) {
4238 : 0 : return ErrorSemanticAnalyzeFail;
4239 : : }
4240 : : }
4241 : : bool callee_is_async;
4242 [ + - ]: 41554 : if (callee->anal_state == FnAnalStateComplete) {
4243 : 41554 : analyze_fn_async(g, callee, true);
4244 [ - + ]: 41554 : if (callee->anal_state == FnAnalStateInvalid) {
4245 : 0 : return ErrorSemanticAnalyzeFail;
4246 : : }
4247 : 41554 : callee_is_async = fn_is_async(callee);
4248 : : } else {
4249 : : // If it's already been determined, use that value. Otherwise
4250 : : // assume non-async, emit an error later if it turned out to be async.
4251 [ # # ][ # # ]: 0 : if (callee->inferred_async_node == nullptr ||
4252 : 0 : callee->inferred_async_node == inferred_async_checking)
4253 : : {
4254 : 0 : callee->assumed_non_async = call_node;
4255 : 0 : callee_is_async = false;
4256 : : } else {
4257 : 0 : callee_is_async = callee->inferred_async_node != inferred_async_none;
4258 : : }
4259 : : }
4260 [ + + ]: 41554 : if (callee_is_async) {
4261 : 312 : fn->inferred_async_node = call_node;
4262 : 312 : fn->inferred_async_fn = callee;
4263 [ - + ]: 312 : if (must_not_be_async) {
4264 : 0 : ErrorMsg *msg = add_node_error(g, fn->proto_node,
4265 : : buf_sprintf("function with calling convention '%s' cannot be async",
4266 : 0 : calling_convention_name(fn->type_entry->data.fn.fn_type_id.cc)));
4267 : 0 : add_async_error_notes(g, msg, fn);
4268 : 0 : return ErrorSemanticAnalyzeFail;
4269 : : }
4270 [ - + ]: 312 : if (fn->assumed_non_async != nullptr) {
4271 : 0 : ErrorMsg *msg = add_node_error(g, fn->proto_node,
4272 : : buf_sprintf("unable to infer whether '%s' should be async",
4273 : 0 : buf_ptr(&fn->symbol_name)));
4274 : 0 : add_error_note(g, msg, fn->assumed_non_async,
4275 : : buf_sprintf("assumed to be non-async here"));
4276 : 0 : add_async_error_notes(g, msg, fn);
4277 : 0 : fn->anal_state = FnAnalStateInvalid;
4278 : 0 : return ErrorSemanticAnalyzeFail;
4279 : : }
4280 : 312 : return ErrorIsAsync;
4281 : : }
4282 : 41242 : return ErrorNone;
4283 : : }
4284 : :
4285 : : // This function resolves functions being inferred async.
4286 : 107833 : static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {
4287 [ + + ]: 107833 : if (fn->inferred_async_node == inferred_async_checking) {
4288 : : // TODO call graph cycle detected, disallow the recursion
4289 : 65 : fn->inferred_async_node = inferred_async_none;
4290 : 65 : return;
4291 : : }
4292 [ + + ]: 107768 : if (fn->inferred_async_node == inferred_async_none) {
4293 : 80504 : return;
4294 : : }
4295 [ + + ]: 27264 : if (fn->inferred_async_node != nullptr) {
4296 [ + + ]: 3472 : if (resolve_frame) {
4297 : 2672 : resolve_async_fn_frame(g, fn);
4298 : : }
4299 : 3472 : return;
4300 : : }
4301 : 23792 : fn->inferred_async_node = inferred_async_checking;
4302 : :
4303 : 23792 : bool must_not_be_async = false;
4304 [ + + ]: 23792 : if (fn->type_entry->data.fn.fn_type_id.cc != CallingConventionUnspecified) {
4305 : 4015 : must_not_be_async = true;
4306 : 4015 : fn->inferred_async_node = inferred_async_none;
4307 : : }
4308 : :
4309 [ + + ]: 67555 : for (size_t i = 0; i < fn->call_list.length; i += 1) {
4310 : 43931 : IrInstructionCallGen *call = fn->call_list.at(i);
4311 [ + + ]: 43931 : if (call->fn_entry == nullptr) {
4312 : : // TODO function pointer call here, could be anything
4313 : 2537 : continue;
4314 : : }
4315 [ - + + - ]: 41394 : switch (analyze_callee_async(g, fn, call->fn_entry, call->base.source_node, must_not_be_async)) {
4316 : 0 : case ErrorSemanticAnalyzeFail:
4317 : 0 : fn->anal_state = FnAnalStateInvalid;
4318 : 0 : return;
4319 : 41226 : case ErrorNone:
4320 : 41226 : continue;
4321 : 168 : case ErrorIsAsync:
4322 [ + + ]: 168 : if (resolve_frame) {
4323 : 144 : resolve_async_fn_frame(g, fn);
4324 : : }
4325 : 168 : return;
4326 : 0 : default:
4327 : 0 : zig_unreachable();
4328 : : }
4329 : : }
4330 [ + + ]: 23904 : for (size_t i = 0; i < fn->await_list.length; i += 1) {
4331 : 424 : IrInstructionAwaitGen *await = fn->await_list.at(i);
4332 [ - + + - ]: 424 : switch (analyze_callee_async(g, fn, await->target_fn, await->base.source_node, must_not_be_async)) {
4333 : 0 : case ErrorSemanticAnalyzeFail:
4334 : 0 : fn->anal_state = FnAnalStateInvalid;
4335 : 0 : return;
4336 : 280 : case ErrorNone:
4337 : 280 : continue;
4338 : 144 : case ErrorIsAsync:
4339 [ + - ]: 144 : if (resolve_frame) {
4340 : 144 : resolve_async_fn_frame(g, fn);
4341 : : }
4342 : 144 : return;
4343 : 0 : default:
4344 : 0 : zig_unreachable();
4345 : : }
4346 : : }
4347 : 23480 : fn->inferred_async_node = inferred_async_none;
4348 : : }
4349 : :
4350 : 24304 : static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) {
4351 : 24304 : ZigType *fn_type = fn->type_entry;
4352 : 24304 : assert(!fn_type->data.fn.is_generic);
4353 : 24304 : FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
4354 : :
4355 : 24304 : ZigType *block_return_type = ir_analyze(g, &fn->ir_executable,
4356 : 24304 : &fn->analyzed_executable, fn_type_id->return_type, return_type_node);
4357 : 24304 : fn->src_implicit_return_type = block_return_type;
4358 : :
4359 [ - + ][ - + ]: 24304 : if (type_is_invalid(block_return_type) || fn->analyzed_executable.first_err_trace_msg != nullptr) {
[ + - ]
4360 : 0 : assert(g->errors.length > 0);
4361 : 0 : fn->anal_state = FnAnalStateInvalid;
4362 : 0 : return;
4363 : : }
4364 : :
4365 [ + + ]: 24304 : if (fn_type_id->return_type->id == ZigTypeIdErrorUnion) {
4366 : 11145 : ZigType *return_err_set_type = fn_type_id->return_type->data.error_union.err_set_type;
4367 [ + + ]: 11145 : if (return_err_set_type->data.error_set.infer_fn != nullptr) {
4368 : : ZigType *inferred_err_set_type;
4369 [ + + ]: 1239 : if (fn->src_implicit_return_type->id == ZigTypeIdErrorSet) {
4370 : 73 : inferred_err_set_type = fn->src_implicit_return_type;
4371 [ + - ]: 1166 : } else if (fn->src_implicit_return_type->id == ZigTypeIdErrorUnion) {
4372 : 1166 : inferred_err_set_type = fn->src_implicit_return_type->data.error_union.err_set_type;
4373 : : } else {
4374 : 0 : add_node_error(g, return_type_node,
4375 : : buf_sprintf("function with inferred error set must return at least one possible error"));
4376 : 0 : fn->anal_state = FnAnalStateInvalid;
4377 : 0 : return;
4378 : : }
4379 : :
4380 [ + + ]: 1239 : if (inferred_err_set_type->data.error_set.infer_fn != nullptr) {
4381 [ - + ]: 69 : if (!resolve_inferred_error_set(g, inferred_err_set_type, return_type_node)) {
4382 : 0 : fn->anal_state = FnAnalStateInvalid;
4383 : 0 : return;
4384 : : }
4385 : : }
4386 : :
4387 : 1239 : return_err_set_type->data.error_set.infer_fn = nullptr;
4388 [ + + ]: 1239 : if (type_is_global_error_set(inferred_err_set_type)) {
4389 : 445 : return_err_set_type->data.error_set.err_count = UINT32_MAX;
4390 : : } else {
4391 : 794 : return_err_set_type->data.error_set.err_count = inferred_err_set_type->data.error_set.err_count;
4392 [ + - ]: 794 : if (inferred_err_set_type->data.error_set.err_count > 0) {
4393 : 794 : return_err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(inferred_err_set_type->data.error_set.err_count);
4394 [ + + ]: 14556 : for (uint32_t i = 0; i < inferred_err_set_type->data.error_set.err_count; i += 1) {
4395 : 3411 : return_err_set_type->data.error_set.errors[i] = inferred_err_set_type->data.error_set.errors[i];
4396 : : }
4397 : : }
4398 : : }
4399 : : }
4400 : : }
4401 : :
4402 : 24304 : CallingConvention cc = fn->type_entry->data.fn.fn_type_id.cc;
4403 [ + + ][ + + ]: 24304 : if (cc != CallingConventionUnspecified && cc != CallingConventionAsync &&
[ - + ]
4404 [ # # ]: 0 : fn->inferred_async_node != nullptr &&
4405 [ # # ]: 0 : fn->inferred_async_node != inferred_async_checking &&
4406 : 0 : fn->inferred_async_node != inferred_async_none)
4407 : : {
4408 : 0 : ErrorMsg *msg = add_node_error(g, fn->proto_node,
4409 : : buf_sprintf("function with calling convention '%s' cannot be async",
4410 : 0 : calling_convention_name(cc)));
4411 : 0 : add_async_error_notes(g, msg, fn);
4412 : 0 : fn->anal_state = FnAnalStateInvalid;
4413 : : }
4414 : :
4415 [ - + ]: 24304 : if (g->verbose_ir) {
4416 : 0 : fprintf(stderr, "fn %s() { // (analyzed)\n", buf_ptr(&fn->symbol_name));
4417 : 0 : ir_print(g, stderr, &fn->analyzed_executable, 4, IrPassGen);
4418 : 0 : fprintf(stderr, "}\n");
4419 : : }
4420 : 24304 : fn->anal_state = FnAnalStateComplete;
4421 : : }
4422 : :
4423 : 28115 : static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
4424 : 28115 : assert(fn_table_entry->anal_state != FnAnalStateProbing);
4425 [ + + ]: 28115 : if (fn_table_entry->anal_state != FnAnalStateReady)
4426 : 3811 : return;
4427 : :
4428 : 24304 : fn_table_entry->anal_state = FnAnalStateProbing;
4429 : :
4430 [ + - ]: 24304 : AstNode *return_type_node = (fn_table_entry->proto_node != nullptr) ?
4431 : 24304 : fn_table_entry->proto_node->data.fn_proto.return_type : fn_table_entry->fndef_scope->base.source_node;
4432 : :
4433 : 24304 : assert(fn_table_entry->fndef_scope);
4434 [ + + ]: 24304 : if (!fn_table_entry->child_scope)
4435 : 17856 : fn_table_entry->child_scope = &fn_table_entry->fndef_scope->base;
4436 : :
4437 : 24304 : define_local_param_variables(g, fn_table_entry);
4438 : :
4439 : 24304 : ZigType *fn_type = fn_table_entry->type_entry;
4440 : 24304 : assert(!fn_type->data.fn.is_generic);
4441 : :
4442 : 24304 : ir_gen_fn(g, fn_table_entry);
4443 [ - + ]: 24304 : if (fn_table_entry->ir_executable.first_err_trace_msg != nullptr) {
4444 : 0 : fn_table_entry->anal_state = FnAnalStateInvalid;
4445 : 0 : return;
4446 : : }
4447 [ - + ]: 24304 : if (g->verbose_ir) {
4448 : 0 : fprintf(stderr, "\n");
4449 : 0 : ast_render(stderr, fn_table_entry->body_node, 4);
4450 : 0 : fprintf(stderr, "\nfn %s() { // (IR)\n", buf_ptr(&fn_table_entry->symbol_name));
4451 : 0 : ir_print(g, stderr, &fn_table_entry->ir_executable, 4, IrPassSrc);
4452 : 0 : fprintf(stderr, "}\n");
4453 : : }
4454 : :
4455 : 24304 : analyze_fn_ir(g, fn_table_entry, return_type_node);
4456 : : }
4457 : :
4458 : 1804 : ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Buf *source_code,
4459 : : SourceKind source_kind)
4460 : : {
4461 [ - + ]: 1804 : if (g->verbose_tokenize) {
4462 : 0 : fprintf(stderr, "\nOriginal Source (%s):\n", buf_ptr(resolved_path));
4463 : 0 : fprintf(stderr, "----------------\n");
4464 : 0 : fprintf(stderr, "%s\n", buf_ptr(source_code));
4465 : :
4466 : 0 : fprintf(stderr, "\nTokens:\n");
4467 : 0 : fprintf(stderr, "---------\n");
4468 : : }
4469 : :
4470 : 1804 : Tokenization tokenization = {0};
4471 : 1804 : tokenize(source_code, &tokenization);
4472 : :
4473 [ - + ]: 1804 : if (tokenization.err) {
4474 : 0 : ErrorMsg *err = err_msg_create_with_line(resolved_path, tokenization.err_line, tokenization.err_column,
4475 : 0 : source_code, tokenization.line_offsets, tokenization.err);
4476 : :
4477 : 0 : print_err_msg(err, g->err_color);
4478 : 0 : exit(1);
4479 : : }
4480 : :
4481 [ - + ]: 1804 : if (g->verbose_tokenize) {
4482 : 0 : print_tokens(source_code, tokenization.tokens);
4483 : :
4484 : 0 : fprintf(stderr, "\nAST:\n");
4485 : 0 : fprintf(stderr, "------\n");
4486 : : }
4487 : :
4488 : 1804 : Buf *src_dirname = buf_alloc();
4489 : 1804 : Buf *src_basename = buf_alloc();
4490 : 1804 : os_path_split(resolved_path, src_dirname, src_basename);
4491 : :
4492 : 1804 : Buf noextname = BUF_INIT;
4493 : 1804 : os_path_extname(resolved_path, &noextname, nullptr);
4494 : :
4495 : 1804 : Buf *pkg_root_src_dir = &package->root_src_dir;
4496 : 1804 : Buf resolved_root_src_dir = os_path_resolve(&pkg_root_src_dir, 1);
4497 : :
4498 : 1804 : Buf *namespace_name = buf_create_from_buf(&package->pkg_path);
4499 [ + + ]: 1804 : if (source_kind == SourceKindNonRoot) {
4500 : 1713 : assert(buf_starts_with_buf(resolved_path, &resolved_root_src_dir));
4501 [ + + ]: 1713 : if (buf_len(namespace_name) != 0) {
4502 : 577 : buf_append_char(namespace_name, NAMESPACE_SEP_CHAR);
4503 : : }
4504 : : // The namespace components are obtained from the relative path to the
4505 : : // source directory
4506 [ + - ]: 1713 : if (buf_len(&noextname) > buf_len(&resolved_root_src_dir)) {
4507 : : // Skip the trailing separator
4508 : 1713 : buf_append_mem(namespace_name,
4509 : 1713 : buf_ptr(&noextname) + buf_len(&resolved_root_src_dir) + 1,
4510 : 1713 : buf_len(&noextname) - buf_len(&resolved_root_src_dir) - 1);
4511 : : }
4512 : 1713 : buf_replace(namespace_name, ZIG_OS_SEP_CHAR, NAMESPACE_SEP_CHAR);
4513 : : }
4514 : 1804 : Buf *bare_name = buf_alloc();
4515 : 1804 : os_path_extname(src_basename, bare_name, nullptr);
4516 : :
4517 : 1804 : RootStruct *root_struct = allocate<RootStruct>(1);
4518 : 1804 : root_struct->package = package;
4519 : 1804 : root_struct->source_code = source_code;
4520 : 1804 : root_struct->line_offsets = tokenization.line_offsets;
4521 : 1804 : root_struct->path = resolved_path;
4522 : 1804 : root_struct->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname));
4523 : 1804 : ZigType *import_entry = get_root_container_type(g, buf_ptr(namespace_name), bare_name, root_struct);
4524 [ + + ]: 1804 : if (source_kind == SourceKindRoot) {
4525 : 20 : assert(g->root_import == nullptr);
4526 : 20 : g->root_import = import_entry;
4527 : : }
4528 : 1804 : g->import_table.put(resolved_path, import_entry);
4529 : :
4530 : 1804 : AstNode *root_node = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color);
4531 : 1804 : assert(root_node != nullptr);
4532 : 1804 : assert(root_node->type == NodeTypeContainerDecl);
4533 : 1804 : import_entry->data.structure.decl_node = root_node;
4534 : 1804 : import_entry->data.structure.decls_scope->base.source_node = root_node;
4535 [ - + ]: 1804 : if (g->verbose_ast) {
4536 : 0 : ast_print(stderr, root_node, 0);
4537 : : }
4538 : :
4539 [ + + ][ + + ]: 1804 : if (source_kind == SourceKindRoot || package == g->panic_package) {
4540 : : // Look for panic and main
4541 [ + + ]: 3889 : for (size_t decl_i = 0; decl_i < root_node->data.container_decl.decls.length; decl_i += 1) {
4542 : 3860 : AstNode *top_level_decl = root_node->data.container_decl.decls.at(decl_i);
4543 : :
4544 [ + + ]: 3860 : if (top_level_decl->type == NodeTypeFnDef) {
4545 : 3697 : AstNode *proto_node = top_level_decl->data.fn_def.fn_proto;
4546 : 3697 : assert(proto_node->type == NodeTypeFnProto);
4547 : 3697 : Buf *proto_name = proto_node->data.fn_proto.name;
4548 : :
4549 : 3697 : bool is_pub = (proto_node->data.fn_proto.visib_mod == VisibModPub);
4550 [ + + ]: 3697 : if (is_pub) {
4551 [ + + ]: 16 : if (buf_eql_str(proto_name, "main")) {
4552 : 1 : g->have_pub_main = true;
4553 [ + - ]: 15 : } else if (buf_eql_str(proto_name, "panic")) {
4554 : 3697 : g->have_pub_panic = true;
4555 : : }
4556 : : }
4557 : : }
4558 : : }
4559 : : }
4560 : :
4561 [ + + ]: 63396 : for (size_t decl_i = 0; decl_i < root_node->data.container_decl.decls.length; decl_i += 1) {
4562 : 61592 : AstNode *top_level_decl = root_node->data.container_decl.decls.at(decl_i);
4563 : 61592 : scan_decls(g, import_entry->data.structure.decls_scope, top_level_decl);
4564 : : }
4565 : :
4566 : 1804 : TldContainer *tld_container = allocate<TldContainer>(1);
4567 : 1804 : init_tld(&tld_container->base, TldIdContainer, namespace_name, VisibModPub, root_node, nullptr);
4568 : 1804 : tld_container->type_entry = import_entry;
4569 : 1804 : tld_container->decls_scope = import_entry->data.structure.decls_scope;
4570 : 1804 : g->resolve_queue.append(&tld_container->base);
4571 : :
4572 : 1804 : return import_entry;
4573 : : }
4574 : :
4575 : 48 : void semantic_analyze(CodeGen *g) {
4576 [ + + ][ - + ]: 110 : while (g->resolve_queue_index < g->resolve_queue.length ||
4577 : 48 : g->fn_defs_index < g->fn_defs.length)
4578 : : {
4579 [ + + ]: 17174 : for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) {
4580 : 17112 : Tld *tld = g->resolve_queue.at(g->resolve_queue_index);
4581 : 17112 : g->trace_err = nullptr;
4582 : 17112 : AstNode *source_node = nullptr;
4583 : 17112 : resolve_top_level_decl(g, tld, source_node, false);
4584 : : }
4585 : :
4586 [ + + ]: 24366 : for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) {
4587 : 24304 : ZigFn *fn_entry = g->fn_defs.at(g->fn_defs_index);
4588 : 24304 : g->trace_err = nullptr;
4589 : 24304 : analyze_fn_body(g, fn_entry);
4590 : : }
4591 : : }
4592 : :
4593 [ - + ]: 48 : if (g->errors.length != 0) {
4594 : 0 : return;
4595 : : }
4596 : :
4597 : : // second pass over functions for detecting async
4598 [ + + ]: 63143 : for (g->fn_defs_index = 0; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) {
4599 : 63095 : ZigFn *fn = g->fn_defs.at(g->fn_defs_index);
4600 : 63095 : g->trace_err = nullptr;
4601 : 63095 : analyze_fn_async(g, fn, true);
4602 [ - + ]: 63095 : if (fn->anal_state == FnAnalStateInvalid)
4603 : 0 : continue;
4604 [ + + ][ - + ]: 63095 : if (fn_is_async(fn) && fn->non_async_node != nullptr) {
[ - + ]
4605 : 0 : ErrorMsg *msg = add_node_error(g, fn->proto_node,
4606 : 0 : buf_sprintf("'%s' cannot be async", buf_ptr(&fn->symbol_name)));
4607 : 0 : add_error_note(g, msg, fn->non_async_node,
4608 : : buf_sprintf("required to be non-async here"));
4609 : 0 : add_async_error_notes(g, msg, fn);
4610 : : }
4611 : : }
4612 : : }
4613 : :
4614 : 114021 : ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
4615 : 114021 : assert(size_in_bits <= 65535);
4616 : 114021 : TypeId type_id = {};
4617 : 114021 : type_id.id = ZigTypeIdInt;
4618 : 114021 : type_id.data.integer.is_signed = is_signed;
4619 : 114021 : type_id.data.integer.bit_count = size_in_bits;
4620 : :
4621 : : {
4622 : 114021 : auto entry = g->type_table.maybe_get(type_id);
4623 [ + + ]: 114021 : if (entry)
4624 : 113527 : return entry->value;
4625 : : }
4626 : :
4627 : 494 : ZigType *new_entry = make_int_type(g, is_signed, size_in_bits);
4628 : 494 : g->type_table.put(type_id, new_entry);
4629 : 114021 : return new_entry;
4630 : : }
4631 : :
4632 : 444 : bool is_valid_vector_elem_type(ZigType *elem_type) {
4633 [ - + ]: 80 : return elem_type->id == ZigTypeIdInt ||
4634 [ + + # # ]: 524 : elem_type->id == ZigTypeIdFloat ||
4635 : 444 : get_codegen_ptr_type(elem_type) != nullptr;
4636 : : }
4637 : :
4638 : 222 : ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type) {
4639 : 222 : assert(is_valid_vector_elem_type(elem_type));
4640 : :
4641 : 222 : TypeId type_id = {};
4642 : 222 : type_id.id = ZigTypeIdVector;
4643 : 222 : type_id.data.vector.len = len;
4644 : 222 : type_id.data.vector.elem_type = elem_type;
4645 : :
4646 : : {
4647 : 222 : auto entry = g->type_table.maybe_get(type_id);
4648 [ + + ]: 222 : if (entry)
4649 : 197 : return entry->value;
4650 : : }
4651 : :
4652 : 25 : ZigType *entry = new_type_table_entry(ZigTypeIdVector);
4653 [ + - ][ + - ]: 25 : if ((len != 0) && type_has_bits(elem_type)) {
[ + - ]
4654 : : // Vectors can only be ints, floats, or pointers. ints and floats have trivially resolvable
4655 : : // llvm type refs. pointers we will use usize instead.
4656 : : LLVMTypeRef example_vector_llvm_type;
4657 [ - + ]: 25 : if (elem_type->id == ZigTypeIdPointer) {
4658 : 0 : example_vector_llvm_type = LLVMVectorType(g->builtin_types.entry_usize->llvm_type, len);
4659 : : } else {
4660 : 25 : example_vector_llvm_type = LLVMVectorType(elem_type->llvm_type, len);
4661 : : }
4662 : 25 : assert(example_vector_llvm_type != nullptr);
4663 : 25 : entry->size_in_bits = elem_type->size_in_bits * len;
4664 : 25 : entry->abi_size = LLVMABISizeOfType(g->target_data_ref, example_vector_llvm_type);
4665 : 25 : entry->abi_align = LLVMABIAlignmentOfType(g->target_data_ref, example_vector_llvm_type);
4666 : : }
4667 : 25 : entry->data.vector.len = len;
4668 : 25 : entry->data.vector.elem_type = elem_type;
4669 : :
4670 : 25 : buf_resize(&entry->name, 0);
4671 : 25 : buf_appendf(&entry->name, "@Vector(%u, %s)", len, buf_ptr(&elem_type->name));
4672 : :
4673 : 25 : g->type_table.put(type_id, entry);
4674 : 222 : return entry;
4675 : : }
4676 : :
4677 : 192 : ZigType **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type) {
4678 : 192 : return &g->builtin_types.entry_c_int[c_int_type];
4679 : : }
4680 : :
4681 : 24 : ZigType *get_c_int_type(CodeGen *g, CIntType c_int_type) {
4682 : 24 : return *get_c_int_type_ptr(g, c_int_type);
4683 : : }
4684 : :
4685 : 641839 : bool handle_is_ptr(ZigType *type_entry) {
4686 [ - + + + : 641839 : switch (type_entry->id) {
+ + - ]
4687 : 0 : case ZigTypeIdInvalid:
4688 : : case ZigTypeIdMetaType:
4689 : : case ZigTypeIdComptimeFloat:
4690 : : case ZigTypeIdComptimeInt:
4691 : : case ZigTypeIdEnumLiteral:
4692 : : case ZigTypeIdUndefined:
4693 : : case ZigTypeIdNull:
4694 : : case ZigTypeIdBoundFn:
4695 : : case ZigTypeIdArgTuple:
4696 : : case ZigTypeIdOpaque:
4697 : 0 : zig_unreachable();
4698 : 347906 : case ZigTypeIdUnreachable:
4699 : : case ZigTypeIdVoid:
4700 : : case ZigTypeIdBool:
4701 : : case ZigTypeIdInt:
4702 : : case ZigTypeIdFloat:
4703 : : case ZigTypeIdPointer:
4704 : : case ZigTypeIdErrorSet:
4705 : : case ZigTypeIdFn:
4706 : : case ZigTypeIdEnum:
4707 : : case ZigTypeIdVector:
4708 : : case ZigTypeIdAnyFrame:
4709 : 347906 : return false;
4710 : 83639 : case ZigTypeIdArray:
4711 : : case ZigTypeIdStruct:
4712 : : case ZigTypeIdFnFrame:
4713 : 83639 : return type_has_bits(type_entry);
4714 : 193762 : case ZigTypeIdErrorUnion:
4715 : 193762 : return type_has_bits(type_entry->data.error_union.payload_type);
4716 : 14735 : case ZigTypeIdOptional:
4717 [ + + ]: 29086 : return type_has_bits(type_entry->data.maybe.child_type) &&
4718 [ + + ][ + + ]: 29086 : !type_is_nonnull_ptr(type_entry->data.maybe.child_type) &&
4719 : 14735 : type_entry->data.maybe.child_type->id != ZigTypeIdErrorSet;
4720 : 1797 : case ZigTypeIdUnion:
4721 [ + + ][ + + ]: 1797 : return type_has_bits(type_entry) && type_entry->data.unionation.gen_field_count != 0;
4722 : :
4723 : : }
4724 : 0 : zig_unreachable();
4725 : : }
4726 : :
4727 : 495126 : static uint32_t hash_ptr(void *ptr) {
4728 : 495126 : return (uint32_t)(((uintptr_t)ptr) % UINT32_MAX);
4729 : : }
4730 : :
4731 : 32 : static uint32_t hash_size(size_t x) {
4732 : 32 : return (uint32_t)(x % UINT32_MAX);
4733 : : }
4734 : :
4735 : 0 : uint32_t fn_table_entry_hash(ZigFn* value) {
4736 : 0 : return ptr_hash(value);
4737 : : }
4738 : :
4739 : 0 : bool fn_table_entry_eql(ZigFn *a, ZigFn *b) {
4740 : 0 : return ptr_eq(a, b);
4741 : : }
4742 : :
4743 : 43334 : uint32_t fn_type_id_hash(FnTypeId *id) {
4744 : 43334 : uint32_t result = 0;
4745 : 43334 : result += ((uint32_t)(id->cc)) * (uint32_t)3349388391;
4746 [ + + ]: 43334 : result += id->is_var_args ? (uint32_t)1931444534 : 0;
4747 : 43334 : result += hash_ptr(id->return_type);
4748 : 43334 : result += id->alignment * 0xd3b3f3e2;
4749 [ + + ]: 113495 : for (size_t i = 0; i < id->param_count; i += 1) {
4750 : 70161 : FnTypeParamInfo *info = &id->param_info[i];
4751 [ + + ]: 70161 : result += info->is_noalias ? (uint32_t)892356923 : 0;
4752 : 70161 : result += hash_ptr(info->type);
4753 : : }
4754 : 43334 : return result;
4755 : : }
4756 : :
4757 : 178645 : bool fn_type_id_eql(FnTypeId *a, FnTypeId *b) {
4758 [ + + ][ + + ]: 178645 : if (a->cc != b->cc ||
4759 [ + - ]: 24744 : a->return_type != b->return_type ||
4760 [ + + ]: 24744 : a->is_var_args != b->is_var_args ||
4761 [ + + ]: 17705 : a->param_count != b->param_count ||
4762 : 17705 : a->alignment != b->alignment)
4763 : : {
4764 : 160970 : return false;
4765 : : }
4766 [ + + ]: 34230 : for (size_t i = 0; i < a->param_count; i += 1) {
4767 : 21298 : FnTypeParamInfo *a_param_info = &a->param_info[i];
4768 : 21298 : FnTypeParamInfo *b_param_info = &b->param_info[i];
4769 : :
4770 [ + + ][ - + ]: 21298 : if (a_param_info->type != b_param_info->type ||
4771 : 16555 : a_param_info->is_noalias != b_param_info->is_noalias)
4772 : : {
4773 : 4743 : return false;
4774 : : }
4775 : : }
4776 : 12932 : return true;
4777 : : }
4778 : :
4779 : 160 : static uint32_t hash_const_val_error_set(ConstExprValue *const_val) {
4780 : 160 : assert(const_val->data.x_err_set != nullptr);
4781 : 160 : return const_val->data.x_err_set->value ^ 2630160122;
4782 : : }
4783 : :
4784 : 128 : static uint32_t hash_const_val_ptr(ConstExprValue *const_val) {
4785 : 128 : uint32_t hash_val = 0;
4786 [ - + - - ]: 128 : switch (const_val->data.x_ptr.mut) {
4787 : 0 : case ConstPtrMutRuntimeVar:
4788 : 0 : hash_val += (uint32_t)3500721036;
4789 : 0 : break;
4790 : 128 : case ConstPtrMutComptimeConst:
4791 : 128 : hash_val += (uint32_t)4214318515;
4792 : 128 : break;
4793 : 0 : case ConstPtrMutInfer:
4794 : : case ConstPtrMutComptimeVar:
4795 : 0 : hash_val += (uint32_t)1103195694;
4796 : 0 : break;
4797 : : }
4798 [ - + - + : 128 : switch (const_val->data.x_ptr.special) {
- - - - -
- - - ]
4799 : 0 : case ConstPtrSpecialInvalid:
4800 : 0 : zig_unreachable();
4801 : 96 : case ConstPtrSpecialRef:
4802 : 96 : hash_val += (uint32_t)2478261866;
4803 : 96 : hash_val += hash_ptr(const_val->data.x_ptr.data.ref.pointee);
4804 : 96 : return hash_val;
4805 : 0 : case ConstPtrSpecialBaseArray:
4806 : 0 : hash_val += (uint32_t)1764906839;
4807 : 0 : hash_val += hash_ptr(const_val->data.x_ptr.data.base_array.array_val);
4808 : 0 : hash_val += hash_size(const_val->data.x_ptr.data.base_array.elem_index);
4809 [ # # ]: 0 : hash_val += const_val->data.x_ptr.data.base_array.is_cstr ? 1297263887 : 200363492;
4810 : 0 : return hash_val;
4811 : 32 : case ConstPtrSpecialBaseStruct:
4812 : 32 : hash_val += (uint32_t)3518317043;
4813 : 32 : hash_val += hash_ptr(const_val->data.x_ptr.data.base_struct.struct_val);
4814 : 32 : hash_val += hash_size(const_val->data.x_ptr.data.base_struct.field_index);
4815 : 32 : return hash_val;
4816 : 0 : case ConstPtrSpecialBaseErrorUnionCode:
4817 : 0 : hash_val += (uint32_t)2994743799;
4818 : 0 : hash_val += hash_ptr(const_val->data.x_ptr.data.base_err_union_code.err_union_val);
4819 : 0 : return hash_val;
4820 : 0 : case ConstPtrSpecialBaseErrorUnionPayload:
4821 : 0 : hash_val += (uint32_t)3456080131;
4822 : 0 : hash_val += hash_ptr(const_val->data.x_ptr.data.base_err_union_payload.err_union_val);
4823 : 0 : return hash_val;
4824 : 0 : case ConstPtrSpecialBaseOptionalPayload:
4825 : 0 : hash_val += (uint32_t)3163140517;
4826 : 0 : hash_val += hash_ptr(const_val->data.x_ptr.data.base_optional_payload.optional_val);
4827 : 0 : return hash_val;
4828 : 0 : case ConstPtrSpecialHardCodedAddr:
4829 : 0 : hash_val += (uint32_t)4048518294;
4830 : 0 : hash_val += hash_size(const_val->data.x_ptr.data.hard_coded_addr.addr);
4831 : 0 : return hash_val;
4832 : 0 : case ConstPtrSpecialDiscard:
4833 : 0 : hash_val += 2010123162;
4834 : 0 : return hash_val;
4835 : 0 : case ConstPtrSpecialFunction:
4836 : 0 : hash_val += (uint32_t)2590901619;
4837 : 0 : hash_val += hash_ptr(const_val->data.x_ptr.data.fn.fn_entry);
4838 : 0 : return hash_val;
4839 : 0 : case ConstPtrSpecialNull:
4840 : 0 : hash_val += (uint32_t)1486246455;
4841 : 0 : return hash_val;
4842 : : }
4843 : 0 : zig_unreachable();
4844 : : }
4845 : :
4846 : 157550 : static uint32_t hash_const_val(ConstExprValue *const_val) {
4847 : 157550 : assert(const_val->special == ConstValSpecialStatic);
4848 [ - + + + : 157550 : switch (const_val->type->id) {
+ - + + -
- + + - -
+ + + + +
+ - - - -
- ]
4849 : 0 : case ZigTypeIdOpaque:
4850 : 0 : zig_unreachable();
4851 : 12659 : case ZigTypeIdBool:
4852 [ + + ]: 12659 : return const_val->data.x_bool ? (uint32_t)127863866 : (uint32_t)215080464;
4853 : 25320 : case ZigTypeIdMetaType:
4854 : 25320 : return hash_ptr(const_val->data.x_type);
4855 : 16 : case ZigTypeIdVoid:
4856 : 16 : return (uint32_t)4149439618;
4857 : 21928 : case ZigTypeIdInt:
4858 : : case ZigTypeIdComptimeInt:
4859 : : {
4860 : 21928 : uint32_t result = 1331471175;
4861 [ + + ]: 44064 : for (size_t i = 0; i < const_val->data.x_bigint.digit_count; i += 1) {
4862 : 22136 : uint64_t digit = bigint_ptr(&const_val->data.x_bigint)[i];
4863 : 22136 : result ^= ((uint32_t)(digit >> 32)) ^ (uint32_t)(result);
4864 : : }
4865 : 21928 : return result;
4866 : : }
4867 : 0 : case ZigTypeIdEnumLiteral:
4868 : 0 : return buf_hash(const_val->data.x_enum_literal) * 2691276464;
4869 : 116 : case ZigTypeIdEnum:
4870 : : {
4871 : 116 : uint32_t result = 31643936;
4872 [ + + ]: 211 : for (size_t i = 0; i < const_val->data.x_enum_tag.digit_count; i += 1) {
4873 : 95 : uint64_t digit = bigint_ptr(&const_val->data.x_enum_tag)[i];
4874 : 95 : result ^= ((uint32_t)(digit >> 32)) ^ (uint32_t)(result);
4875 : : }
4876 : 116 : return result;
4877 : : }
4878 : 79664 : case ZigTypeIdFloat:
4879 [ + + + + : 79664 : switch (const_val->type->data.floating.bit_count) {
- ]
4880 : 288 : case 16:
4881 : : {
4882 : : uint16_t result;
4883 : : static_assert(sizeof(result) == sizeof(const_val->data.x_f16), "");
4884 : 288 : memcpy(&result, &const_val->data.x_f16, sizeof(result));
4885 : 288 : return result * 65537u;
4886 : : }
4887 : 288 : case 32:
4888 : : {
4889 : : uint32_t result;
4890 : 288 : memcpy(&result, &const_val->data.x_f32, 4);
4891 : 288 : return result ^ 4084870010;
4892 : : }
4893 : 79008 : case 64:
4894 : : {
4895 : : uint32_t ints[2];
4896 : 79008 : memcpy(&ints[0], &const_val->data.x_f64, 8);
4897 : 79008 : return ints[0] ^ ints[1] ^ 0x22ed43c6;
4898 : : }
4899 : 80 : case 128:
4900 : : {
4901 : : uint32_t ints[4];
4902 : 80 : memcpy(&ints[0], &const_val->data.x_f128, 16);
4903 : 80 : return ints[0] ^ ints[1] ^ ints[2] ^ ints[3] ^ 0xb5ffef27;
4904 : : }
4905 : 0 : default:
4906 : 0 : zig_unreachable();
4907 : : }
4908 : 0 : case ZigTypeIdComptimeFloat:
4909 : : {
4910 : 0 : float128_t f128 = bigfloat_to_f128(&const_val->data.x_bigfloat);
4911 : : uint32_t ints[4];
4912 : 0 : memcpy(&ints[0], &f128, 16);
4913 : 0 : return ints[0] ^ ints[1] ^ ints[2] ^ ints[3] ^ 0xed8b3dfb;
4914 : : }
4915 : 0 : case ZigTypeIdArgTuple:
4916 : 0 : return (uint32_t)const_val->data.x_arg_tuple.start_index * (uint32_t)281907309 +
4917 : 0 : (uint32_t)const_val->data.x_arg_tuple.end_index * (uint32_t)2290442768;
4918 : 277 : case ZigTypeIdFn:
4919 : 277 : assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst);
4920 : 277 : assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction);
4921 : 277 : return 3677364617 ^ hash_ptr(const_val->data.x_ptr.data.fn.fn_entry);
4922 : 128 : case ZigTypeIdPointer:
4923 : 128 : return hash_const_val_ptr(const_val);
4924 : 0 : case ZigTypeIdUndefined:
4925 : 0 : return 162837799;
4926 : 0 : case ZigTypeIdNull:
4927 : 0 : return 844854567;
4928 : 96 : case ZigTypeIdArray:
4929 : : // TODO better hashing algorithm
4930 : 96 : return 1166190605;
4931 : 15752 : case ZigTypeIdStruct:
4932 : : // TODO better hashing algorithm
4933 : 15752 : return 1532530855;
4934 : 200 : case ZigTypeIdUnion:
4935 : : // TODO better hashing algorithm
4936 : 200 : return 2709806591;
4937 : 1090 : case ZigTypeIdOptional:
4938 [ - + ]: 1090 : if (get_codegen_ptr_type(const_val->type) != nullptr) {
4939 : 0 : return hash_const_val_ptr(const_val) * 1992916303;
4940 [ - + ]: 1090 : } else if (const_val->type->data.maybe.child_type->id == ZigTypeIdErrorSet) {
4941 : 0 : return hash_const_val_error_set(const_val) * 3147031929;
4942 : : } else {
4943 [ + + ]: 1090 : if (const_val->data.x_optional) {
4944 : 329 : return hash_const_val(const_val->data.x_optional) * 1992916303;
4945 : : } else {
4946 : 761 : return 4016830364;
4947 : : }
4948 : : }
4949 : 144 : case ZigTypeIdErrorUnion:
4950 : : // TODO better hashing algorithm
4951 : 144 : return 3415065496;
4952 : 160 : case ZigTypeIdErrorSet:
4953 : 160 : return hash_const_val_error_set(const_val);
4954 : 0 : case ZigTypeIdVector:
4955 : : // TODO better hashing algorithm
4956 : 0 : return 3647867726;
4957 : 0 : case ZigTypeIdFnFrame:
4958 : : // TODO better hashing algorithm
4959 : 0 : return 675741936;
4960 : 0 : case ZigTypeIdAnyFrame:
4961 : : // TODO better hashing algorithm
4962 : 0 : return 3747294894;
4963 : 0 : case ZigTypeIdBoundFn:
4964 : : case ZigTypeIdInvalid:
4965 : : case ZigTypeIdUnreachable:
4966 : 0 : zig_unreachable();
4967 : : }
4968 : 0 : zig_unreachable();
4969 : : }
4970 : :
4971 : 27377 : uint32_t generic_fn_type_id_hash(GenericFnTypeId *id) {
4972 : 27377 : uint32_t result = 0;
4973 : 27377 : result += hash_ptr(id->fn_entry);
4974 [ + + ]: 78873 : for (size_t i = 0; i < id->param_count; i += 1) {
4975 : 51496 : ConstExprValue *generic_param = &id->params[i];
4976 [ + + ]: 51496 : if (generic_param->special != ConstValSpecialRuntime) {
4977 : 26827 : result += hash_const_val(generic_param);
4978 : 26827 : result += hash_ptr(generic_param->type);
4979 : : }
4980 : : }
4981 : 27377 : return result;
4982 : : }
4983 : :
4984 : 657775 : bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) {
4985 : 657775 : assert(a->fn_entry);
4986 [ + + ]: 657775 : if (a->fn_entry != b->fn_entry) return false;
4987 [ + + ]: 312211 : if (a->param_count != b->param_count) return false;
4988 [ + + ]: 228560 : for (size_t i = 0; i < a->param_count; i += 1) {
4989 : 221809 : ConstExprValue *a_val = &a->params[i];
4990 : 221809 : ConstExprValue *b_val = &b->params[i];
4991 [ + + ]: 221809 : if (a_val->type != b_val->type) return false;
4992 [ + + ][ + - ]: 115865 : if (a_val->special != ConstValSpecialRuntime && b_val->special != ConstValSpecialRuntime) {
4993 : 83056 : assert(a_val->special == ConstValSpecialStatic);
4994 : 83056 : assert(b_val->special == ConstValSpecialStatic);
4995 [ + + ]: 83056 : if (!const_values_equal(a->codegen, a_val, b_val)) {
4996 : 68432 : return false;
4997 : : }
4998 : : } else {
4999 [ + - ][ + - ]: 32809 : assert(a_val->special == ConstValSpecialRuntime && b_val->special == ConstValSpecialRuntime);
5000 : : }
5001 : : }
5002 : 6751 : return true;
5003 : : }
5004 : :
5005 : 54479 : static bool can_mutate_comptime_var_state(ConstExprValue *value) {
5006 : 54479 : assert(value != nullptr);
5007 [ - + + + : 54479 : switch (value->type->id) {
+ + + + -
- ]
5008 : 0 : case ZigTypeIdInvalid:
5009 : 0 : zig_unreachable();
5010 : 45621 : case ZigTypeIdMetaType:
5011 : : case ZigTypeIdVoid:
5012 : : case ZigTypeIdBool:
5013 : : case ZigTypeIdUnreachable:
5014 : : case ZigTypeIdInt:
5015 : : case ZigTypeIdVector:
5016 : : case ZigTypeIdFloat:
5017 : : case ZigTypeIdComptimeFloat:
5018 : : case ZigTypeIdComptimeInt:
5019 : : case ZigTypeIdEnumLiteral:
5020 : : case ZigTypeIdUndefined:
5021 : : case ZigTypeIdNull:
5022 : : case ZigTypeIdBoundFn:
5023 : : case ZigTypeIdFn:
5024 : : case ZigTypeIdOpaque:
5025 : : case ZigTypeIdErrorSet:
5026 : : case ZigTypeIdEnum:
5027 : : case ZigTypeIdFnFrame:
5028 : : case ZigTypeIdAnyFrame:
5029 : 45621 : return false;
5030 : :
5031 : 4761 : case ZigTypeIdPointer:
5032 : 4761 : return value->data.x_ptr.mut == ConstPtrMutComptimeVar;
5033 : :
5034 : 16 : case ZigTypeIdArray:
5035 [ - + ]: 16 : if (value->type->data.array.len == 0)
5036 : 0 : return false;
5037 [ - + - ]: 16 : switch (value->data.x_array.special) {
5038 : 0 : case ConstArraySpecialUndef:
5039 : : case ConstArraySpecialBuf:
5040 : 0 : return false;
5041 : 16 : case ConstArraySpecialNone:
5042 [ + + ]: 48 : for (uint32_t i = 0; i < value->type->data.array.len; i += 1) {
5043 [ - + ]: 32 : if (can_mutate_comptime_var_state(&value->data.x_array.data.s_none.elements[i]))
5044 : 0 : return true;
5045 : : }
5046 : 16 : return false;
5047 : : }
5048 : 0 : zig_unreachable();
5049 : 3743 : case ZigTypeIdStruct:
5050 [ + + ]: 11134 : for (uint32_t i = 0; i < value->type->data.structure.src_field_count; i += 1) {
5051 [ + + ]: 7439 : if (can_mutate_comptime_var_state(&value->data.x_struct.fields[i]))
5052 : 48 : return true;
5053 : : }
5054 : 3695 : return false;
5055 : :
5056 : 146 : case ZigTypeIdOptional:
5057 [ - + ]: 146 : if (get_codegen_ptr_type(value->type) != nullptr)
5058 : 0 : return value->data.x_ptr.mut == ConstPtrMutComptimeVar;
5059 [ + + ]: 146 : if (value->data.x_optional == nullptr)
5060 : 98 : return false;
5061 : 48 : return can_mutate_comptime_var_state(value->data.x_optional);
5062 : :
5063 : 72 : case ZigTypeIdErrorUnion:
5064 [ + + ]: 72 : if (value->data.x_err_union.error_set->data.x_err_set != nullptr)
5065 : 56 : return false;
5066 : 16 : assert(value->data.x_err_union.payload != nullptr);
5067 : 16 : return can_mutate_comptime_var_state(value->data.x_err_union.payload);
5068 : :
5069 : 120 : case ZigTypeIdUnion:
5070 : 120 : return can_mutate_comptime_var_state(value->data.x_union.payload);
5071 : :
5072 : 0 : case ZigTypeIdArgTuple:
5073 : 0 : zig_panic("TODO var args at comptime is currently not supported");
5074 : : }
5075 : 0 : zig_unreachable();
5076 : : }
5077 : :
5078 : 42203 : static bool return_type_is_cacheable(ZigType *return_type) {
5079 [ - + + + : 42203 : switch (return_type->id) {
+ - - ]
5080 : 0 : case ZigTypeIdInvalid:
5081 : 0 : zig_unreachable();
5082 : 38016 : case ZigTypeIdMetaType:
5083 : : case ZigTypeIdVoid:
5084 : : case ZigTypeIdBool:
5085 : : case ZigTypeIdUnreachable:
5086 : : case ZigTypeIdInt:
5087 : : case ZigTypeIdFloat:
5088 : : case ZigTypeIdComptimeFloat:
5089 : : case ZigTypeIdComptimeInt:
5090 : : case ZigTypeIdEnumLiteral:
5091 : : case ZigTypeIdUndefined:
5092 : : case ZigTypeIdNull:
5093 : : case ZigTypeIdBoundFn:
5094 : : case ZigTypeIdFn:
5095 : : case ZigTypeIdOpaque:
5096 : : case ZigTypeIdErrorSet:
5097 : : case ZigTypeIdEnum:
5098 : : case ZigTypeIdPointer:
5099 : : case ZigTypeIdVector:
5100 : : case ZigTypeIdFnFrame:
5101 : : case ZigTypeIdAnyFrame:
5102 : 38016 : return true;
5103 : :
5104 : 3787 : case ZigTypeIdArray:
5105 : : case ZigTypeIdStruct:
5106 : : case ZigTypeIdUnion:
5107 : 3787 : return false;
5108 : :
5109 : 184 : case ZigTypeIdOptional:
5110 : 184 : return return_type_is_cacheable(return_type->data.maybe.child_type);
5111 : :
5112 : 216 : case ZigTypeIdErrorUnion:
5113 : 216 : return return_type_is_cacheable(return_type->data.error_union.payload_type);
5114 : :
5115 : 0 : case ZigTypeIdArgTuple:
5116 : 0 : zig_panic("TODO var args at comptime is currently not supported");
5117 : : }
5118 : 0 : zig_unreachable();
5119 : : }
5120 : :
5121 : 41803 : bool fn_eval_cacheable(Scope *scope, ZigType *return_type) {
5122 [ + + ]: 41803 : if (!return_type_is_cacheable(return_type))
5123 : 3787 : return false;
5124 [ + - ]: 83781 : while (scope) {
5125 [ + + ]: 83781 : if (scope->id == ScopeIdVarDecl) {
5126 : 46824 : ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
5127 [ - + ]: 46824 : if (type_is_invalid(var_scope->var->var_type))
5128 : 0 : return false;
5129 [ - + ]: 46824 : if (var_scope->var->const_value->special == ConstValSpecialUndef)
5130 : 0 : return false;
5131 [ + + ]: 46824 : if (can_mutate_comptime_var_state(var_scope->var->const_value))
5132 : 46824 : return false;
5133 [ + - ]: 36957 : } else if (scope->id == ScopeIdFnDef) {
5134 : 36957 : return true;
5135 : : } else {
5136 : 0 : zig_unreachable();
5137 : : }
5138 : :
5139 : 45765 : scope = scope->parent;
5140 : : }
5141 : 0 : zig_unreachable();
5142 : : }
5143 : :
5144 : 102645 : uint32_t fn_eval_hash(Scope* scope) {
5145 : 102645 : uint32_t result = 0;
5146 [ + - ]: 233039 : while (scope) {
5147 [ + + ]: 233039 : if (scope->id == ScopeIdVarDecl) {
5148 : 130394 : ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
5149 : 130394 : result += hash_const_val(var_scope->var->const_value);
5150 [ + - ]: 102645 : } else if (scope->id == ScopeIdFnDef) {
5151 : 102645 : ScopeFnDef *fn_scope = (ScopeFnDef *)scope;
5152 : 102645 : result += hash_ptr(fn_scope->fn_entry);
5153 : 102645 : return result;
5154 : : } else {
5155 : 0 : zig_unreachable();
5156 : : }
5157 : :
5158 : 130394 : scope = scope->parent;
5159 : : }
5160 : 0 : zig_unreachable();
5161 : : }
5162 : :
5163 : 429392 : bool fn_eval_eql(Scope *a, Scope *b) {
5164 : 429392 : assert(a->codegen != nullptr);
5165 : 429392 : assert(b->codegen != nullptr);
5166 [ + - ][ + - ]: 461712 : while (a && b) {
5167 [ + + ]: 461712 : if (a->id != b->id)
5168 : 8313 : return false;
5169 : :
5170 [ + + ]: 453399 : if (a->id == ScopeIdVarDecl) {
5171 : 440805 : ScopeVarDecl *a_var_scope = (ScopeVarDecl *)a;
5172 : 440805 : ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b;
5173 [ + + ]: 440805 : if (a_var_scope->var->var_type != b_var_scope->var->var_type)
5174 : 60062 : return false;
5175 [ + - ][ + - ]: 380743 : if (a_var_scope->var->var_type == a_var_scope->var->const_value->type &&
5176 : 380743 : b_var_scope->var->var_type == b_var_scope->var->const_value->type)
5177 : : {
5178 [ + + ]: 380743 : if (!const_values_equal(a->codegen, a_var_scope->var->const_value, b_var_scope->var->const_value))
5179 : 348423 : return false;
5180 : : } else {
5181 : 32320 : zig_panic("TODO comptime ptr reinterpret for fn_eval_eql");
5182 : : }
5183 [ + - ]: 12594 : } else if (a->id == ScopeIdFnDef) {
5184 : 12594 : ScopeFnDef *a_fn_scope = (ScopeFnDef *)a;
5185 : 12594 : ScopeFnDef *b_fn_scope = (ScopeFnDef *)b;
5186 [ + + ]: 12594 : if (a_fn_scope->fn_entry != b_fn_scope->fn_entry)
5187 : 1317 : return false;
5188 : :
5189 : 11277 : return true;
5190 : : } else {
5191 : 0 : zig_unreachable();
5192 : : }
5193 : :
5194 : 32320 : a = a->parent;
5195 : 32320 : b = b->parent;
5196 : : }
5197 : 0 : return false;
5198 : : }
5199 : :
5200 : : // Whether the type has bits at runtime.
5201 : 4096859 : bool type_has_bits(ZigType *type_entry) {
5202 : 4096859 : assert(type_entry != nullptr);
5203 : 4096859 : assert(!type_is_invalid(type_entry));
5204 : 4096859 : assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown));
5205 : 4096859 : return type_entry->abi_size != 0;
5206 : : }
5207 : :
5208 : : // Whether you can infer the value based solely on the type.
5209 : 3413490 : OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
5210 : 3413490 : assert(type_entry != nullptr);
5211 : :
5212 [ + + ]: 3413490 : if (type_entry->one_possible_value != OnePossibleValueInvalid)
5213 : 215690 : return type_entry->one_possible_value;
5214 : :
5215 : : Error err;
5216 [ - + ]: 3197800 : if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
5217 : 0 : return OnePossibleValueInvalid;
5218 [ - + + + : 3197800 : switch (type_entry->id) {
+ + + +
- ]
5219 : 0 : case ZigTypeIdInvalid:
5220 : 0 : zig_unreachable();
5221 : 1817631 : case ZigTypeIdOpaque:
5222 : : case ZigTypeIdComptimeFloat:
5223 : : case ZigTypeIdComptimeInt:
5224 : : case ZigTypeIdEnumLiteral:
5225 : : case ZigTypeIdMetaType:
5226 : : case ZigTypeIdBoundFn:
5227 : : case ZigTypeIdArgTuple:
5228 : : case ZigTypeIdOptional:
5229 : : case ZigTypeIdFn:
5230 : : case ZigTypeIdBool:
5231 : : case ZigTypeIdFloat:
5232 : : case ZigTypeIdErrorUnion:
5233 : : case ZigTypeIdFnFrame:
5234 : : case ZigTypeIdAnyFrame:
5235 : 1817631 : return OnePossibleValueNo;
5236 : 21484 : case ZigTypeIdUndefined:
5237 : : case ZigTypeIdNull:
5238 : : case ZigTypeIdVoid:
5239 : : case ZigTypeIdUnreachable:
5240 : 21484 : return OnePossibleValueYes;
5241 : 72697 : case ZigTypeIdArray:
5242 [ + + ]: 72697 : if (type_entry->data.array.len == 0)
5243 : 403 : return OnePossibleValueYes;
5244 : 72294 : return type_has_one_possible_value(g, type_entry->data.array.child_type);
5245 : 223031 : case ZigTypeIdStruct:
5246 [ + + ]: 223287 : for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
5247 : 222959 : TypeStructField *field = &type_entry->data.structure.fields[i];
5248 [ + + ]: 222959 : OnePossibleValue opv = (field->type_entry != nullptr) ?
5249 : 221888 : type_has_one_possible_value(g, field->type_entry) :
5250 : 224030 : type_val_resolve_has_one_possible_value(g, field->type_val);
5251 [ - + + - ]: 222959 : switch (opv) {
5252 : 0 : case OnePossibleValueInvalid:
5253 : 0 : return OnePossibleValueInvalid;
5254 : 222703 : case OnePossibleValueNo:
5255 : 222703 : return OnePossibleValueNo;
5256 : 256 : case OnePossibleValueYes:
5257 : 256 : continue;
5258 : : }
5259 : : }
5260 : 328 : return OnePossibleValueYes;
5261 : 1049312 : case ZigTypeIdErrorSet:
5262 : : case ZigTypeIdEnum:
5263 : : case ZigTypeIdInt:
5264 : : case ZigTypeIdVector:
5265 [ + + ]: 1049312 : return type_has_bits(type_entry) ? OnePossibleValueNo : OnePossibleValueYes;
5266 : 2123 : case ZigTypeIdPointer: {
5267 : 2123 : ZigType *elem_type = type_entry->data.pointer.child_type;
5268 : : // If the recursive function call asks, then we are not one possible value.
5269 : 2123 : type_entry->one_possible_value = OnePossibleValueNo;
5270 : : // Now update it to be the value of the recursive call.
5271 : 2123 : type_entry->one_possible_value = type_has_one_possible_value(g, elem_type);
5272 : 2123 : return type_entry->one_possible_value;
5273 : : }
5274 : 11522 : case ZigTypeIdUnion:
5275 [ + + ]: 11522 : if (type_entry->data.unionation.src_field_count > 1)
5276 : 11078 : return OnePossibleValueNo;
5277 : 444 : TypeUnionField *only_field = &type_entry->data.unionation.fields[0];
5278 [ + + ]: 444 : if (only_field->type_entry != nullptr) {
5279 : 396 : return type_has_one_possible_value(g, only_field->type_entry);
5280 : : }
5281 : 48 : return type_val_resolve_has_one_possible_value(g, only_field->type_val);
5282 : : }
5283 : 0 : zig_unreachable();
5284 : : }
5285 : :
5286 : 421912 : ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty) {
5287 : : Error err;
5288 [ - + + + : 421912 : switch (ty->id) {
+ + + + +
+ - ]
5289 : 0 : case ZigTypeIdInvalid:
5290 : 0 : zig_unreachable();
5291 : 23087 : case ZigTypeIdComptimeFloat:
5292 : : case ZigTypeIdComptimeInt:
5293 : : case ZigTypeIdEnumLiteral:
5294 : : case ZigTypeIdUndefined:
5295 : : case ZigTypeIdNull:
5296 : : case ZigTypeIdMetaType:
5297 : : case ZigTypeIdBoundFn:
5298 : : case ZigTypeIdArgTuple:
5299 : 23087 : return ReqCompTimeYes;
5300 : 13079 : case ZigTypeIdArray:
5301 : 13079 : return type_requires_comptime(g, ty->data.array.child_type);
5302 : 75359 : case ZigTypeIdStruct:
5303 [ + + ]: 75359 : if (ty->data.structure.resolve_loop_flag_zero_bits) {
5304 : : // Does a struct which contains a pointer field to itself require comptime? No.
5305 : 347 : return ReqCompTimeNo;
5306 : : }
5307 [ - + ]: 75012 : if ((err = type_resolve(g, ty, ResolveStatusZeroBitsKnown)))
5308 : 0 : return ReqCompTimeInvalid;
5309 [ + + ]: 75012 : return ty->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
5310 : 3305 : case ZigTypeIdUnion:
5311 [ + + ]: 3305 : if (ty->data.unionation.resolve_loop_flag_zero_bits) {
5312 : : // Does a union which contains a pointer field to itself require comptime? No.
5313 : 8 : return ReqCompTimeNo;
5314 : : }
5315 [ - + ]: 3297 : if ((err = type_resolve(g, ty, ResolveStatusZeroBitsKnown)))
5316 : 0 : return ReqCompTimeInvalid;
5317 [ + + ]: 3297 : return ty->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
5318 : 4193 : case ZigTypeIdOptional:
5319 : 4193 : return type_requires_comptime(g, ty->data.maybe.child_type);
5320 : 7135 : case ZigTypeIdErrorUnion:
5321 : 7135 : return type_requires_comptime(g, ty->data.error_union.payload_type);
5322 : 42883 : case ZigTypeIdPointer:
5323 [ + + ]: 42883 : if (ty->data.pointer.child_type->id == ZigTypeIdOpaque) {
5324 : 439 : return ReqCompTimeNo;
5325 : : } else {
5326 : 42444 : return type_requires_comptime(g, ty->data.pointer.child_type);
5327 : : }
5328 : 5449 : case ZigTypeIdFn:
5329 [ + + ]: 5449 : return ty->data.fn.is_generic ? ReqCompTimeYes : ReqCompTimeNo;
5330 : 247422 : case ZigTypeIdOpaque:
5331 : : case ZigTypeIdEnum:
5332 : : case ZigTypeIdErrorSet:
5333 : : case ZigTypeIdBool:
5334 : : case ZigTypeIdInt:
5335 : : case ZigTypeIdVector:
5336 : : case ZigTypeIdFloat:
5337 : : case ZigTypeIdVoid:
5338 : : case ZigTypeIdUnreachable:
5339 : : case ZigTypeIdFnFrame:
5340 : : case ZigTypeIdAnyFrame:
5341 : 247422 : return ReqCompTimeNo;
5342 : : }
5343 : 0 : zig_unreachable();
5344 : : }
5345 : :
5346 : 68265 : void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
5347 : 68265 : auto entry = g->string_literals_table.maybe_get(str);
5348 [ + + ]: 68265 : if (entry != nullptr) {
5349 : 49937 : memcpy(const_val, entry->value, sizeof(ConstExprValue));
5350 : 49937 : return;
5351 : : }
5352 : :
5353 : 18328 : const_val->special = ConstValSpecialStatic;
5354 : 18328 : const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str));
5355 : 18328 : const_val->data.x_array.special = ConstArraySpecialBuf;
5356 : 18328 : const_val->data.x_array.data.s_buf = str;
5357 : :
5358 : 18328 : g->string_literals_table.put(str, const_val);
5359 : : }
5360 : :
5361 : 7256 : ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) {
5362 : 7256 : ConstExprValue *const_val = create_const_vals(1);
5363 : 7256 : init_const_str_lit(g, const_val, str);
5364 : 7256 : return const_val;
5365 : : }
5366 : :
5367 : 113 : void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
5368 : : // first we build the underlying array
5369 : 113 : size_t len_with_null = buf_len(str) + 1;
5370 : 113 : ConstExprValue *array_val = create_const_vals(1);
5371 : 113 : array_val->special = ConstValSpecialStatic;
5372 : 113 : array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null);
5373 : : // TODO buf optimization
5374 : 113 : array_val->data.x_array.data.s_none.elements = create_const_vals(len_with_null);
5375 [ + + ]: 1280 : for (size_t i = 0; i < buf_len(str); i += 1) {
5376 : 1167 : ConstExprValue *this_char = &array_val->data.x_array.data.s_none.elements[i];
5377 : 1167 : this_char->special = ConstValSpecialStatic;
5378 : 1167 : this_char->type = g->builtin_types.entry_u8;
5379 : 1167 : bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]);
5380 : : }
5381 : 113 : ConstExprValue *null_char = &array_val->data.x_array.data.s_none.elements[len_with_null - 1];
5382 : 113 : null_char->special = ConstValSpecialStatic;
5383 : 113 : null_char->type = g->builtin_types.entry_u8;
5384 : 113 : bigint_init_unsigned(&null_char->data.x_bigint, 0);
5385 : :
5386 : : // then make the pointer point to it
5387 : 113 : const_val->special = ConstValSpecialStatic;
5388 : : // TODO make this `[*]null u8` instead of `[*]u8`
5389 : 113 : const_val->type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
5390 : : PtrLenUnknown, 0, 0, 0, false);
5391 : 113 : const_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
5392 : 113 : const_val->data.x_ptr.data.base_array.array_val = array_val;
5393 : 113 : const_val->data.x_ptr.data.base_array.elem_index = 0;
5394 : 113 : const_val->data.x_ptr.data.base_array.is_cstr = true;
5395 : 113 : }
5396 : 0 : ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *str) {
5397 : 0 : ConstExprValue *const_val = create_const_vals(1);
5398 : 0 : init_const_c_str_lit(g, const_val, str);
5399 : 0 : return const_val;
5400 : : }
5401 : :
5402 : 128 : void init_const_bigint(ConstExprValue *const_val, ZigType *type, const BigInt *bigint) {
5403 : 128 : const_val->special = ConstValSpecialStatic;
5404 : 128 : const_val->type = type;
5405 : 128 : bigint_init_bigint(&const_val->data.x_bigint, bigint);
5406 : 128 : }
5407 : :
5408 : 0 : ConstExprValue *create_const_bigint(ZigType *type, const BigInt *bigint) {
5409 : 0 : ConstExprValue *const_val = create_const_vals(1);
5410 : 0 : init_const_bigint(const_val, type, bigint);
5411 : 0 : return const_val;
5412 : : }
5413 : :
5414 : :
5415 : 34609 : void init_const_unsigned_negative(ConstExprValue *const_val, ZigType *type, uint64_t x, bool negative) {
5416 : 34609 : const_val->special = ConstValSpecialStatic;
5417 : 34609 : const_val->type = type;
5418 : 34609 : bigint_init_unsigned(&const_val->data.x_bigint, x);
5419 : 34609 : const_val->data.x_bigint.is_negative = negative;
5420 : 34609 : }
5421 : :
5422 : 2547 : ConstExprValue *create_const_unsigned_negative(ZigType *type, uint64_t x, bool negative) {
5423 : 2547 : ConstExprValue *const_val = create_const_vals(1);
5424 : 2547 : init_const_unsigned_negative(const_val, type, x, negative);
5425 : 2547 : return const_val;
5426 : : }
5427 : :
5428 : 32046 : void init_const_usize(CodeGen *g, ConstExprValue *const_val, uint64_t x) {
5429 : 32046 : return init_const_unsigned_negative(const_val, g->builtin_types.entry_usize, x, false);
5430 : : }
5431 : :
5432 : 8 : ConstExprValue *create_const_usize(CodeGen *g, uint64_t x) {
5433 : 8 : return create_const_unsigned_negative(g->builtin_types.entry_usize, x, false);
5434 : : }
5435 : :
5436 : 0 : void init_const_signed(ConstExprValue *const_val, ZigType *type, int64_t x) {
5437 : 0 : const_val->special = ConstValSpecialStatic;
5438 : 0 : const_val->type = type;
5439 : 0 : bigint_init_signed(&const_val->data.x_bigint, x);
5440 : 0 : }
5441 : :
5442 : 0 : ConstExprValue *create_const_signed(ZigType *type, int64_t x) {
5443 : 0 : ConstExprValue *const_val = create_const_vals(1);
5444 : 0 : init_const_signed(const_val, type, x);
5445 : 0 : return const_val;
5446 : : }
5447 : :
5448 : 0 : void init_const_float(ConstExprValue *const_val, ZigType *type, double value) {
5449 : 0 : const_val->special = ConstValSpecialStatic;
5450 : 0 : const_val->type = type;
5451 [ # # ]: 0 : if (type->id == ZigTypeIdComptimeFloat) {
5452 : 0 : bigfloat_init_64(&const_val->data.x_bigfloat, value);
5453 [ # # ]: 0 : } else if (type->id == ZigTypeIdFloat) {
5454 [ # # # # : 0 : switch (type->data.floating.bit_count) {
# ]
5455 : 0 : case 16:
5456 : 0 : const_val->data.x_f16 = zig_double_to_f16(value);
5457 : 0 : break;
5458 : 0 : case 32:
5459 : 0 : const_val->data.x_f32 = value;
5460 : 0 : break;
5461 : 0 : case 64:
5462 : 0 : const_val->data.x_f64 = value;
5463 : 0 : break;
5464 : 0 : case 128:
5465 : : // if we need this, we should add a function that accepts a float128_t param
5466 : 0 : zig_unreachable();
5467 : 0 : default:
5468 : 0 : zig_unreachable();
5469 : : }
5470 : : } else {
5471 : 0 : zig_unreachable();
5472 : : }
5473 : 0 : }
5474 : :
5475 : 0 : ConstExprValue *create_const_float(ZigType *type, double value) {
5476 : 0 : ConstExprValue *const_val = create_const_vals(1);
5477 : 0 : init_const_float(const_val, type, value);
5478 : 0 : return const_val;
5479 : : }
5480 : :
5481 : 23242 : void init_const_enum(ConstExprValue *const_val, ZigType *type, const BigInt *tag) {
5482 : 23242 : const_val->special = ConstValSpecialStatic;
5483 : 23242 : const_val->type = type;
5484 : 23242 : bigint_init_bigint(&const_val->data.x_enum_tag, tag);
5485 : 23242 : }
5486 : :
5487 : 23242 : ConstExprValue *create_const_enum(ZigType *type, const BigInt *tag) {
5488 : 23242 : ConstExprValue *const_val = create_const_vals(1);
5489 : 23242 : init_const_enum(const_val, type, tag);
5490 : 23242 : return const_val;
5491 : : }
5492 : :
5493 : :
5494 : 292 : void init_const_bool(CodeGen *g, ConstExprValue *const_val, bool value) {
5495 : 292 : const_val->special = ConstValSpecialStatic;
5496 : 292 : const_val->type = g->builtin_types.entry_bool;
5497 : 292 : const_val->data.x_bool = value;
5498 : 292 : }
5499 : :
5500 : 292 : ConstExprValue *create_const_bool(CodeGen *g, bool value) {
5501 : 292 : ConstExprValue *const_val = create_const_vals(1);
5502 : 292 : init_const_bool(g, const_val, value);
5503 : 292 : return const_val;
5504 : : }
5505 : :
5506 : 60601 : void init_const_runtime(ConstExprValue *const_val, ZigType *type) {
5507 : 60601 : const_val->special = ConstValSpecialRuntime;
5508 : 60601 : const_val->type = type;
5509 : 60601 : }
5510 : :
5511 : 60601 : ConstExprValue *create_const_runtime(ZigType *type) {
5512 : 60601 : ConstExprValue *const_val = create_const_vals(1);
5513 : 60601 : init_const_runtime(const_val, type);
5514 : 60601 : return const_val;
5515 : : }
5516 : :
5517 : 236 : void init_const_type(CodeGen *g, ConstExprValue *const_val, ZigType *type_value) {
5518 : 236 : const_val->special = ConstValSpecialStatic;
5519 : 236 : const_val->type = g->builtin_types.entry_type;
5520 : 236 : const_val->data.x_type = type_value;
5521 : 236 : }
5522 : :
5523 : 236 : ConstExprValue *create_const_type(CodeGen *g, ZigType *type_value) {
5524 : 236 : ConstExprValue *const_val = create_const_vals(1);
5525 : 236 : init_const_type(g, const_val, type_value);
5526 : 236 : return const_val;
5527 : : }
5528 : :
5529 : 24673 : void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val,
5530 : : size_t start, size_t len, bool is_const)
5531 : : {
5532 : 24673 : assert(array_val->type->id == ZigTypeIdArray);
5533 : :
5534 : 24673 : ZigType *ptr_type = get_pointer_to_type_extra(g, array_val->type->data.array.child_type,
5535 : 24673 : is_const, false, PtrLenUnknown, 0, 0, 0, false);
5536 : :
5537 : 24673 : const_val->special = ConstValSpecialStatic;
5538 : 24673 : const_val->type = get_slice_type(g, ptr_type);
5539 : 24673 : const_val->data.x_struct.fields = create_const_vals(2);
5540 : :
5541 : 24673 : init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const,
5542 : : PtrLenUnknown);
5543 : 24673 : init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len);
5544 : 24673 : }
5545 : :
5546 : 24 : ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t start, size_t len, bool is_const) {
5547 : 24 : ConstExprValue *const_val = create_const_vals(1);
5548 : 24 : init_const_slice(g, const_val, array_val, start, len, is_const);
5549 : 24 : return const_val;
5550 : : }
5551 : :
5552 : 26878 : void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val,
5553 : : size_t elem_index, bool is_const, PtrLen ptr_len)
5554 : : {
5555 : 26878 : assert(array_val->type->id == ZigTypeIdArray);
5556 : 26878 : ZigType *child_type = array_val->type->data.array.child_type;
5557 : :
5558 : 26878 : const_val->special = ConstValSpecialStatic;
5559 : 26878 : const_val->type = get_pointer_to_type_extra(g, child_type, is_const, false,
5560 : : ptr_len, 0, 0, 0, false);
5561 : 26878 : const_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
5562 : 26878 : const_val->data.x_ptr.data.base_array.array_val = array_val;
5563 : 26878 : const_val->data.x_ptr.data.base_array.elem_index = elem_index;
5564 : 26878 : }
5565 : :
5566 : 0 : ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const,
5567 : : PtrLen ptr_len)
5568 : : {
5569 : 0 : ConstExprValue *const_val = create_const_vals(1);
5570 : 0 : init_const_ptr_array(g, const_val, array_val, elem_index, is_const, ptr_len);
5571 : 0 : return const_val;
5572 : : }
5573 : :
5574 : 0 : void init_const_ptr_ref(CodeGen *g, ConstExprValue *const_val, ConstExprValue *pointee_val, bool is_const) {
5575 : 0 : const_val->special = ConstValSpecialStatic;
5576 : 0 : const_val->type = get_pointer_to_type(g, pointee_val->type, is_const);
5577 : 0 : const_val->data.x_ptr.special = ConstPtrSpecialRef;
5578 : 0 : const_val->data.x_ptr.data.ref.pointee = pointee_val;
5579 : 0 : }
5580 : :
5581 : 0 : ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bool is_const) {
5582 : 0 : ConstExprValue *const_val = create_const_vals(1);
5583 : 0 : init_const_ptr_ref(g, const_val, pointee_val, is_const);
5584 : 0 : return const_val;
5585 : : }
5586 : :
5587 : 24 : void init_const_ptr_hard_coded_addr(CodeGen *g, ConstExprValue *const_val, ZigType *pointee_type,
5588 : : size_t addr, bool is_const)
5589 : : {
5590 : 24 : const_val->special = ConstValSpecialStatic;
5591 : 24 : const_val->type = get_pointer_to_type(g, pointee_type, is_const);
5592 : 24 : const_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
5593 : 24 : const_val->data.x_ptr.data.hard_coded_addr.addr = addr;
5594 : 24 : }
5595 : :
5596 : 0 : ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, ZigType *pointee_type,
5597 : : size_t addr, bool is_const)
5598 : : {
5599 : 0 : ConstExprValue *const_val = create_const_vals(1);
5600 : 0 : init_const_ptr_hard_coded_addr(g, const_val, pointee_type, addr, is_const);
5601 : 0 : return const_val;
5602 : : }
5603 : :
5604 : 2576 : void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end) {
5605 : 2576 : const_val->special = ConstValSpecialStatic;
5606 : 2576 : const_val->type = g->builtin_types.entry_arg_tuple;
5607 : 2576 : const_val->data.x_arg_tuple.start_index = arg_index_start;
5608 : 2576 : const_val->data.x_arg_tuple.end_index = arg_index_end;
5609 : 2576 : }
5610 : :
5611 : 2576 : ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end) {
5612 : 2576 : ConstExprValue *const_val = create_const_vals(1);
5613 : 2576 : init_const_arg_tuple(g, const_val, arg_index_start, arg_index_end);
5614 : 2576 : return const_val;
5615 : : }
5616 : :
5617 : :
5618 : 702058 : ConstExprValue *create_const_vals(size_t count) {
5619 : 702058 : ConstGlobalRefs *global_refs = allocate<ConstGlobalRefs>(count);
5620 : 702058 : ConstExprValue *vals = allocate<ConstExprValue>(count);
5621 [ + + ]: 3064958 : for (size_t i = 0; i < count; i += 1) {
5622 : 2362900 : vals[i].global_refs = &global_refs[i];
5623 : : }
5624 : 702058 : return vals;
5625 : : }
5626 : :
5627 : 824 : static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) {
5628 [ + + ]: 824 : if (orig_fn_type->data.fn.fn_type_id.cc == CallingConventionAsync)
5629 : 128 : return orig_fn_type;
5630 : :
5631 : 696 : ZigType *fn_type = allocate_nonzero<ZigType>(1);
5632 : 696 : *fn_type = *orig_fn_type;
5633 : 696 : fn_type->data.fn.fn_type_id.cc = CallingConventionAsync;
5634 : 696 : fn_type->llvm_type = nullptr;
5635 : 696 : fn_type->llvm_di_type = nullptr;
5636 : :
5637 : 696 : return fn_type;
5638 : : }
5639 : :
5640 : 10832 : static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
5641 : : Error err;
5642 : :
5643 [ + + ]: 10832 : if (frame_type->data.frame.locals_struct != nullptr)
5644 : 9816 : return ErrorNone;
5645 : :
5646 : 1016 : ZigFn *fn = frame_type->data.frame.fn;
5647 : 1016 : assert(!fn->type_entry->data.fn.is_generic);
5648 : :
5649 [ - + ]: 1016 : if (frame_type->data.frame.resolve_loop_type != nullptr) {
5650 [ # # ]: 0 : if (!frame_type->data.frame.reported_loop_err) {
5651 : 0 : add_node_error(g, fn->proto_node,
5652 : : buf_sprintf("'%s' depends on itself", buf_ptr(&frame_type->name)));
5653 : : }
5654 : 0 : return ErrorSemanticAnalyzeFail;
5655 : : }
5656 : :
5657 [ - + + - : 1016 : switch (fn->anal_state) {
- ]
5658 : 0 : case FnAnalStateInvalid:
5659 : 0 : return ErrorSemanticAnalyzeFail;
5660 : 512 : case FnAnalStateComplete:
5661 : 512 : break;
5662 : 504 : case FnAnalStateReady:
5663 : 504 : analyze_fn_body(g, fn);
5664 [ - + ]: 504 : if (fn->anal_state == FnAnalStateInvalid)
5665 : 0 : return ErrorSemanticAnalyzeFail;
5666 : 504 : break;
5667 : 0 : case FnAnalStateProbing: {
5668 : 0 : add_node_error(g, fn->proto_node,
5669 : : buf_sprintf("cannot resolve '%s': function not fully analyzed yet",
5670 : : buf_ptr(&frame_type->name)));
5671 : 0 : return ErrorSemanticAnalyzeFail;
5672 : : }
5673 : : }
5674 : 1016 : analyze_fn_async(g, fn, false);
5675 [ - + ]: 1016 : if (fn->anal_state == FnAnalStateInvalid)
5676 : 0 : return ErrorSemanticAnalyzeFail;
5677 : :
5678 [ + + ]: 1016 : if (!fn_is_async(fn)) {
5679 : 192 : ZigType *fn_type = fn->type_entry;
5680 : 192 : FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
5681 : 192 : ZigType *ptr_return_type = get_pointer_to_type(g, fn_type_id->return_type, false);
5682 : :
5683 : : // label (grep this): [fn_frame_struct_layout]
5684 : 192 : ZigList<SrcField> fields = {};
5685 : :
5686 : 192 : fields.append({"@fn_ptr", g->builtin_types.entry_usize, 0});
5687 : 192 : fields.append({"@resume_index", g->builtin_types.entry_usize, 0});
5688 : 192 : fields.append({"@awaiter", g->builtin_types.entry_usize, 0});
5689 : :
5690 : 192 : fields.append({"@result_ptr_callee", ptr_return_type, 0});
5691 : 192 : fields.append({"@result_ptr_awaiter", ptr_return_type, 0});
5692 : 192 : fields.append({"@result", fn_type_id->return_type, 0});
5693 : :
5694 [ + + ]: 192 : if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
5695 : 136 : ZigType *ptr_to_stack_trace_type = get_pointer_to_type(g, get_stack_trace_type(g), false);
5696 : 136 : fields.append({"@ptr_stack_trace_callee", ptr_to_stack_trace_type, 0});
5697 : 136 : fields.append({"@ptr_stack_trace_awaiter", ptr_to_stack_trace_type, 0});
5698 : :
5699 : 136 : fields.append({"@stack_trace", get_stack_trace_type(g), 0});
5700 : 136 : fields.append({"@instruction_addresses",
5701 : 136 : get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count), 0});
5702 : : }
5703 : :
5704 : 192 : frame_type->data.frame.locals_struct = get_struct_type(g, buf_ptr(&frame_type->name),
5705 : : fields.items, fields.length, target_fn_align(g->zig_target));
5706 : 192 : frame_type->abi_size = frame_type->data.frame.locals_struct->abi_size;
5707 : 192 : frame_type->abi_align = frame_type->data.frame.locals_struct->abi_align;
5708 : 192 : frame_type->size_in_bits = frame_type->data.frame.locals_struct->size_in_bits;
5709 : :
5710 : 192 : return ErrorNone;
5711 : : }
5712 : :
5713 : 824 : ZigType *fn_type = get_async_fn_type(g, fn->type_entry);
5714 : :
5715 [ + + ]: 824 : if (fn->analyzed_executable.need_err_code_spill) {
5716 : 248 : IrInstructionAllocaGen *alloca_gen = allocate<IrInstructionAllocaGen>(1);
5717 : 248 : alloca_gen->base.id = IrInstructionIdAllocaGen;
5718 : 248 : alloca_gen->base.source_node = fn->proto_node;
5719 : 248 : alloca_gen->base.scope = fn->child_scope;
5720 : 248 : alloca_gen->base.value.type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false);
5721 : 248 : alloca_gen->base.ref_count = 1;
5722 : 248 : alloca_gen->name_hint = "";
5723 : 248 : fn->alloca_gen_list.append(alloca_gen);
5724 : 248 : fn->err_code_spill = &alloca_gen->base;
5725 : : }
5726 : :
5727 [ + + ]: 3016 : for (size_t i = 0; i < fn->call_list.length; i += 1) {
5728 : 2192 : IrInstructionCallGen *call = fn->call_list.at(i);
5729 [ + + ]: 2192 : if (call->new_stack != nullptr) {
5730 : : // don't need to allocate a frame for this
5731 : 24 : continue;
5732 : : }
5733 : 2168 : ZigFn *callee = call->fn_entry;
5734 [ - + ]: 2168 : if (callee == nullptr) {
5735 : 0 : add_node_error(g, call->base.source_node,
5736 : : buf_sprintf("function is not comptime-known; @asyncCall required"));
5737 : 0 : return ErrorSemanticAnalyzeFail;
5738 : : }
5739 [ - + ]: 2168 : if (callee->body_node == nullptr) {
5740 : 0 : continue;
5741 : : }
5742 [ - + ]: 2168 : if (callee->anal_state == FnAnalStateProbing) {
5743 : 0 : ErrorMsg *msg = add_node_error(g, fn->proto_node,
5744 : 0 : buf_sprintf("unable to determine async function frame of '%s'", buf_ptr(&fn->symbol_name)));
5745 : 0 : g->trace_err = add_error_note(g, msg, call->base.source_node,
5746 : : buf_sprintf("analysis of function '%s' depends on the frame", buf_ptr(&callee->symbol_name)));
5747 : 0 : return ErrorSemanticAnalyzeFail;
5748 : : }
5749 : :
5750 : 2168 : ZigType *callee_frame_type = get_fn_frame_type(g, callee);
5751 : 2168 : frame_type->data.frame.resolve_loop_type = callee_frame_type;
5752 : 2168 : frame_type->data.frame.resolve_loop_src_node = call->base.source_node;
5753 : :
5754 : 2168 : analyze_fn_body(g, callee);
5755 [ - + ]: 2168 : if (callee->anal_state == FnAnalStateInvalid) {
5756 : 0 : frame_type->data.frame.locals_struct = g->builtin_types.entry_invalid;
5757 : 0 : return ErrorSemanticAnalyzeFail;
5758 : : }
5759 : 2168 : analyze_fn_async(g, callee, true);
5760 [ - + ]: 2168 : if (callee->inferred_async_node == inferred_async_checking) {
5761 : 0 : assert(g->errors.length != 0);
5762 : 0 : frame_type->data.frame.locals_struct = g->builtin_types.entry_invalid;
5763 : 0 : return ErrorSemanticAnalyzeFail;
5764 : : }
5765 [ + + ]: 2168 : if (!fn_is_async(callee))
5766 : 1992 : continue;
5767 : :
5768 : 176 : IrInstructionAllocaGen *alloca_gen = allocate<IrInstructionAllocaGen>(1);
5769 : 176 : alloca_gen->base.id = IrInstructionIdAllocaGen;
5770 : 176 : alloca_gen->base.source_node = call->base.source_node;
5771 : 176 : alloca_gen->base.scope = call->base.scope;
5772 : 176 : alloca_gen->base.value.type = get_pointer_to_type(g, callee_frame_type, false);
5773 : 176 : alloca_gen->base.ref_count = 1;
5774 : 176 : alloca_gen->name_hint = "";
5775 : 176 : fn->alloca_gen_list.append(alloca_gen);
5776 : 176 : call->frame_result_loc = &alloca_gen->base;
5777 : : }
5778 : 824 : FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
5779 : 824 : ZigType *ptr_return_type = get_pointer_to_type(g, fn_type_id->return_type, false);
5780 : :
5781 : : // label (grep this): [fn_frame_struct_layout]
5782 : 824 : ZigList<SrcField> fields = {};
5783 : :
5784 : 824 : fields.append({"@fn_ptr", fn_type, 0});
5785 : 824 : fields.append({"@resume_index", g->builtin_types.entry_usize, 0});
5786 : 824 : fields.append({"@awaiter", g->builtin_types.entry_usize, 0});
5787 : :
5788 : 824 : fields.append({"@result_ptr_callee", ptr_return_type, 0});
5789 : 824 : fields.append({"@result_ptr_awaiter", ptr_return_type, 0});
5790 : 824 : fields.append({"@result", fn_type_id->return_type, 0});
5791 : :
5792 [ + + ]: 824 : if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
5793 : 328 : ZigType *ptr_stack_trace_type = get_pointer_to_type(g, get_stack_trace_type(g), false);
5794 : 328 : fields.append({"@ptr_stack_trace_callee", ptr_stack_trace_type, 0});
5795 : 328 : fields.append({"@ptr_stack_trace_awaiter", ptr_stack_trace_type, 0});
5796 : : }
5797 : :
5798 [ + + ]: 1296 : for (size_t arg_i = 0; arg_i < fn_type_id->param_count; arg_i += 1) {
5799 : 472 : FnTypeParamInfo *param_info = &fn_type_id->param_info[arg_i];
5800 : 472 : AstNode *param_decl_node = get_param_decl_node(fn, arg_i);
5801 : : Buf *param_name;
5802 [ - + ][ + - ]: 472 : bool is_var_args = param_decl_node && param_decl_node->data.param_decl.is_var_args;
5803 [ + - ][ + - ]: 472 : if (param_decl_node && !is_var_args) {
5804 : 472 : param_name = param_decl_node->data.param_decl.name;
5805 : : } else {
5806 : 0 : param_name = buf_sprintf("@arg%" ZIG_PRI_usize, arg_i);
5807 : : }
5808 : 472 : ZigType *param_type = param_info->type;
5809 : :
5810 : 472 : fields.append({buf_ptr(param_name), param_type, 0});
5811 : : }
5812 : :
5813 [ + + ]: 824 : if (codegen_fn_has_err_ret_tracing_stack(g, fn, true)) {
5814 : 448 : fields.append({"@stack_trace", get_stack_trace_type(g), 0});
5815 : 448 : fields.append({"@instruction_addresses",
5816 : 448 : get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count), 0});
5817 : : }
5818 : :
5819 [ + + ]: 4104 : for (size_t alloca_i = 0; alloca_i < fn->alloca_gen_list.length; alloca_i += 1) {
5820 : 3280 : IrInstructionAllocaGen *instruction = fn->alloca_gen_list.at(alloca_i);
5821 : 3280 : instruction->field_index = SIZE_MAX;
5822 : 3280 : ZigType *ptr_type = instruction->base.value.type;
5823 : 3280 : assert(ptr_type->id == ZigTypeIdPointer);
5824 : 3280 : ZigType *child_type = ptr_type->data.pointer.child_type;
5825 [ + + ]: 3280 : if (!type_has_bits(child_type))
5826 : 936 : continue;
5827 [ - + ]: 2344 : if (instruction->base.ref_count == 0)
5828 : 0 : continue;
5829 [ - + ]: 2344 : if (instruction->base.value.special != ConstValSpecialRuntime) {
5830 [ # # ]: 0 : if (const_ptr_pointee(nullptr, g, &instruction->base.value, nullptr)->special !=
5831 : : ConstValSpecialRuntime)
5832 : : {
5833 : 0 : continue;
5834 : : }
5835 : : }
5836 : :
5837 : 2344 : frame_type->data.frame.resolve_loop_type = child_type;
5838 : 2344 : frame_type->data.frame.resolve_loop_src_node = instruction->base.source_node;
5839 [ - + ]: 2344 : if ((err = type_resolve(g, child_type, ResolveStatusSizeKnown))) {
5840 : 0 : return err;
5841 : : }
5842 : :
5843 : : const char *name;
5844 [ + + ]: 2344 : if (*instruction->name_hint == 0) {
5845 : 1336 : name = buf_ptr(buf_sprintf("@local%" ZIG_PRI_usize, alloca_i));
5846 : : } else {
5847 : 1008 : name = buf_ptr(buf_sprintf("%s.%" ZIG_PRI_usize, instruction->name_hint, alloca_i));
5848 : : }
5849 : 2344 : instruction->field_index = fields.length;
5850 : :
5851 : 2344 : fields.append({name, child_type, instruction->align});
5852 : : }
5853 : :
5854 : :
5855 : 824 : frame_type->data.frame.locals_struct = get_struct_type(g, buf_ptr(&frame_type->name),
5856 : : fields.items, fields.length, target_fn_align(g->zig_target));
5857 : 824 : frame_type->abi_size = frame_type->data.frame.locals_struct->abi_size;
5858 : 824 : frame_type->abi_align = frame_type->data.frame.locals_struct->abi_align;
5859 : 824 : frame_type->size_in_bits = frame_type->data.frame.locals_struct->size_in_bits;
5860 : 10832 : return ErrorNone;
5861 : : }
5862 : :
5863 : 89471 : static Error resolve_pointer_zero_bits(CodeGen *g, ZigType *ty) {
5864 : : Error err;
5865 : :
5866 [ + + ]: 89471 : if (ty->abi_size != SIZE_MAX)
5867 : 89194 : return ErrorNone;
5868 : :
5869 [ - + ]: 277 : if (ty->data.pointer.resolve_loop_flag_zero_bits) {
5870 : 0 : ty->abi_size = g->builtin_types.entry_usize->abi_size;
5871 : 0 : ty->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
5872 : 0 : ty->abi_align = g->builtin_types.entry_usize->abi_align;
5873 : 0 : return ErrorNone;
5874 : : }
5875 : 277 : ty->data.pointer.resolve_loop_flag_zero_bits = true;
5876 : :
5877 : 277 : ZigType *elem_type = ty->data.pointer.child_type;
5878 : :
5879 [ - + ]: 277 : if ((err = type_resolve(g, elem_type, ResolveStatusZeroBitsKnown)))
5880 : 0 : return err;
5881 : :
5882 [ + + ]: 277 : if (type_has_bits(elem_type)) {
5883 : 269 : ty->abi_size = g->builtin_types.entry_usize->abi_size;
5884 : 269 : ty->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
5885 : 269 : ty->abi_align = g->builtin_types.entry_usize->abi_align;
5886 : : } else {
5887 : 8 : ty->abi_size = 0;
5888 : 8 : ty->size_in_bits = 0;
5889 : 8 : ty->abi_align = 0;
5890 : : }
5891 : 277 : return ErrorNone;
5892 : : }
5893 : :
5894 : 9187218 : Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) {
5895 [ - + ]: 9187218 : if (type_is_invalid(ty))
5896 : 0 : return ErrorSemanticAnalyzeFail;
5897 [ - - + + : 9187218 : switch (status) {
+ + - ]
5898 : 0 : case ResolveStatusUnstarted:
5899 : 0 : return ErrorNone;
5900 : 0 : case ResolveStatusInvalid:
5901 : 0 : zig_unreachable();
5902 : 3835817 : case ResolveStatusZeroBitsKnown:
5903 [ + + + + : 3835817 : switch (ty->id) {
+ ]
5904 : 316102 : case ZigTypeIdStruct:
5905 : 316102 : return resolve_struct_zero_bits(g, ty);
5906 : 342770 : case ZigTypeIdEnum:
5907 : 342770 : return resolve_enum_zero_bits(g, ty);
5908 : 18411 : case ZigTypeIdUnion:
5909 : 18411 : return resolve_union_zero_bits(g, ty);
5910 : 27107 : case ZigTypeIdPointer:
5911 : 27107 : return resolve_pointer_zero_bits(g, ty);
5912 : 3131427 : default:
5913 : 3131427 : return ErrorNone;
5914 : : }
5915 : 397096 : case ResolveStatusAlignmentKnown:
5916 [ + + + + : 397096 : switch (ty->id) {
+ + ]
5917 : 100525 : case ZigTypeIdStruct:
5918 : 100525 : return resolve_struct_alignment(g, ty);
5919 : 2012 : case ZigTypeIdEnum:
5920 : 2012 : return resolve_enum_zero_bits(g, ty);
5921 : 1387 : case ZigTypeIdUnion:
5922 : 1387 : return resolve_union_alignment(g, ty);
5923 : 544 : case ZigTypeIdFnFrame:
5924 : 544 : return resolve_async_frame(g, ty);
5925 : 25196 : case ZigTypeIdPointer:
5926 : 25196 : return resolve_pointer_zero_bits(g, ty);
5927 : 267432 : default:
5928 : 267432 : return ErrorNone;
5929 : : }
5930 : 1657487 : case ResolveStatusSizeKnown:
5931 [ + + + + : 1657487 : switch (ty->id) {
+ + ]
5932 : 135116 : case ZigTypeIdStruct:
5933 : 135116 : return resolve_struct_type(g, ty);
5934 : 90899 : case ZigTypeIdEnum:
5935 : 90899 : return resolve_enum_zero_bits(g, ty);
5936 : 17889 : case ZigTypeIdUnion:
5937 : 17889 : return resolve_union_type(g, ty);
5938 : 10288 : case ZigTypeIdFnFrame:
5939 : 10288 : return resolve_async_frame(g, ty);
5940 : 26398 : case ZigTypeIdPointer:
5941 : 26398 : return resolve_pointer_zero_bits(g, ty);
5942 : 1376897 : default:
5943 : 1376897 : return ErrorNone;
5944 : : }
5945 : 3296818 : case ResolveStatusLLVMFwdDecl:
5946 : : case ResolveStatusLLVMFull:
5947 : 3296818 : resolve_llvm_types(g, ty, status);
5948 : 3296818 : return ErrorNone;
5949 : : }
5950 : 0 : zig_unreachable();
5951 : : }
5952 : :
5953 : 1012523 : bool ir_get_var_is_comptime(ZigVar *var) {
5954 : : // The is_comptime field can be left null, which means not comptime.
5955 [ + + ]: 1012523 : if (var->is_comptime == nullptr)
5956 : 352020 : return false;
5957 : : // When the is_comptime field references an instruction that has to get analyzed, this
5958 : : // is the value.
5959 [ + - ]: 660503 : if (var->is_comptime->child != nullptr) {
5960 : 660503 : assert(var->is_comptime->child->value.type->id == ZigTypeIdBool);
5961 : 660503 : return var->is_comptime->child->value.data.x_bool;
5962 : : }
5963 : : // As an optimization, is_comptime values which are constant are allowed
5964 : : // to be omitted from analysis. In this case, there is no child instruction
5965 : : // and we simply look at the unanalyzed const parent instruction.
5966 : 0 : assert(var->is_comptime->value.type->id == ZigTypeIdBool);
5967 : 0 : return var->is_comptime->value.data.x_bool;
5968 : : }
5969 : :
5970 : 359012 : bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) {
5971 [ + + ]: 359012 : if (a->data.x_ptr.special != b->data.x_ptr.special)
5972 : 24 : return false;
5973 [ + + ]: 358988 : if (a->data.x_ptr.mut != b->data.x_ptr.mut)
5974 : 32 : return false;
5975 [ - + + + : 358956 : switch (a->data.x_ptr.special) {
- - - + -
+ + - ]
5976 : 0 : case ConstPtrSpecialInvalid:
5977 : 0 : zig_unreachable();
5978 : 162 : case ConstPtrSpecialRef:
5979 [ - + ]: 162 : if (a->data.x_ptr.data.ref.pointee != b->data.x_ptr.data.ref.pointee)
5980 : 0 : return false;
5981 : 162 : return true;
5982 : 358698 : case ConstPtrSpecialBaseArray:
5983 [ + + ][ + + ]: 358698 : if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val &&
5984 : 357817 : a->data.x_ptr.data.base_array.array_val->global_refs !=
5985 : 357817 : b->data.x_ptr.data.base_array.array_val->global_refs)
5986 : : {
5987 : 340059 : return false;
5988 : : }
5989 [ + + ]: 18639 : if (a->data.x_ptr.data.base_array.elem_index != b->data.x_ptr.data.base_array.elem_index)
5990 : 441 : return false;
5991 [ - + ]: 18198 : if (a->data.x_ptr.data.base_array.is_cstr != b->data.x_ptr.data.base_array.is_cstr)
5992 : 0 : return false;
5993 : 18198 : return true;
5994 : 32 : case ConstPtrSpecialBaseStruct:
5995 [ - + ][ # # ]: 32 : if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val &&
5996 : 0 : a->data.x_ptr.data.base_struct.struct_val->global_refs !=
5997 : 0 : b->data.x_ptr.data.base_struct.struct_val->global_refs)
5998 : : {
5999 : 0 : return false;
6000 : : }
6001 [ - + ]: 32 : if (a->data.x_ptr.data.base_struct.field_index != b->data.x_ptr.data.base_struct.field_index)
6002 : 0 : return false;
6003 : 32 : return true;
6004 : 0 : case ConstPtrSpecialBaseErrorUnionCode:
6005 [ # # ]: 0 : if (a->data.x_ptr.data.base_err_union_code.err_union_val !=
6006 [ # # ]: 0 : b->data.x_ptr.data.base_err_union_code.err_union_val &&
6007 : 0 : a->data.x_ptr.data.base_err_union_code.err_union_val->global_refs !=
6008 : 0 : b->data.x_ptr.data.base_err_union_code.err_union_val->global_refs)
6009 : : {
6010 : 0 : return false;
6011 : : }
6012 : 0 : return true;
6013 : 0 : case ConstPtrSpecialBaseErrorUnionPayload:
6014 [ # # ]: 0 : if (a->data.x_ptr.data.base_err_union_payload.err_union_val !=
6015 [ # # ]: 0 : b->data.x_ptr.data.base_err_union_payload.err_union_val &&
6016 : 0 : a->data.x_ptr.data.base_err_union_payload.err_union_val->global_refs !=
6017 : 0 : b->data.x_ptr.data.base_err_union_payload.err_union_val->global_refs)
6018 : : {
6019 : 0 : return false;
6020 : : }
6021 : 0 : return true;
6022 : 0 : case ConstPtrSpecialBaseOptionalPayload:
6023 [ # # ]: 0 : if (a->data.x_ptr.data.base_optional_payload.optional_val !=
6024 [ # # ]: 0 : b->data.x_ptr.data.base_optional_payload.optional_val &&
6025 : 0 : a->data.x_ptr.data.base_optional_payload.optional_val->global_refs !=
6026 : 0 : b->data.x_ptr.data.base_optional_payload.optional_val->global_refs)
6027 : : {
6028 : 0 : return false;
6029 : : }
6030 : 0 : return true;
6031 : 40 : case ConstPtrSpecialHardCodedAddr:
6032 [ - + ]: 40 : if (a->data.x_ptr.data.hard_coded_addr.addr != b->data.x_ptr.data.hard_coded_addr.addr)
6033 : 0 : return false;
6034 : 40 : return true;
6035 : 0 : case ConstPtrSpecialDiscard:
6036 : 0 : return true;
6037 : 16 : case ConstPtrSpecialFunction:
6038 : 16 : return a->data.x_ptr.data.fn.fn_entry == b->data.x_ptr.data.fn.fn_entry;
6039 : 8 : case ConstPtrSpecialNull:
6040 : 8 : return true;
6041 : : }
6042 : 0 : zig_unreachable();
6043 : : }
6044 : :
6045 : 8 : static bool const_values_equal_array(CodeGen *g, ConstExprValue *a, ConstExprValue *b, size_t len) {
6046 : 8 : assert(a->data.x_array.special != ConstArraySpecialUndef);
6047 : 8 : assert(b->data.x_array.special != ConstArraySpecialUndef);
6048 [ # # ][ - + ]: 8 : if (a->data.x_array.special == ConstArraySpecialBuf &&
6049 : 0 : b->data.x_array.special == ConstArraySpecialBuf)
6050 : : {
6051 : 0 : return buf_eql_buf(a->data.x_array.data.s_buf, b->data.x_array.data.s_buf);
6052 : : }
6053 : 8 : expand_undef_array(g, a);
6054 : 8 : expand_undef_array(g, b);
6055 : :
6056 : 8 : ConstExprValue *a_elems = a->data.x_array.data.s_none.elements;
6057 : 8 : ConstExprValue *b_elems = b->data.x_array.data.s_none.elements;
6058 : :
6059 [ + + ]: 24 : for (size_t i = 0; i < len; i += 1) {
6060 [ - + ]: 16 : if (!const_values_equal(g, &a_elems[i], &b_elems[i]))
6061 : 0 : return false;
6062 : : }
6063 : :
6064 : 8 : return true;
6065 : : }
6066 : :
6067 : 914991 : bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
6068 : 914991 : assert(a->type->id == b->type->id);
6069 : 914991 : assert(a->special == ConstValSpecialStatic);
6070 : 914991 : assert(b->special == ConstValSpecialStatic);
6071 [ - + + + : 914991 : switch (a->type->id) {
- + + + -
+ + + - +
+ - - - -
+ - - -
- ]
6072 : 0 : case ZigTypeIdOpaque:
6073 : 0 : zig_unreachable();
6074 : 33334 : case ZigTypeIdEnum:
6075 : 33334 : return bigint_cmp(&a->data.x_enum_tag, &b->data.x_enum_tag) == CmpEQ;
6076 : 152 : case ZigTypeIdUnion: {
6077 : 152 : ConstUnionValue *union1 = &a->data.x_union;
6078 : 152 : ConstUnionValue *union2 = &b->data.x_union;
6079 : :
6080 [ + + ]: 152 : if (bigint_cmp(&union1->tag, &union2->tag) == CmpEQ) {
6081 : 72 : TypeUnionField *field = find_union_field_by_tag(a->type, &union1->tag);
6082 : 72 : assert(field != nullptr);
6083 [ + + ]: 72 : if (!type_has_bits(field->type_entry))
6084 : 24 : return true;
6085 : 48 : assert(find_union_field_by_tag(a->type, &union2->tag) != nullptr);
6086 : 48 : return const_values_equal(g, union1->payload, union2->payload);
6087 : : }
6088 : 80 : return false;
6089 : : }
6090 : 43688 : case ZigTypeIdMetaType:
6091 : 43688 : return a->data.x_type == b->data.x_type;
6092 : 0 : case ZigTypeIdVoid:
6093 : 0 : return true;
6094 : 32 : case ZigTypeIdErrorSet:
6095 : 32 : return a->data.x_err_set->value == b->data.x_err_set->value;
6096 : 10925 : case ZigTypeIdBool:
6097 : 10925 : return a->data.x_bool == b->data.x_bool;
6098 : 57966 : case ZigTypeIdFloat:
6099 : 57966 : assert(a->type->data.floating.bit_count == b->type->data.floating.bit_count);
6100 [ + + + + : 57966 : switch (a->type->data.floating.bit_count) {
- ]
6101 : 162 : case 16:
6102 : 162 : return f16_eq(a->data.x_f16, b->data.x_f16);
6103 : 96 : case 32:
6104 : 96 : return a->data.x_f32 == b->data.x_f32;
6105 : 57676 : case 64:
6106 : 57676 : return a->data.x_f64 == b->data.x_f64;
6107 : 32 : case 128:
6108 : 32 : return f128M_eq(&a->data.x_f128, &b->data.x_f128);
6109 : 0 : default:
6110 : 0 : zig_unreachable();
6111 : : }
6112 : 0 : case ZigTypeIdComptimeFloat:
6113 : 0 : return bigfloat_cmp(&a->data.x_bigfloat, &b->data.x_bigfloat) == CmpEQ;
6114 : 51345 : case ZigTypeIdInt:
6115 : : case ZigTypeIdComptimeInt:
6116 : 51345 : return bigint_cmp(&a->data.x_bigint, &b->data.x_bigint) == CmpEQ;
6117 : 16 : case ZigTypeIdEnumLiteral:
6118 : 16 : return buf_eql_buf(a->data.x_enum_literal, b->data.x_enum_literal);
6119 : 358940 : case ZigTypeIdPointer:
6120 : : case ZigTypeIdFn:
6121 : 358940 : return const_values_equal_ptr(a, b);
6122 : 0 : case ZigTypeIdVector:
6123 : 0 : assert(a->type->data.vector.len == b->type->data.vector.len);
6124 : 0 : return const_values_equal_array(g, a, b, a->type->data.vector.len);
6125 : 8 : case ZigTypeIdArray: {
6126 : 8 : assert(a->type->data.array.len == b->type->data.array.len);
6127 : 8 : return const_values_equal_array(g, a, b, a->type->data.array.len);
6128 : : }
6129 : 357836 : case ZigTypeIdStruct:
6130 [ + + ]: 393832 : for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) {
6131 : 375834 : ConstExprValue *field_a = &a->data.x_struct.fields[i];
6132 : 375834 : ConstExprValue *field_b = &b->data.x_struct.fields[i];
6133 [ + + ]: 375834 : if (!const_values_equal(g, field_a, field_b))
6134 : 339838 : return false;
6135 : : }
6136 : 17998 : return true;
6137 : 0 : case ZigTypeIdFnFrame:
6138 : 0 : zig_panic("TODO");
6139 : 0 : case ZigTypeIdAnyFrame:
6140 : 0 : zig_panic("TODO");
6141 : 0 : case ZigTypeIdUndefined:
6142 : 0 : zig_panic("TODO");
6143 : 0 : case ZigTypeIdNull:
6144 : 0 : zig_panic("TODO");
6145 : 749 : case ZigTypeIdOptional:
6146 [ + + ]: 749 : if (get_codegen_ptr_type(a->type) != nullptr)
6147 : 72 : return const_values_equal_ptr(a, b);
6148 [ + + ][ - + ]: 677 : if (a->data.x_optional == nullptr || b->data.x_optional == nullptr) {
6149 [ + - ][ + - ]: 471 : return (a->data.x_optional == nullptr && b->data.x_optional == nullptr);
6150 : : } else {
6151 : 206 : return const_values_equal(g, a->data.x_optional, b->data.x_optional);
6152 : : }
6153 : 0 : case ZigTypeIdErrorUnion:
6154 : 0 : zig_panic("TODO");
6155 : 0 : case ZigTypeIdArgTuple:
6156 [ # # ][ # # ]: 0 : return a->data.x_arg_tuple.start_index == b->data.x_arg_tuple.start_index &&
6157 : 0 : a->data.x_arg_tuple.end_index == b->data.x_arg_tuple.end_index;
6158 : 0 : case ZigTypeIdBoundFn:
6159 : : case ZigTypeIdInvalid:
6160 : : case ZigTypeIdUnreachable:
6161 : 0 : zig_unreachable();
6162 : : }
6163 : 0 : zig_unreachable();
6164 : : }
6165 : :
6166 : 213 : void eval_min_max_value_int(CodeGen *g, ZigType *int_type, BigInt *bigint, bool is_max) {
6167 : 213 : assert(int_type->id == ZigTypeIdInt);
6168 [ + + ]: 213 : if (int_type->data.integral.bit_count == 0) {
6169 : 32 : bigint_init_unsigned(bigint, 0);
6170 : 32 : return;
6171 : : }
6172 [ + + ]: 181 : if (is_max) {
6173 : : // is_signed=true (1 << (bit_count - 1)) - 1
6174 : : // is_signed=false (1 << (bit_count - 0)) - 1
6175 : 82 : BigInt one = {0};
6176 : 82 : bigint_init_unsigned(&one, 1);
6177 : :
6178 [ - + ]: 82 : size_t shift_amt = int_type->data.integral.bit_count - (int_type->data.integral.is_signed ? 1 : 0);
6179 : 82 : BigInt bit_count_bi = {0};
6180 : 82 : bigint_init_unsigned(&bit_count_bi, shift_amt);
6181 : :
6182 : 82 : BigInt shifted_bi = {0};
6183 : 82 : bigint_shl(&shifted_bi, &one, &bit_count_bi);
6184 : :
6185 : 82 : bigint_sub(bigint, &shifted_bi, &one);
6186 [ + + ]: 99 : } else if (int_type->data.integral.is_signed) {
6187 : : // - (1 << (bit_count - 1))
6188 : 26 : BigInt one = {0};
6189 : 26 : bigint_init_unsigned(&one, 1);
6190 : :
6191 : 26 : BigInt bit_count_bi = {0};
6192 : 26 : bigint_init_unsigned(&bit_count_bi, int_type->data.integral.bit_count - 1);
6193 : :
6194 : 26 : BigInt shifted_bi = {0};
6195 : 26 : bigint_shl(&shifted_bi, &one, &bit_count_bi);
6196 : :
6197 : 26 : bigint_negate(bigint, &shifted_bi);
6198 : : } else {
6199 : 73 : bigint_init_unsigned(bigint, 0);
6200 : : }
6201 : : }
6202 : :
6203 : 0 : void eval_min_max_value(CodeGen *g, ZigType *type_entry, ConstExprValue *const_val, bool is_max) {
6204 [ # # ]: 0 : if (type_entry->id == ZigTypeIdInt) {
6205 : 0 : const_val->special = ConstValSpecialStatic;
6206 : 0 : eval_min_max_value_int(g, type_entry, &const_val->data.x_bigint, is_max);
6207 [ # # ]: 0 : } else if (type_entry->id == ZigTypeIdBool) {
6208 : 0 : const_val->special = ConstValSpecialStatic;
6209 : 0 : const_val->data.x_bool = is_max;
6210 [ # # ]: 0 : } else if (type_entry->id == ZigTypeIdVoid) {
6211 : : // nothing to do
6212 : : } else {
6213 : 0 : zig_unreachable();
6214 : : }
6215 : 0 : }
6216 : :
6217 : 0 : static void render_const_val_ptr(CodeGen *g, Buf *buf, ConstExprValue *const_val, ZigType *type_entry) {
6218 : 0 : assert(type_entry->id == ZigTypeIdPointer);
6219 : :
6220 [ # # ]: 0 : if (type_entry->data.pointer.child_type->id == ZigTypeIdOpaque) {
6221 : 0 : buf_append_buf(buf, &type_entry->name);
6222 : 0 : return;
6223 : : }
6224 : :
6225 [ # # # # : 0 : switch (const_val->data.x_ptr.special) {
# # # # ]
6226 : 0 : case ConstPtrSpecialInvalid:
6227 : 0 : zig_unreachable();
6228 : 0 : case ConstPtrSpecialRef:
6229 : : case ConstPtrSpecialBaseStruct:
6230 : : case ConstPtrSpecialBaseErrorUnionCode:
6231 : : case ConstPtrSpecialBaseErrorUnionPayload:
6232 : : case ConstPtrSpecialBaseOptionalPayload:
6233 : 0 : buf_appendf(buf, "*");
6234 : : // TODO we need a source node for const_ptr_pointee because it can generate compile errors
6235 : 0 : render_const_value(g, buf, const_ptr_pointee(nullptr, g, const_val, nullptr));
6236 : 0 : return;
6237 : 0 : case ConstPtrSpecialBaseArray:
6238 [ # # ]: 0 : if (const_val->data.x_ptr.data.base_array.is_cstr) {
6239 : 0 : buf_appendf(buf, "*(c str lit)");
6240 : 0 : return;
6241 : : } else {
6242 : 0 : buf_appendf(buf, "*");
6243 : : // TODO we need a source node for const_ptr_pointee because it can generate compile errors
6244 : 0 : render_const_value(g, buf, const_ptr_pointee(nullptr, g, const_val, nullptr));
6245 : 0 : return;
6246 : : }
6247 : 0 : case ConstPtrSpecialHardCodedAddr:
6248 : 0 : buf_appendf(buf, "(%s)(%" ZIG_PRI_x64 ")", buf_ptr(&type_entry->name),
6249 : : const_val->data.x_ptr.data.hard_coded_addr.addr);
6250 : 0 : return;
6251 : 0 : case ConstPtrSpecialDiscard:
6252 : 0 : buf_append_str(buf, "*_");
6253 : 0 : return;
6254 : 0 : case ConstPtrSpecialFunction:
6255 : : {
6256 : 0 : ZigFn *fn_entry = const_val->data.x_ptr.data.fn.fn_entry;
6257 : 0 : buf_appendf(buf, "@ptrCast(%s, %s)", buf_ptr(&const_val->type->name), buf_ptr(&fn_entry->symbol_name));
6258 : 0 : return;
6259 : : }
6260 : 0 : case ConstPtrSpecialNull:
6261 : 0 : buf_append_str(buf, "null");
6262 : 0 : return;
6263 : : }
6264 : 0 : zig_unreachable();
6265 : : }
6266 : :
6267 : 0 : static void render_const_val_err_set(CodeGen *g, Buf *buf, ConstExprValue *const_val, ZigType *type_entry) {
6268 [ # # ]: 0 : if (const_val->data.x_err_set == nullptr) {
6269 : 0 : buf_append_str(buf, "null");
6270 : : } else {
6271 : 0 : buf_appendf(buf, "%s.%s", buf_ptr(&type_entry->name), buf_ptr(&const_val->data.x_err_set->name));
6272 : : }
6273 : 0 : }
6274 : :
6275 : 8 : static void render_const_val_array(CodeGen *g, Buf *buf, Buf *type_name, ConstExprValue *const_val, uint64_t start, uint64_t len) {
6276 : 8 : ConstArrayValue *array = &const_val->data.x_array;
6277 [ - + - - ]: 8 : switch (array->special) {
6278 : 0 : case ConstArraySpecialUndef:
6279 : 0 : buf_append_str(buf, "undefined");
6280 : 0 : return;
6281 : 8 : case ConstArraySpecialBuf: {
6282 : 8 : Buf *array_buf = array->data.s_buf;
6283 : 8 : const char *base = &buf_ptr(array_buf)[start];
6284 : 8 : assert(start + len <= buf_len(array_buf));
6285 : :
6286 : 8 : buf_append_char(buf, '"');
6287 [ + + ]: 40 : for (size_t i = 0; i < len; i += 1) {
6288 : 32 : uint8_t c = base[i];
6289 [ - + ]: 32 : if (c == '"') {
6290 : 0 : buf_append_str(buf, "\\\"");
6291 : : } else {
6292 : 32 : buf_append_char(buf, c);
6293 : : }
6294 : : }
6295 : 8 : buf_append_char(buf, '"');
6296 : 8 : return;
6297 : : }
6298 : 0 : case ConstArraySpecialNone: {
6299 : 0 : ConstExprValue *base = &array->data.s_none.elements[start];
6300 : 0 : assert(start + len <= const_val->type->data.array.len);
6301 : :
6302 : 0 : buf_appendf(buf, "%s{", buf_ptr(type_name));
6303 [ # # ]: 0 : for (uint64_t i = 0; i < len; i += 1) {
6304 [ # # ]: 0 : if (i != 0) buf_appendf(buf, ",");
6305 : 0 : render_const_value(g, buf, &base[i]);
6306 : : }
6307 : 0 : buf_appendf(buf, "}");
6308 : 0 : return;
6309 : : }
6310 : : }
6311 : 0 : zig_unreachable();
6312 : : }
6313 : :
6314 : 1192 : void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
6315 [ - - - + : 1192 : switch (const_val->special) {
- ]
6316 : 0 : case ConstValSpecialRuntime:
6317 : 0 : buf_appendf(buf, "(runtime value)");
6318 : 0 : return;
6319 : 0 : case ConstValSpecialLazy:
6320 : 0 : buf_appendf(buf, "(lazy value)");
6321 : 0 : return;
6322 : 0 : case ConstValSpecialUndef:
6323 : 0 : buf_appendf(buf, "undefined");
6324 : 0 : return;
6325 : 1192 : case ConstValSpecialStatic:
6326 : 1192 : break;
6327 : : }
6328 : 1192 : assert(const_val->type);
6329 : :
6330 : 1192 : ZigType *type_entry = const_val->type;
6331 [ - - - - : 1192 : switch (type_entry->id) {
- + - + -
+ + - - -
- - + - +
- - + - -
- - - ]
6332 : 0 : case ZigTypeIdOpaque:
6333 : 0 : zig_unreachable();
6334 : 0 : case ZigTypeIdInvalid:
6335 : 0 : buf_appendf(buf, "(invalid)");
6336 : 0 : return;
6337 : 0 : case ZigTypeIdVoid:
6338 : 0 : buf_appendf(buf, "{}");
6339 : 0 : return;
6340 : 0 : case ZigTypeIdComptimeFloat:
6341 : 0 : bigfloat_append_buf(buf, &const_val->data.x_bigfloat);
6342 : 0 : return;
6343 : 0 : case ZigTypeIdFloat:
6344 [ # # # # : 0 : switch (type_entry->data.floating.bit_count) {
# ]
6345 : 0 : case 16:
6346 : 0 : buf_appendf(buf, "%f", zig_f16_to_double(const_val->data.x_f16));
6347 : 0 : return;
6348 : 0 : case 32:
6349 : 0 : buf_appendf(buf, "%f", const_val->data.x_f32);
6350 : 0 : return;
6351 : 0 : case 64:
6352 : 0 : buf_appendf(buf, "%f", const_val->data.x_f64);
6353 : 0 : return;
6354 : 0 : case 128:
6355 : : {
6356 : 0 : const size_t extra_len = 100;
6357 : 0 : size_t old_len = buf_len(buf);
6358 : 0 : buf_resize(buf, old_len + extra_len);
6359 : 0 : float64_t f64_value = f128M_to_f64(&const_val->data.x_f128);
6360 : : double double_value;
6361 : 0 : memcpy(&double_value, &f64_value, sizeof(double));
6362 : : // TODO actual f128 printing to decimal
6363 : 0 : int len = snprintf(buf_ptr(buf) + old_len, extra_len, "%f", double_value);
6364 : 0 : assert(len > 0);
6365 : 0 : buf_resize(buf, old_len + len);
6366 : 0 : return;
6367 : : }
6368 : 0 : default:
6369 : 0 : zig_unreachable();
6370 : : }
6371 : 88 : case ZigTypeIdComptimeInt:
6372 : : case ZigTypeIdInt:
6373 : 88 : bigint_append_buf(buf, &const_val->data.x_bigint, 10);
6374 : 88 : return;
6375 : 0 : case ZigTypeIdEnumLiteral:
6376 : 0 : buf_append_buf(buf, const_val->data.x_enum_literal);
6377 : 0 : return;
6378 : 411 : case ZigTypeIdMetaType:
6379 : 411 : buf_appendf(buf, "%s", buf_ptr(&const_val->data.x_type->name));
6380 : 411 : return;
6381 : 0 : case ZigTypeIdUnreachable:
6382 : 0 : buf_appendf(buf, "unreachable");
6383 : 0 : return;
6384 : 544 : case ZigTypeIdBool:
6385 : : {
6386 [ + + ]: 544 : const char *value = const_val->data.x_bool ? "true" : "false";
6387 : 544 : buf_appendf(buf, "%s", value);
6388 : 544 : return;
6389 : : }
6390 : 26 : case ZigTypeIdFn:
6391 : : {
6392 : 26 : assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst);
6393 : 26 : assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction);
6394 : 26 : ZigFn *fn_entry = const_val->data.x_ptr.data.fn.fn_entry;
6395 : 26 : buf_appendf(buf, "%s", buf_ptr(&fn_entry->symbol_name));
6396 : 26 : return;
6397 : : }
6398 : 0 : case ZigTypeIdPointer:
6399 : 0 : return render_const_val_ptr(g, buf, const_val, type_entry);
6400 : 0 : case ZigTypeIdArray: {
6401 : 0 : uint64_t len = type_entry->data.array.len;
6402 : 0 : render_const_val_array(g, buf, &type_entry->name, const_val, 0, len);
6403 : 0 : return;
6404 : : }
6405 : 0 : case ZigTypeIdVector: {
6406 : 0 : uint32_t len = type_entry->data.vector.len;
6407 : 0 : render_const_val_array(g, buf, &type_entry->name, const_val, 0, len);
6408 : 0 : return;
6409 : : }
6410 : 0 : case ZigTypeIdNull:
6411 : : {
6412 : 0 : buf_appendf(buf, "null");
6413 : 0 : return;
6414 : : }
6415 : 0 : case ZigTypeIdUndefined:
6416 : : {
6417 : 0 : buf_appendf(buf, "undefined");
6418 : 0 : return;
6419 : : }
6420 : 82 : case ZigTypeIdOptional:
6421 : : {
6422 [ - + ]: 82 : if (get_codegen_ptr_type(const_val->type) != nullptr)
6423 : 0 : return render_const_val_ptr(g, buf, const_val, type_entry->data.maybe.child_type);
6424 [ - + ]: 82 : if (type_entry->data.maybe.child_type->id == ZigTypeIdErrorSet)
6425 : 0 : return render_const_val_err_set(g, buf, const_val, type_entry->data.maybe.child_type);
6426 [ - + ]: 82 : if (const_val->data.x_optional) {
6427 : 0 : render_const_value(g, buf, const_val->data.x_optional);
6428 : : } else {
6429 : 82 : buf_appendf(buf, "null");
6430 : : }
6431 : 82 : return;
6432 : : }
6433 : 0 : case ZigTypeIdBoundFn:
6434 : : {
6435 : 0 : ZigFn *fn_entry = const_val->data.x_bound_fn.fn;
6436 : 0 : buf_appendf(buf, "(bound fn %s)", buf_ptr(&fn_entry->symbol_name));
6437 : 0 : return;
6438 : : }
6439 : 9 : case ZigTypeIdStruct:
6440 : : {
6441 [ + + ]: 9 : if (is_slice(type_entry)) {
6442 : 8 : ConstExprValue *len_val = &const_val->data.x_struct.fields[slice_len_index];
6443 : 8 : size_t len = bigint_as_usize(&len_val->data.x_bigint);
6444 : :
6445 : 8 : ConstExprValue *ptr_val = &const_val->data.x_struct.fields[slice_ptr_index];
6446 [ - + ]: 8 : if (ptr_val->special == ConstValSpecialUndef) {
6447 : 0 : assert(len == 0);
6448 : 0 : buf_appendf(buf, "((%s)(undefined))[0..0]", buf_ptr(&type_entry->name));
6449 : 0 : return;
6450 : : }
6451 : 8 : assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray);
6452 : 8 : ConstExprValue *array = ptr_val->data.x_ptr.data.base_array.array_val;
6453 : 8 : size_t start = ptr_val->data.x_ptr.data.base_array.elem_index;
6454 : :
6455 : 8 : render_const_val_array(g, buf, &type_entry->name, array, start, len);
6456 : : } else {
6457 : 1 : buf_appendf(buf, "(struct %s constant)", buf_ptr(&type_entry->name));
6458 : : }
6459 : 9 : return;
6460 : : }
6461 : 0 : case ZigTypeIdEnum:
6462 : : {
6463 : 0 : TypeEnumField *field = find_enum_field_by_tag(type_entry, &const_val->data.x_enum_tag);
6464 : 0 : buf_appendf(buf, "%s.%s", buf_ptr(&type_entry->name), buf_ptr(field->name));
6465 : 0 : return;
6466 : : }
6467 : 0 : case ZigTypeIdErrorUnion:
6468 : : {
6469 : 0 : buf_appendf(buf, "%s(", buf_ptr(&type_entry->name));
6470 : 0 : ErrorTableEntry *err_set = const_val->data.x_err_union.error_set->data.x_err_set;
6471 [ # # ]: 0 : if (err_set == nullptr) {
6472 : 0 : render_const_value(g, buf, const_val->data.x_err_union.payload);
6473 : : } else {
6474 : 0 : buf_appendf(buf, "%s.%s", buf_ptr(&type_entry->data.error_union.err_set_type->name),
6475 : : buf_ptr(&err_set->name));
6476 : : }
6477 : 0 : buf_appendf(buf, ")");
6478 : 0 : return;
6479 : : }
6480 : 32 : case ZigTypeIdUnion:
6481 : : {
6482 : 32 : const BigInt *tag = &const_val->data.x_union.tag;
6483 : 32 : TypeUnionField *field = find_union_field_by_tag(type_entry, tag);
6484 : 32 : buf_appendf(buf, "%s { .%s = ", buf_ptr(&type_entry->name), buf_ptr(field->name));
6485 : 32 : render_const_value(g, buf, const_val->data.x_union.payload);
6486 : 32 : buf_append_str(buf, "}");
6487 : 32 : return;
6488 : : }
6489 : 0 : case ZigTypeIdErrorSet:
6490 : 0 : return render_const_val_err_set(g, buf, const_val, type_entry);
6491 : 0 : case ZigTypeIdArgTuple:
6492 : : {
6493 : 0 : buf_appendf(buf, "(args value)");
6494 : 0 : return;
6495 : : }
6496 : 0 : case ZigTypeIdFnFrame:
6497 : 0 : buf_appendf(buf, "(TODO: async function frame value)");
6498 : 0 : return;
6499 : :
6500 : 0 : case ZigTypeIdAnyFrame:
6501 : 0 : buf_appendf(buf, "(TODO: anyframe value)");
6502 : 0 : return;
6503 : :
6504 : : }
6505 : 0 : zig_unreachable();
6506 : : }
6507 : :
6508 : 494 : ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
6509 : 494 : assert(size_in_bits <= 65535);
6510 : 494 : ZigType *entry = new_type_table_entry(ZigTypeIdInt);
6511 : :
6512 : 494 : entry->size_in_bits = size_in_bits;
6513 [ + + ]: 494 : if (size_in_bits != 0) {
6514 : 486 : entry->llvm_type = LLVMIntType(size_in_bits);
6515 : 486 : entry->abi_size = LLVMABISizeOfType(g->target_data_ref, entry->llvm_type);
6516 : 486 : entry->abi_align = LLVMABIAlignmentOfType(g->target_data_ref, entry->llvm_type);
6517 : :
6518 [ + - ][ + + ]: 486 : if (size_in_bits >= 128 && entry->abi_align < 16) {
6519 : : // Override the incorrect alignment reported by LLVM. Clang does this as well.
6520 : : // On x86_64 there are some instructions like CMPXCHG16B which require this.
6521 : : // On all targets, integers 128 bits and above have ABI alignment of 16.
6522 : : // However for some targets, LLVM incorrectly reports this as 8.
6523 : : // See: https://github.com/ziglang/zig/issues/2987
6524 : 35 : entry->abi_align = 16;
6525 : : }
6526 : : }
6527 : :
6528 [ + + ]: 494 : const char u_or_i = is_signed ? 'i' : 'u';
6529 : 494 : buf_resize(&entry->name, 0);
6530 : 494 : buf_appendf(&entry->name, "%c%" PRIu32, u_or_i, size_in_bits);
6531 : :
6532 : 494 : entry->data.integral.is_signed = is_signed;
6533 : 494 : entry->data.integral.bit_count = size_in_bits;
6534 : 494 : return entry;
6535 : : }
6536 : :
6537 : 289392 : uint32_t type_id_hash(TypeId x) {
6538 [ - + + + : 289392 : switch (x.id) {
+ + - ]
6539 : 0 : case ZigTypeIdInvalid:
6540 : : case ZigTypeIdOpaque:
6541 : : case ZigTypeIdMetaType:
6542 : : case ZigTypeIdVoid:
6543 : : case ZigTypeIdBool:
6544 : : case ZigTypeIdUnreachable:
6545 : : case ZigTypeIdFloat:
6546 : : case ZigTypeIdStruct:
6547 : : case ZigTypeIdComptimeFloat:
6548 : : case ZigTypeIdComptimeInt:
6549 : : case ZigTypeIdEnumLiteral:
6550 : : case ZigTypeIdUndefined:
6551 : : case ZigTypeIdNull:
6552 : : case ZigTypeIdOptional:
6553 : : case ZigTypeIdErrorSet:
6554 : : case ZigTypeIdEnum:
6555 : : case ZigTypeIdUnion:
6556 : : case ZigTypeIdFn:
6557 : : case ZigTypeIdBoundFn:
6558 : : case ZigTypeIdArgTuple:
6559 : : case ZigTypeIdFnFrame:
6560 : : case ZigTypeIdAnyFrame:
6561 : 0 : zig_unreachable();
6562 : 20421 : case ZigTypeIdErrorUnion:
6563 : 20421 : return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type);
6564 : 118840 : case ZigTypeIdPointer:
6565 : 118840 : return hash_ptr(x.data.pointer.child_type) +
6566 [ + + ]: 118840 : ((x.data.pointer.ptr_len == PtrLenSingle) ? (uint32_t)1120226602 : (uint32_t)3200913342) +
6567 [ + + ]: 118840 : (x.data.pointer.is_const ? (uint32_t)2749109194 : (uint32_t)4047371087) +
6568 [ + + ]: 118840 : (x.data.pointer.is_volatile ? (uint32_t)536730450 : (uint32_t)1685612214) +
6569 [ + + ]: 118840 : (x.data.pointer.allow_zero ? (uint32_t)3324284834 : (uint32_t)3584904923) +
6570 : 237680 : (((uint32_t)x.data.pointer.alignment) ^ (uint32_t)0x777fbe0e) +
6571 : 118840 : (((uint32_t)x.data.pointer.bit_offset_in_host) ^ (uint32_t)2639019452) +
6572 : 118840 : (((uint32_t)x.data.pointer.host_int_bytes) ^ (uint32_t)529908881);
6573 : 33967 : case ZigTypeIdArray:
6574 : 33967 : return hash_ptr(x.data.array.child_type) +
6575 : 33967 : ((uint32_t)x.data.array.size ^ (uint32_t)2122979968);
6576 : 115884 : case ZigTypeIdInt:
6577 [ + + ]: 115884 : return (x.data.integer.is_signed ? (uint32_t)2652528194 : (uint32_t)163929201) +
6578 : 115884 : (((uint32_t)x.data.integer.bit_count) ^ (uint32_t)2998081557);
6579 : 280 : case ZigTypeIdVector:
6580 : 280 : return hash_ptr(x.data.vector.elem_type) * (x.data.vector.len * 526582681);
6581 : : }
6582 : 0 : zig_unreachable();
6583 : : }
6584 : :
6585 : 1025272 : bool type_id_eql(TypeId a, TypeId b) {
6586 [ + + ]: 1025272 : if (a.id != b.id)
6587 : 372867 : return false;
6588 [ - + + + : 652405 : switch (a.id) {
+ + - ]
6589 : 0 : case ZigTypeIdInvalid:
6590 : : case ZigTypeIdMetaType:
6591 : : case ZigTypeIdVoid:
6592 : : case ZigTypeIdBool:
6593 : : case ZigTypeIdUnreachable:
6594 : : case ZigTypeIdFloat:
6595 : : case ZigTypeIdStruct:
6596 : : case ZigTypeIdComptimeFloat:
6597 : : case ZigTypeIdComptimeInt:
6598 : : case ZigTypeIdEnumLiteral:
6599 : : case ZigTypeIdUndefined:
6600 : : case ZigTypeIdNull:
6601 : : case ZigTypeIdOptional:
6602 : : case ZigTypeIdErrorSet:
6603 : : case ZigTypeIdEnum:
6604 : : case ZigTypeIdUnion:
6605 : : case ZigTypeIdFn:
6606 : : case ZigTypeIdBoundFn:
6607 : : case ZigTypeIdArgTuple:
6608 : : case ZigTypeIdOpaque:
6609 : : case ZigTypeIdFnFrame:
6610 : : case ZigTypeIdAnyFrame:
6611 : 0 : zig_unreachable();
6612 : 51504 : case ZigTypeIdErrorUnion:
6613 [ + + ][ + + ]: 51504 : return a.data.error_union.err_set_type == b.data.error_union.err_set_type &&
6614 : 51504 : a.data.error_union.payload_type == b.data.error_union.payload_type;
6615 : :
6616 : 161105 : case ZigTypeIdPointer:
6617 [ + + ]: 142661 : return a.data.pointer.child_type == b.data.pointer.child_type &&
6618 [ + + ]: 141413 : a.data.pointer.ptr_len == b.data.pointer.ptr_len &&
6619 [ + - ]: 141283 : a.data.pointer.is_const == b.data.pointer.is_const &&
6620 [ + - ]: 141283 : a.data.pointer.is_volatile == b.data.pointer.is_volatile &&
6621 [ + + ]: 141283 : a.data.pointer.allow_zero == b.data.pointer.allow_zero &&
6622 [ + + ]: 111468 : a.data.pointer.alignment == b.data.pointer.alignment &&
6623 [ + + ][ + + ]: 303766 : a.data.pointer.bit_offset_in_host == b.data.pointer.bit_offset_in_host &&
6624 : 161105 : a.data.pointer.host_int_bytes == b.data.pointer.host_int_bytes;
6625 : 268332 : case ZigTypeIdArray:
6626 [ + + ][ + + ]: 268332 : return a.data.array.child_type == b.data.array.child_type &&
6627 : 268332 : a.data.array.size == b.data.array.size;
6628 : 171267 : case ZigTypeIdInt:
6629 [ + + ][ + + ]: 171267 : return a.data.integer.is_signed == b.data.integer.is_signed &&
6630 : 171267 : a.data.integer.bit_count == b.data.integer.bit_count;
6631 : 197 : case ZigTypeIdVector:
6632 [ + - ][ + - ]: 197 : return a.data.vector.elem_type == b.data.vector.elem_type &&
6633 : 197 : a.data.vector.len == b.data.vector.len;
6634 : : }
6635 : 0 : zig_unreachable();
6636 : : }
6637 : :
6638 : 8263 : uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) {
6639 [ + + + + : 8263 : switch (x.id) {
+ + + +
- ]
6640 : 72 : case ZigLLVMFnIdCtz:
6641 : 72 : return (uint32_t)(x.data.ctz.bit_count) * (uint32_t)810453934;
6642 : 230 : case ZigLLVMFnIdClz:
6643 : 230 : return (uint32_t)(x.data.clz.bit_count) * (uint32_t)2428952817;
6644 : 106 : case ZigLLVMFnIdPopCount:
6645 : 106 : return (uint32_t)(x.data.clz.bit_count) * (uint32_t)101195049;
6646 : 694 : case ZigLLVMFnIdFloatOp:
6647 : 1388 : return (uint32_t)(x.data.floating.bit_count) * ((uint32_t)x.id + 1025) +
6648 : 694 : (uint32_t)(x.data.floating.vector_len) * (((uint32_t)x.id << 5) + 1025) +
6649 : 694 : (uint32_t)(x.data.floating.op) * (uint32_t)43789879;
6650 : 48 : case ZigLLVMFnIdFMA:
6651 : 48 : return (uint32_t)(x.data.floating.bit_count) * ((uint32_t)x.id + 1025) +
6652 : 48 : (uint32_t)(x.data.floating.vector_len) * (((uint32_t)x.id << 5) + 1025);
6653 : 49 : case ZigLLVMFnIdBswap:
6654 : 49 : return (uint32_t)(x.data.bswap.bit_count) * (uint32_t)3661994335;
6655 : 342 : case ZigLLVMFnIdBitReverse:
6656 : 342 : return (uint32_t)(x.data.bit_reverse.bit_count) * (uint32_t)2621398431;
6657 : 6722 : case ZigLLVMFnIdOverflowArithmetic:
6658 : 13444 : return ((uint32_t)(x.data.overflow_arithmetic.bit_count) * 87135777) +
6659 : 13444 : ((uint32_t)(x.data.overflow_arithmetic.add_sub_mul) * 31640542) +
6660 [ + + ]: 6722 : ((uint32_t)(x.data.overflow_arithmetic.is_signed) ? 1062315172 : 314955820) +
6661 : 6722 : x.data.overflow_arithmetic.vector_len * 1435156945;
6662 : : }
6663 : 0 : zig_unreachable();
6664 : : }
6665 : :
6666 : 9622 : bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
6667 [ + + ]: 9622 : if (a.id != b.id)
6668 : 1667 : return false;
6669 [ + + + + : 7955 : switch (a.id) {
+ + - +
- ]
6670 : 20 : case ZigLLVMFnIdCtz:
6671 : 20 : return a.data.ctz.bit_count == b.data.ctz.bit_count;
6672 : 334 : case ZigLLVMFnIdClz:
6673 : 334 : return a.data.clz.bit_count == b.data.clz.bit_count;
6674 : 24 : case ZigLLVMFnIdPopCount:
6675 : 24 : return a.data.pop_count.bit_count == b.data.pop_count.bit_count;
6676 : 10 : case ZigLLVMFnIdBswap:
6677 : 10 : return a.data.bswap.bit_count == b.data.bswap.bit_count;
6678 : 116 : case ZigLLVMFnIdBitReverse:
6679 : 116 : return a.data.bit_reverse.bit_count == b.data.bit_reverse.bit_count;
6680 : 362 : case ZigLLVMFnIdFloatOp:
6681 [ + - ]: 214 : return a.data.floating.bit_count == b.data.floating.bit_count &&
6682 [ + + ][ + + ]: 576 : a.data.floating.vector_len == b.data.floating.vector_len &&
6683 : 362 : a.data.floating.op == b.data.floating.op;
6684 : 0 : case ZigLLVMFnIdFMA:
6685 [ # # ][ # # ]: 0 : return a.data.floating.bit_count == b.data.floating.bit_count &&
6686 : 0 : a.data.floating.vector_len == b.data.floating.vector_len;
6687 : 7089 : case ZigLLVMFnIdOverflowArithmetic:
6688 [ + + ]: 5925 : return (a.data.overflow_arithmetic.bit_count == b.data.overflow_arithmetic.bit_count) &&
6689 [ + - ]: 5892 : (a.data.overflow_arithmetic.add_sub_mul == b.data.overflow_arithmetic.add_sub_mul) &&
6690 [ + + ][ + - ]: 13014 : (a.data.overflow_arithmetic.is_signed == b.data.overflow_arithmetic.is_signed) &&
6691 : 7089 : (a.data.overflow_arithmetic.vector_len == b.data.overflow_arithmetic.vector_len);
6692 : : }
6693 : 0 : zig_unreachable();
6694 : : }
6695 : :
6696 : 842564 : static void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
6697 : : Error err;
6698 : 842564 : ZigType *wanted_type = const_val->type;
6699 [ + + ]: 842564 : if (wanted_type->id == ZigTypeIdArray) {
6700 : 24 : const_val->special = ConstValSpecialStatic;
6701 : 24 : const_val->data.x_array.special = ConstArraySpecialUndef;
6702 [ + + ]: 842540 : } else if (wanted_type->id == ZigTypeIdStruct) {
6703 [ - + ]: 104 : if ((err = type_resolve(g, wanted_type, ResolveStatusZeroBitsKnown))) {
6704 : 0 : return;
6705 : : }
6706 : :
6707 : 104 : const_val->special = ConstValSpecialStatic;
6708 : 104 : size_t field_count = wanted_type->data.structure.src_field_count;
6709 : 104 : const_val->data.x_struct.fields = create_const_vals(field_count);
6710 [ + + ]: 256 : for (size_t i = 0; i < field_count; i += 1) {
6711 : 152 : ConstExprValue *field_val = &const_val->data.x_struct.fields[i];
6712 : 152 : field_val->type = wanted_type->data.structure.fields[i].type_entry;
6713 : 152 : assert(field_val->type);
6714 : 152 : init_const_undefined(g, field_val);
6715 : 152 : field_val->parent.id = ConstParentIdStruct;
6716 : 152 : field_val->parent.data.p_struct.struct_val = const_val;
6717 : 152 : field_val->parent.data.p_struct.field_index = i;
6718 : : }
6719 : : } else {
6720 : 842436 : const_val->special = ConstValSpecialUndef;
6721 : : }
6722 : : }
6723 : :
6724 : 52996 : void expand_undef_struct(CodeGen *g, ConstExprValue *const_val) {
6725 [ + + ]: 52996 : if (const_val->special == ConstValSpecialUndef) {
6726 : 116 : init_const_undefined(g, const_val);
6727 : : }
6728 : 52996 : }
6729 : :
6730 : : // Canonicalize the array value as ConstArraySpecialNone
6731 : 102980 : void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
6732 : : size_t elem_count;
6733 : : ZigType *elem_type;
6734 [ + + ]: 102980 : if (const_val->type->id == ZigTypeIdArray) {
6735 : 102620 : elem_count = const_val->type->data.array.len;
6736 : 102620 : elem_type = const_val->type->data.array.child_type;
6737 [ + - ]: 360 : } else if (const_val->type->id == ZigTypeIdVector) {
6738 : 360 : elem_count = const_val->type->data.vector.len;
6739 : 360 : elem_type = const_val->type->data.vector.elem_type;
6740 : : } else {
6741 : 0 : zig_unreachable();
6742 : : }
6743 [ + + ]: 102980 : if (const_val->special == ConstValSpecialUndef) {
6744 : 232 : const_val->special = ConstValSpecialStatic;
6745 : 232 : const_val->data.x_array.special = ConstArraySpecialUndef;
6746 : : }
6747 [ + + + - ]: 102980 : switch (const_val->data.x_array.special) {
6748 : 87063 : case ConstArraySpecialNone:
6749 : 87063 : return;
6750 : 256 : case ConstArraySpecialUndef: {
6751 : 256 : const_val->data.x_array.special = ConstArraySpecialNone;
6752 : 256 : const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
6753 [ + + ]: 842552 : for (size_t i = 0; i < elem_count; i += 1) {
6754 : 842296 : ConstExprValue *element_val = &const_val->data.x_array.data.s_none.elements[i];
6755 : 842296 : element_val->type = elem_type;
6756 : 842296 : init_const_undefined(g, element_val);
6757 : 842296 : element_val->parent.id = ConstParentIdArray;
6758 : 842296 : element_val->parent.data.p_array.array_val = const_val;
6759 : 842296 : element_val->parent.data.p_array.elem_index = i;
6760 : : }
6761 : 256 : return;
6762 : : }
6763 : 15661 : case ConstArraySpecialBuf: {
6764 : 15661 : Buf *buf = const_val->data.x_array.data.s_buf;
6765 : : // If we're doing this it means that we are potentially modifying the data,
6766 : : // so we can't have it be in the string literals table
6767 : 15661 : g->string_literals_table.maybe_remove(buf);
6768 : :
6769 : 15661 : const_val->data.x_array.special = ConstArraySpecialNone;
6770 : 15661 : assert(elem_count == buf_len(buf));
6771 : 15661 : const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
6772 [ + + ]: 798075 : for (size_t i = 0; i < elem_count; i += 1) {
6773 : 782414 : ConstExprValue *this_char = &const_val->data.x_array.data.s_none.elements[i];
6774 : 782414 : this_char->special = ConstValSpecialStatic;
6775 : 782414 : this_char->type = g->builtin_types.entry_u8;
6776 : 782414 : bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(buf)[i]);
6777 : 782414 : this_char->parent.id = ConstParentIdArray;
6778 : 782414 : this_char->parent.data.p_array.array_val = const_val;
6779 : 782414 : this_char->parent.data.p_array.elem_index = i;
6780 : : }
6781 : 15661 : return;
6782 : : }
6783 : : }
6784 : 0 : zig_unreachable();
6785 : : }
6786 : :
6787 : : static const ZigTypeId all_type_ids[] = {
6788 : : ZigTypeIdMetaType,
6789 : : ZigTypeIdVoid,
6790 : : ZigTypeIdBool,
6791 : : ZigTypeIdUnreachable,
6792 : : ZigTypeIdInt,
6793 : : ZigTypeIdFloat,
6794 : : ZigTypeIdPointer,
6795 : : ZigTypeIdArray,
6796 : : ZigTypeIdStruct,
6797 : : ZigTypeIdComptimeFloat,
6798 : : ZigTypeIdComptimeInt,
6799 : : ZigTypeIdUndefined,
6800 : : ZigTypeIdNull,
6801 : : ZigTypeIdOptional,
6802 : : ZigTypeIdErrorUnion,
6803 : : ZigTypeIdErrorSet,
6804 : : ZigTypeIdEnum,
6805 : : ZigTypeIdUnion,
6806 : : ZigTypeIdFn,
6807 : : ZigTypeIdBoundFn,
6808 : : ZigTypeIdArgTuple,
6809 : : ZigTypeIdOpaque,
6810 : : ZigTypeIdFnFrame,
6811 : : ZigTypeIdAnyFrame,
6812 : : ZigTypeIdVector,
6813 : : ZigTypeIdEnumLiteral,
6814 : : };
6815 : :
6816 : 1186 : ZigTypeId type_id_at_index(size_t index) {
6817 : 1186 : assert(index < array_length(all_type_ids));
6818 : 1186 : return all_type_ids[index];
6819 : : }
6820 : :
6821 : 13 : size_t type_id_len() {
6822 : 13 : return array_length(all_type_ids);
6823 : : }
6824 : :
6825 : 9412 : size_t type_id_index(ZigType *entry) {
6826 [ - + + + : 9412 : switch (entry->id) {
+ + + + +
+ + + + +
+ + + + +
+ + - - -
+ + - - ]
6827 : 0 : case ZigTypeIdInvalid:
6828 : 0 : zig_unreachable();
6829 : 24 : case ZigTypeIdMetaType:
6830 : 24 : return 0;
6831 : 57 : case ZigTypeIdVoid:
6832 : 57 : return 1;
6833 : 17 : case ZigTypeIdBool:
6834 : 17 : return 2;
6835 : 16 : case ZigTypeIdUnreachable:
6836 : 16 : return 3;
6837 : 847 : case ZigTypeIdInt:
6838 : 847 : return 4;
6839 : 6336 : case ZigTypeIdFloat:
6840 : 6336 : return 5;
6841 : 549 : case ZigTypeIdPointer:
6842 : 549 : return 6;
6843 : 76 : case ZigTypeIdArray:
6844 : 76 : return 7;
6845 : 1057 : case ZigTypeIdStruct:
6846 [ + + ]: 1057 : if (entry->data.structure.is_slice)
6847 : 949 : return 6;
6848 : 108 : return 8;
6849 : 16 : case ZigTypeIdComptimeFloat:
6850 : 16 : return 9;
6851 : 40 : case ZigTypeIdComptimeInt:
6852 : 40 : return 10;
6853 : 16 : case ZigTypeIdUndefined:
6854 : 16 : return 11;
6855 : 16 : case ZigTypeIdNull:
6856 : 16 : return 12;
6857 : 32 : case ZigTypeIdOptional:
6858 : 32 : return 13;
6859 : 56 : case ZigTypeIdErrorUnion:
6860 : 56 : return 14;
6861 : 64 : case ZigTypeIdErrorSet:
6862 : 64 : return 15;
6863 : 33 : case ZigTypeIdEnum:
6864 : 33 : return 16;
6865 : 64 : case ZigTypeIdUnion:
6866 : 64 : return 17;
6867 : 32 : case ZigTypeIdFn:
6868 : 32 : return 18;
6869 : 16 : case ZigTypeIdBoundFn:
6870 : 16 : return 19;
6871 : 0 : case ZigTypeIdArgTuple:
6872 : 0 : return 20;
6873 : 0 : case ZigTypeIdOpaque:
6874 : 0 : return 21;
6875 : 0 : case ZigTypeIdFnFrame:
6876 : 0 : return 22;
6877 : 32 : case ZigTypeIdAnyFrame:
6878 : 32 : return 23;
6879 : 16 : case ZigTypeIdVector:
6880 : 16 : return 24;
6881 : 0 : case ZigTypeIdEnumLiteral:
6882 : 0 : return 25;
6883 : : }
6884 : 0 : zig_unreachable();
6885 : : }
6886 : :
6887 : 338 : const char *type_id_name(ZigTypeId id) {
6888 [ - + + + : 338 : switch (id) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + - ]
6889 : 0 : case ZigTypeIdInvalid:
6890 : 0 : zig_unreachable();
6891 : 13 : case ZigTypeIdMetaType:
6892 : 13 : return "Type";
6893 : 13 : case ZigTypeIdVoid:
6894 : 13 : return "Void";
6895 : 13 : case ZigTypeIdBool:
6896 : 13 : return "Bool";
6897 : 13 : case ZigTypeIdUnreachable:
6898 : 13 : return "NoReturn";
6899 : 13 : case ZigTypeIdInt:
6900 : 13 : return "Int";
6901 : 13 : case ZigTypeIdFloat:
6902 : 13 : return "Float";
6903 : 13 : case ZigTypeIdPointer:
6904 : 13 : return "Pointer";
6905 : 13 : case ZigTypeIdArray:
6906 : 13 : return "Array";
6907 : 13 : case ZigTypeIdStruct:
6908 : 13 : return "Struct";
6909 : 13 : case ZigTypeIdComptimeFloat:
6910 : 13 : return "ComptimeFloat";
6911 : 13 : case ZigTypeIdComptimeInt:
6912 : 13 : return "ComptimeInt";
6913 : 13 : case ZigTypeIdEnumLiteral:
6914 : 13 : return "EnumLiteral";
6915 : 13 : case ZigTypeIdUndefined:
6916 : 13 : return "Undefined";
6917 : 13 : case ZigTypeIdNull:
6918 : 13 : return "Null";
6919 : 13 : case ZigTypeIdOptional:
6920 : 13 : return "Optional";
6921 : 13 : case ZigTypeIdErrorUnion:
6922 : 13 : return "ErrorUnion";
6923 : 13 : case ZigTypeIdErrorSet:
6924 : 13 : return "ErrorSet";
6925 : 13 : case ZigTypeIdEnum:
6926 : 13 : return "Enum";
6927 : 13 : case ZigTypeIdUnion:
6928 : 13 : return "Union";
6929 : 13 : case ZigTypeIdFn:
6930 : 13 : return "Fn";
6931 : 13 : case ZigTypeIdBoundFn:
6932 : 13 : return "BoundFn";
6933 : 13 : case ZigTypeIdArgTuple:
6934 : 13 : return "ArgTuple";
6935 : 13 : case ZigTypeIdOpaque:
6936 : 13 : return "Opaque";
6937 : 13 : case ZigTypeIdVector:
6938 : 13 : return "Vector";
6939 : 13 : case ZigTypeIdFnFrame:
6940 : 13 : return "Frame";
6941 : 13 : case ZigTypeIdAnyFrame:
6942 : 13 : return "AnyFrame";
6943 : : }
6944 : 0 : zig_unreachable();
6945 : : }
6946 : :
6947 : 18 : LinkLib *create_link_lib(Buf *name) {
6948 : 18 : LinkLib *link_lib = allocate<LinkLib>(1);
6949 : 18 : link_lib->name = name;
6950 : 18 : return link_lib;
6951 : : }
6952 : :
6953 : 138 : LinkLib *add_link_lib(CodeGen *g, Buf *name) {
6954 : 138 : bool is_libc = buf_eql_str(name, "c");
6955 : :
6956 [ + + ][ + + ]: 138 : if (is_libc && g->libc_link_lib != nullptr)
6957 : 52 : return g->libc_link_lib;
6958 : :
6959 [ + + ]: 88 : for (size_t i = 0; i < g->link_libs_list.length; i += 1) {
6960 : 76 : LinkLib *existing_lib = g->link_libs_list.at(i);
6961 [ + + ]: 76 : if (buf_eql_buf(existing_lib->name, name)) {
6962 : 74 : return existing_lib;
6963 : : }
6964 : : }
6965 : :
6966 : 12 : LinkLib *link_lib = create_link_lib(name);
6967 : 12 : g->link_libs_list.append(link_lib);
6968 : :
6969 [ + + ]: 12 : if (is_libc)
6970 : 8 : g->libc_link_lib = link_lib;
6971 : :
6972 : 12 : return link_lib;
6973 : : }
6974 : :
6975 : 2931 : ZigType *get_align_amt_type(CodeGen *g) {
6976 [ + + ]: 2931 : if (g->align_amt_type == nullptr) {
6977 : : // according to LLVM the maximum alignment is 1 << 29.
6978 : 13 : g->align_amt_type = get_int_type(g, false, 29);
6979 : : }
6980 : 2931 : return g->align_amt_type;
6981 : : }
6982 : :
6983 : 5128 : uint32_t type_ptr_hash(const ZigType *ptr) {
6984 : 5128 : return hash_ptr((void*)ptr);
6985 : : }
6986 : :
6987 : 25597 : bool type_ptr_eql(const ZigType *a, const ZigType *b) {
6988 : 25597 : return a == b;
6989 : : }
6990 : :
6991 : 15374 : ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name) {
6992 : 15374 : Tld *tld = get_container_scope(codegen->compile_var_import)->decl_table.get(buf_create_from_str(name));
6993 : 15374 : resolve_top_level_decl(codegen, tld, nullptr, false);
6994 : 15374 : assert(tld->id == TldIdVar);
6995 : 15374 : TldVar *tld_var = (TldVar *)tld;
6996 : 15374 : ConstExprValue *var_value = tld_var->var->const_value;
6997 : 15374 : assert(var_value != nullptr);
6998 : 15374 : return var_value;
6999 : : }
7000 : :
7001 : 27030 : bool type_is_global_error_set(ZigType *err_set_type) {
7002 : 27030 : assert(err_set_type->id == ZigTypeIdErrorSet);
7003 : 27030 : assert(err_set_type->data.error_set.infer_fn == nullptr);
7004 : 27030 : return err_set_type->data.error_set.err_count == UINT32_MAX;
7005 : : }
7006 : :
7007 : 103445 : bool type_can_fail(ZigType *type_entry) {
7008 [ + + ][ + + ]: 103445 : return type_entry->id == ZigTypeIdErrorUnion || type_entry->id == ZigTypeIdErrorSet;
7009 : : }
7010 : :
7011 : 102453 : bool fn_type_can_fail(FnTypeId *fn_type_id) {
7012 : 102453 : return type_can_fail(fn_type_id->return_type);
7013 : : }
7014 : :
7015 : : // ErrorNone - result pointer has the type
7016 : : // ErrorOverflow - an integer primitive type has too large a bit width
7017 : : // ErrorPrimitiveTypeNotFound - result pointer unchanged
7018 : 1675582 : Error get_primitive_type(CodeGen *g, Buf *name, ZigType **result) {
7019 [ + + ]: 1675582 : if (buf_len(name) >= 2) {
7020 : 1237764 : uint8_t first_c = buf_ptr(name)[0];
7021 [ + + ][ + + ]: 1237764 : if (first_c == 'i' || first_c == 'u') {
7022 [ + + ]: 314565 : for (size_t i = 1; i < buf_len(name); i += 1) {
7023 : 222983 : uint8_t c = buf_ptr(name)[i];
7024 [ + + ][ - + ]: 222983 : if (c < '0' || c > '9') {
7025 : : goto not_integer;
7026 : : }
7027 : : }
7028 : 91582 : bool is_signed = (first_c == 'i');
7029 : 91582 : unsigned long int bit_count = strtoul(buf_ptr(name) + 1, nullptr, 10);
7030 : : // strtoul returns ULONG_MAX on errors, so this comparison catches that as well.
7031 [ - + ]: 91582 : if (bit_count >= 65536) return ErrorOverflow;
7032 : 91582 : *result = get_int_type(g, is_signed, bit_count);
7033 : 1171385 : return ErrorNone;
7034 : : }
7035 : : }
7036 : :
7037 : 504197 : not_integer:
7038 : :
7039 : 1584000 : auto primitive_table_entry = g->primitive_type_table.maybe_get(name);
7040 [ + + ]: 1584000 : if (primitive_table_entry == nullptr)
7041 : 1400587 : return ErrorPrimitiveTypeNotFound;
7042 : :
7043 : 183413 : *result = primitive_table_entry->value;
7044 : 183413 : return ErrorNone;
7045 : : }
7046 : :
7047 : 1763 : Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents) {
7048 [ + - ]: 1763 : if (g->enable_cache) {
7049 : 1763 : return cache_add_file_fetch(&g->cache_hash, resolved_path, contents);
7050 : : } else {
7051 : 0 : return os_fetch_file_path(resolved_path, contents);
7052 : : }
7053 : : }
7054 : :
7055 : 31 : static X64CABIClass type_windows_abi_x86_64_class(CodeGen *g, ZigType *ty, size_t ty_size) {
7056 : : // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017
7057 [ - + + - ]: 31 : switch (ty->id) {
7058 : 0 : case ZigTypeIdEnum:
7059 : : case ZigTypeIdInt:
7060 : : case ZigTypeIdBool:
7061 : 0 : return X64CABIClass_INTEGER;
7062 : 21 : case ZigTypeIdFloat:
7063 : : case ZigTypeIdVector:
7064 : 21 : return X64CABIClass_SSE;
7065 : 10 : case ZigTypeIdStruct:
7066 : : case ZigTypeIdUnion: {
7067 [ + - ]: 10 : if (ty_size <= 8)
7068 : 10 : return X64CABIClass_INTEGER;
7069 : 0 : return X64CABIClass_MEMORY;
7070 : : }
7071 : 0 : default:
7072 : 0 : return X64CABIClass_Unknown;
7073 : : }
7074 : : }
7075 : :
7076 : 60 : static X64CABIClass type_system_V_abi_x86_64_class(CodeGen *g, ZigType *ty, size_t ty_size) {
7077 [ + - + - : 60 : switch (ty->id) {
- ]
7078 : 30 : case ZigTypeIdEnum:
7079 : : case ZigTypeIdInt:
7080 : : case ZigTypeIdBool:
7081 : 30 : return X64CABIClass_INTEGER;
7082 : 0 : case ZigTypeIdFloat:
7083 : : case ZigTypeIdVector:
7084 : 0 : return X64CABIClass_SSE;
7085 : 30 : case ZigTypeIdStruct: {
7086 : : // "If the size of an object is larger than four eightbytes, or it contains unaligned
7087 : : // fields, it has class MEMORY"
7088 [ - + ]: 30 : if (ty_size > 32)
7089 : 0 : return X64CABIClass_MEMORY;
7090 [ - + ]: 30 : if (ty->data.structure.layout != ContainerLayoutExtern) {
7091 : : // TODO determine whether packed structs have any unaligned fields
7092 : 0 : return X64CABIClass_Unknown;
7093 : : }
7094 : : // "If the size of the aggregate exceeds two eightbytes and the first eight-
7095 : : // byte isn’t SSE or any other eightbyte isn’t SSEUP, the whole argument
7096 : : // is passed in memory."
7097 [ - + ]: 30 : if (ty_size > 16) {
7098 : : // Zig doesn't support vectors and large fp registers yet, so this will always
7099 : : // be memory.
7100 : 0 : return X64CABIClass_MEMORY;
7101 : : }
7102 : 30 : X64CABIClass working_class = X64CABIClass_Unknown;
7103 [ + + ]: 60 : for (uint32_t i = 0; i < ty->data.structure.src_field_count; i += 1) {
7104 : 30 : X64CABIClass field_class = type_c_abi_x86_64_class(g, ty->data.structure.fields->type_entry);
7105 [ - + ]: 30 : if (field_class == X64CABIClass_Unknown)
7106 : 0 : return X64CABIClass_Unknown;
7107 [ - + ][ # # ]: 30 : if (i == 0 || field_class == X64CABIClass_MEMORY || working_class == X64CABIClass_SSE) {
[ # # ]
7108 : 30 : working_class = field_class;
7109 : : }
7110 : : }
7111 : 30 : return working_class;
7112 : : }
7113 : 0 : case ZigTypeIdUnion: {
7114 : : // "If the size of an object is larger than four eightbytes, or it contains unaligned
7115 : : // fields, it has class MEMORY"
7116 [ # # ]: 0 : if (ty_size > 32)
7117 : 0 : return X64CABIClass_MEMORY;
7118 [ # # ]: 0 : if (ty->data.unionation.layout != ContainerLayoutExtern)
7119 : 0 : return X64CABIClass_MEMORY;
7120 : : // "If the size of the aggregate exceeds two eightbytes and the first eight-
7121 : : // byte isn’t SSE or any other eightbyte isn’t SSEUP, the whole argument
7122 : : // is passed in memory."
7123 [ # # ]: 0 : if (ty_size > 16) {
7124 : : // Zig doesn't support vectors and large fp registers yet, so this will always
7125 : : // be memory.
7126 : 0 : return X64CABIClass_MEMORY;
7127 : : }
7128 : 0 : X64CABIClass working_class = X64CABIClass_Unknown;
7129 [ # # ]: 0 : for (uint32_t i = 0; i < ty->data.unionation.src_field_count; i += 1) {
7130 : 0 : X64CABIClass field_class = type_c_abi_x86_64_class(g, ty->data.unionation.fields->type_entry);
7131 [ # # ]: 0 : if (field_class == X64CABIClass_Unknown)
7132 : 0 : return X64CABIClass_Unknown;
7133 [ # # ][ # # ]: 0 : if (i == 0 || field_class == X64CABIClass_MEMORY || working_class == X64CABIClass_SSE) {
[ # # ]
7134 : 0 : working_class = field_class;
7135 : : }
7136 : : }
7137 : 0 : return working_class;
7138 : : }
7139 : 0 : default:
7140 : 0 : return X64CABIClass_Unknown;
7141 : : }
7142 : : }
7143 : :
7144 : 91 : X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) {
7145 : 91 : const size_t ty_size = type_size(g, ty);
7146 [ - + ]: 91 : if (get_codegen_ptr_type(ty) != nullptr)
7147 : 0 : return X64CABIClass_INTEGER;
7148 : :
7149 [ + + ][ - + ]: 91 : if (g->zig_target->os == OsWindows || g->zig_target->os == OsUefi) {
7150 : 31 : return type_windows_abi_x86_64_class(g, ty, ty_size);
7151 : : } else {
7152 : 60 : return type_system_V_abi_x86_64_class(g, ty, ty_size);
7153 : : }
7154 : : }
7155 : :
7156 : : // NOTE this does not depend on x86_64
7157 : 12943 : bool type_is_c_abi_int(CodeGen *g, ZigType *ty) {
7158 [ + + ]: 10197 : return (ty->id == ZigTypeIdInt ||
7159 [ + - ]: 7881 : ty->id == ZigTypeIdFloat ||
7160 [ + + ]: 7881 : ty->id == ZigTypeIdBool ||
7161 [ + + ]: 7841 : ty->id == ZigTypeIdEnum ||
7162 [ + + ]: 795 : ty->id == ZigTypeIdVoid ||
7163 [ + + + + ]: 23140 : ty->id == ZigTypeIdUnreachable ||
7164 : 13718 : get_codegen_ptr_type(ty) != nullptr);
7165 : : }
7166 : :
7167 : 63118 : uint32_t get_host_int_bytes(CodeGen *g, ZigType *struct_type, TypeStructField *field) {
7168 : 63118 : assert(struct_type->id == ZigTypeIdStruct);
7169 : 63118 : assert(type_is_resolved(struct_type, ResolveStatusSizeKnown));
7170 [ + + ]: 63118 : if (struct_type->data.structure.host_int_bytes == nullptr)
7171 : 61620 : return 0;
7172 : 1498 : return struct_type->data.structure.host_int_bytes[field->gen_index];
7173 : : }
7174 : :
7175 : 65737 : Error ensure_const_val_repr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node,
7176 : : ConstExprValue *const_val, ZigType *wanted_type)
7177 : : {
7178 : 65737 : ConstExprValue ptr_val = {};
7179 : 65737 : ptr_val.special = ConstValSpecialStatic;
7180 : 65737 : ptr_val.type = get_pointer_to_type(codegen, wanted_type, true);
7181 : 65737 : ptr_val.data.x_ptr.mut = ConstPtrMutComptimeConst;
7182 : 65737 : ptr_val.data.x_ptr.special = ConstPtrSpecialRef;
7183 : 65737 : ptr_val.data.x_ptr.data.ref.pointee = const_val;
7184 [ - + ]: 65737 : if (const_ptr_pointee(ira, codegen, &ptr_val, source_node) == nullptr)
7185 : 0 : return ErrorSemanticAnalyzeFail;
7186 : :
7187 : 65737 : return ErrorNone;
7188 : : }
7189 : :
7190 : 5608 : const char *container_string(ContainerKind kind) {
7191 [ + + + - ]: 5608 : switch (kind) {
7192 : 1109 : case ContainerKindEnum: return "enum";
7193 : 3922 : case ContainerKindStruct: return "struct";
7194 : 577 : case ContainerKindUnion: return "union";
7195 : : }
7196 : 0 : zig_unreachable();
7197 : : }
7198 : :
7199 : 1740012 : bool ptr_allows_addr_zero(ZigType *ptr_type) {
7200 [ + + ]: 1740012 : if (ptr_type->id == ZigTypeIdPointer) {
7201 : 32862 : return ptr_type->data.pointer.allow_zero;
7202 [ + + ]: 1707150 : } else if (ptr_type->id == ZigTypeIdOptional) {
7203 : 4736 : return true;
7204 : : }
7205 : 1702414 : return false;
7206 : : }
7207 : :
7208 : 120 : Buf *type_bare_name(ZigType *type_entry) {
7209 [ + + ]: 120 : if (is_slice(type_entry)) {
7210 : 8 : return &type_entry->name;
7211 [ + + ]: 112 : } else if (is_container(type_entry)) {
7212 : 48 : return get_container_scope(type_entry)->bare_name;
7213 [ + + ]: 64 : } else if (type_entry->id == ZigTypeIdOpaque) {
7214 : 16 : return type_entry->data.opaque.bare_name;
7215 : : } else {
7216 : 48 : return &type_entry->name;
7217 : : }
7218 : : }
7219 : :
7220 : : // TODO this will have to be more clever, probably using the full name
7221 : : // and replacing '.' with '_' or something like that
7222 : 0 : Buf *type_h_name(ZigType *t) {
7223 : 0 : return type_bare_name(t);
7224 : : }
7225 : :
7226 : 96996 : static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
7227 [ + + ]: 97422 : if (type->data.structure.resolve_status >= wanted_resolve_status) return;
7228 : :
7229 : 833 : ZigType *ptr_type = type->data.structure.fields[slice_ptr_index].type_entry;
7230 : 833 : ZigType *child_type = ptr_type->data.pointer.child_type;
7231 : 833 : ZigType *usize_type = g->builtin_types.entry_usize;
7232 : :
7233 : 833 : bool done = false;
7234 [ + + ][ + + ]: 833 : if (ptr_type->data.pointer.is_const || ptr_type->data.pointer.is_volatile ||
[ + + ]
7235 [ + + ]: 539 : ptr_type->data.pointer.explicit_alignment != 0 || ptr_type->data.pointer.allow_zero)
7236 : : {
7237 : : ZigType *peer_ptr_type = get_pointer_to_type_extra(g, child_type, false, false,
7238 : 310 : PtrLenUnknown, 0, 0, 0, false);
7239 : 310 : ZigType *peer_slice_type = get_slice_type(g, peer_ptr_type);
7240 : :
7241 : 310 : assertNoError(type_resolve(g, peer_slice_type, wanted_resolve_status));
7242 : 310 : type->llvm_type = peer_slice_type->llvm_type;
7243 : 310 : type->llvm_di_type = peer_slice_type->llvm_di_type;
7244 : 310 : type->data.structure.resolve_status = peer_slice_type->data.structure.resolve_status;
7245 : 310 : done = true;
7246 : : }
7247 : :
7248 : : // If the child type is []const T then we need to make sure the type ref
7249 : : // and debug info is the same as if the child type were []T.
7250 [ + + ]: 833 : if (is_slice(child_type)) {
7251 : 101 : ZigType *child_ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry;
7252 : 101 : assert(child_ptr_type->id == ZigTypeIdPointer);
7253 [ + - ][ + - ]: 101 : if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile ||
[ + + ]
7254 [ - + ]: 37 : child_ptr_type->data.pointer.explicit_alignment != 0 || child_ptr_type->data.pointer.allow_zero)
7255 : : {
7256 : 64 : ZigType *grand_child_type = child_ptr_type->data.pointer.child_type;
7257 : : ZigType *bland_child_ptr_type = get_pointer_to_type_extra(g, grand_child_type, false, false,
7258 : 64 : PtrLenUnknown, 0, 0, 0, false);
7259 : 64 : ZigType *bland_child_slice = get_slice_type(g, bland_child_ptr_type);
7260 : : ZigType *peer_ptr_type = get_pointer_to_type_extra(g, bland_child_slice, false, false,
7261 : 64 : PtrLenUnknown, 0, 0, 0, false);
7262 : 64 : ZigType *peer_slice_type = get_slice_type(g, peer_ptr_type);
7263 : :
7264 : 64 : assertNoError(type_resolve(g, peer_slice_type, wanted_resolve_status));
7265 : 64 : type->llvm_type = peer_slice_type->llvm_type;
7266 : 64 : type->llvm_di_type = peer_slice_type->llvm_di_type;
7267 : 64 : type->data.structure.resolve_status = peer_slice_type->data.structure.resolve_status;
7268 : 101 : done = true;
7269 : : }
7270 : : }
7271 : :
7272 [ + + ]: 833 : if (done) return;
7273 : :
7274 : 491 : LLVMTypeRef usize_llvm_type = get_llvm_type(g, usize_type);
7275 : 491 : ZigLLVMDIType *usize_llvm_di_type = get_llvm_di_type(g, usize_type);
7276 : 491 : ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
7277 : 491 : ZigLLVMDIFile *di_file = nullptr;
7278 : 491 : unsigned line = 0;
7279 : :
7280 [ + + ]: 491 : if (type->data.structure.resolve_status < ResolveStatusLLVMFwdDecl) {
7281 : 423 : type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&type->name));
7282 : :
7283 : 423 : type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
7284 : 423 : ZigLLVMTag_DW_structure_type(), buf_ptr(&type->name),
7285 : : compile_unit_scope, di_file, line);
7286 : :
7287 : 423 : type->data.structure.resolve_status = ResolveStatusLLVMFwdDecl;
7288 [ + + ]: 423 : if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;
7289 : : }
7290 : :
7291 [ + + ]: 455 : if (!type_has_bits(child_type)) {
7292 : : LLVMTypeRef element_types[] = {
7293 : : usize_llvm_type,
7294 : 16 : };
7295 : 16 : LLVMStructSetBody(type->llvm_type, element_types, 1, false);
7296 : :
7297 : 16 : uint64_t len_debug_size_in_bits = usize_type->size_in_bits;
7298 : 16 : uint64_t len_debug_align_in_bits = 8*usize_type->abi_align;
7299 : 16 : uint64_t len_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, type->llvm_type, 0);
7300 : :
7301 : 16 : uint64_t debug_size_in_bits = type->size_in_bits;
7302 : 16 : uint64_t debug_align_in_bits = 8*type->abi_align;
7303 : :
7304 : : ZigLLVMDIType *di_element_types[] = {
7305 : 16 : ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),
7306 : : "len", di_file, line,
7307 : : len_debug_size_in_bits,
7308 : : len_debug_align_in_bits,
7309 : : len_offset_in_bits,
7310 : : ZigLLVM_DIFlags_Zero,
7311 : : usize_llvm_di_type),
7312 : 16 : };
7313 : 16 : ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
7314 : : compile_unit_scope,
7315 : 16 : buf_ptr(&type->name),
7316 : : di_file, line, debug_size_in_bits, debug_align_in_bits,
7317 : : ZigLLVM_DIFlags_Zero,
7318 : 16 : nullptr, di_element_types, 1, 0, nullptr, "");
7319 : :
7320 : 16 : ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);
7321 : 16 : type->llvm_di_type = replacement_di_type;
7322 : 16 : type->data.structure.resolve_status = ResolveStatusLLVMFull;
7323 : 16 : return;
7324 : : }
7325 : :
7326 : : LLVMTypeRef element_types[2];
7327 : 439 : element_types[slice_ptr_index] = get_llvm_type(g, ptr_type);
7328 : 439 : element_types[slice_len_index] = get_llvm_type(g, g->builtin_types.entry_usize);
7329 [ + + ]: 439 : if (type->data.structure.resolve_status >= wanted_resolve_status) return;
7330 : 407 : LLVMStructSetBody(type->llvm_type, element_types, 2, false);
7331 : :
7332 : 407 : uint64_t ptr_debug_size_in_bits = ptr_type->size_in_bits;
7333 : 407 : uint64_t ptr_debug_align_in_bits = 8*ptr_type->abi_align;
7334 : 407 : uint64_t ptr_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, type->llvm_type, 0);
7335 : :
7336 : 407 : uint64_t len_debug_size_in_bits = usize_type->size_in_bits;
7337 : 407 : uint64_t len_debug_align_in_bits = 8*usize_type->abi_align;
7338 : 407 : uint64_t len_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, type->llvm_type, 1);
7339 : :
7340 : 407 : uint64_t debug_size_in_bits = type->size_in_bits;
7341 : 407 : uint64_t debug_align_in_bits = 8*type->abi_align;
7342 : :
7343 : : ZigLLVMDIType *di_element_types[] = {
7344 : 407 : ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),
7345 : : "ptr", di_file, line,
7346 : : ptr_debug_size_in_bits,
7347 : : ptr_debug_align_in_bits,
7348 : : ptr_offset_in_bits,
7349 : : ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, ptr_type)),
7350 : 407 : ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),
7351 : : "len", di_file, line,
7352 : : len_debug_size_in_bits,
7353 : : len_debug_align_in_bits,
7354 : : len_offset_in_bits,
7355 : : ZigLLVM_DIFlags_Zero, usize_llvm_di_type),
7356 : 814 : };
7357 : 407 : ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
7358 : : compile_unit_scope,
7359 : 407 : buf_ptr(&type->name),
7360 : : di_file, line, debug_size_in_bits, debug_align_in_bits,
7361 : : ZigLLVM_DIFlags_Zero,
7362 : 407 : nullptr, di_element_types, 2, 0, nullptr, "");
7363 : :
7364 : 407 : ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);
7365 : 407 : type->llvm_di_type = replacement_di_type;
7366 : 407 : type->data.structure.resolve_status = ResolveStatusLLVMFull;
7367 : : }
7368 : :
7369 : 91936 : static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveStatus wanted_resolve_status,
7370 : : ZigType *async_frame_type)
7371 : : {
7372 : 91936 : assert(struct_type->id == ZigTypeIdStruct);
7373 : 91936 : assert(struct_type->data.structure.resolve_status != ResolveStatusInvalid);
7374 : 91936 : assert(struct_type->data.structure.resolve_status >= ResolveStatusSizeKnown);
7375 [ + - ][ + + ]: 91936 : assert(struct_type->data.structure.fields || struct_type->data.structure.src_field_count == 0);
7376 [ + + ]: 91936 : if (struct_type->data.structure.resolve_status >= wanted_resolve_status) return;
7377 : :
7378 : 4718 : AstNode *decl_node = struct_type->data.structure.decl_node;
7379 : : ZigLLVMDIFile *di_file;
7380 : : ZigLLVMDIScope *di_scope;
7381 : : unsigned line;
7382 [ + + ]: 4718 : if (decl_node != nullptr) {
7383 : 3574 : assert(decl_node->type == NodeTypeContainerDecl);
7384 : 3574 : Scope *scope = &struct_type->data.structure.decls_scope->base;
7385 : 3574 : ZigType *import = get_scope_import(scope);
7386 : 3574 : di_file = import->data.structure.root_struct->di_file;
7387 : 3574 : di_scope = ZigLLVMFileToScope(di_file);
7388 : 3574 : line = decl_node->line + 1;
7389 : : } else {
7390 : 1144 : di_file = nullptr;
7391 : 1144 : di_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
7392 : 1144 : line = 0;
7393 : : }
7394 : :
7395 [ + + ]: 4718 : if (struct_type->data.structure.resolve_status < ResolveStatusLLVMFwdDecl) {
7396 [ + + ]: 6931 : struct_type->llvm_type = type_has_bits(struct_type) ?
7397 : 2989 : LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&struct_type->name)) : LLVMVoidType();
7398 : 3942 : unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();
7399 : 3942 : struct_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
7400 : 3942 : dwarf_kind, buf_ptr(&struct_type->name),
7401 : : di_scope, di_file, line);
7402 : :
7403 : 3942 : struct_type->data.structure.resolve_status = ResolveStatusLLVMFwdDecl;
7404 [ + + ]: 3942 : if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) {
7405 : 584 : struct_type->data.structure.llvm_full_type_queue_index = g->type_resolve_stack.length;
7406 : 584 : g->type_resolve_stack.append(struct_type);
7407 : 584 : return;
7408 : : } else {
7409 : 3358 : struct_type->data.structure.llvm_full_type_queue_index = SIZE_MAX;
7410 : : }
7411 : : }
7412 : :
7413 : 4134 : size_t field_count = struct_type->data.structure.src_field_count;
7414 : : // Every field could potentially have a generated padding field after it.
7415 : 4134 : LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count * 2);
7416 : :
7417 : 4134 : bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked);
7418 : 4134 : size_t packed_bits_offset = 0;
7419 : 4134 : size_t first_packed_bits_offset_misalign = SIZE_MAX;
7420 : 4134 : size_t debug_field_count = 0;
7421 : :
7422 : : // trigger all the recursive get_llvm_type calls
7423 [ + + ]: 20481 : for (size_t i = 0; i < field_count; i += 1) {
7424 : 16539 : TypeStructField *field = &struct_type->data.structure.fields[i];
7425 : 16539 : ZigType *field_type = field->type_entry;
7426 [ + + ]: 16539 : if (!type_has_bits(field_type))
7427 : 1451 : continue;
7428 : 15088 : (void)get_llvm_type(g, field_type);
7429 [ + + ]: 15088 : if (struct_type->data.structure.resolve_status >= wanted_resolve_status) return;
7430 : : }
7431 : :
7432 : 3942 : size_t gen_field_index = 0;
7433 : :
7434 : : // Calculate what LLVM thinks the ABI align of the struct will be. We do this to avoid
7435 : : // inserting padding bytes where LLVM would do it automatically.
7436 : 3942 : size_t llvm_struct_abi_align = 0;
7437 [ + + ]: 19872 : for (size_t i = 0; i < field_count; i += 1) {
7438 : 15930 : ZigType *field_type = struct_type->data.structure.fields[i].type_entry;
7439 [ + + ]: 15930 : if (!type_has_bits(field_type))
7440 : 1379 : continue;
7441 : 14551 : LLVMTypeRef field_llvm_type = get_llvm_type(g, field_type);
7442 : 14551 : size_t llvm_field_abi_align = LLVMABIAlignmentOfType(g->target_data_ref, field_llvm_type);
7443 : 14551 : llvm_struct_abi_align = max(llvm_struct_abi_align, llvm_field_abi_align);
7444 : : }
7445 : :
7446 [ + + ]: 19872 : for (size_t i = 0; i < field_count; i += 1) {
7447 : 15930 : TypeStructField *field = &struct_type->data.structure.fields[i];
7448 : 15930 : ZigType *field_type = field->type_entry;
7449 : :
7450 [ + + ]: 15930 : if (!type_has_bits(field_type)) {
7451 : 1379 : field->gen_index = SIZE_MAX;
7452 : 1379 : continue;
7453 : : }
7454 : :
7455 [ + + ]: 14551 : if (packed) {
7456 : 692 : size_t field_size_in_bits = type_size_bits(g, field_type);
7457 : 692 : size_t next_packed_bits_offset = packed_bits_offset + field_size_in_bits;
7458 : :
7459 [ + + ]: 692 : if (first_packed_bits_offset_misalign != SIZE_MAX) {
7460 : : // this field is not byte-aligned; it is part of the previous field with a bit offset
7461 : :
7462 : 184 : size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign;
7463 : 184 : size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes);
7464 [ + + ]: 184 : if (full_abi_size * 8 == full_bit_count) {
7465 : : // next field recovers ABI alignment
7466 : 104 : element_types[gen_field_index] = LLVMIntType((unsigned)(full_bit_count));
7467 : 104 : gen_field_index += 1;
7468 : :
7469 : 184 : first_packed_bits_offset_misalign = SIZE_MAX;
7470 : : }
7471 [ + + ]: 508 : } else if (get_abi_size_bytes(field_type->size_in_bits, g->pointer_size_bytes) * 8 != field_size_in_bits) {
7472 : 144 : first_packed_bits_offset_misalign = packed_bits_offset;
7473 : : } else {
7474 : : // This is a byte-aligned field (both start and end) in a packed struct.
7475 : 364 : element_types[gen_field_index] = get_llvm_type(g, field_type);
7476 : 364 : gen_field_index += 1;
7477 : : }
7478 : 692 : packed_bits_offset = next_packed_bits_offset;
7479 : : } else {
7480 : : LLVMTypeRef llvm_type;
7481 [ + + ][ + + ]: 13859 : if (i == 0 && async_frame_type != nullptr) {
7482 : 824 : assert(async_frame_type->id == ZigTypeIdFnFrame);
7483 : 824 : assert(field_type->id == ZigTypeIdFn);
7484 : 824 : resolve_llvm_types_fn(g, async_frame_type->data.frame.fn);
7485 : 824 : llvm_type = LLVMPointerType(async_frame_type->data.frame.fn->raw_type_ref, 0);
7486 : : } else {
7487 : 13035 : llvm_type = get_llvm_type(g, field_type);
7488 : : }
7489 : 13859 : element_types[gen_field_index] = llvm_type;
7490 : 13859 : field->gen_index = gen_field_index;
7491 : 13859 : gen_field_index += 1;
7492 : :
7493 : : // find the next non-zero-byte field for offset calculations
7494 : 13859 : size_t next_src_field_index = i + 1;
7495 [ + + ]: 15198 : for (; next_src_field_index < field_count; next_src_field_index += 1) {
7496 [ + + ]: 12462 : if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry))
7497 : 11123 : break;
7498 : : }
7499 : : size_t next_abi_align;
7500 [ + + ]: 13859 : if (next_src_field_index == field_count) {
7501 : 2736 : next_abi_align = struct_type->abi_align;
7502 : : } else {
7503 [ + + ]: 11123 : if (struct_type->data.structure.fields[next_src_field_index].align == 0) {
7504 : 8704 : next_abi_align = struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align;
7505 : : } else {
7506 : 2419 : next_abi_align = struct_type->data.structure.fields[next_src_field_index].align;
7507 : : }
7508 : : }
7509 [ + + ]: 24982 : size_t llvm_next_abi_align = (next_src_field_index == field_count) ?
7510 : : llvm_struct_abi_align :
7511 : 11123 : LLVMABIAlignmentOfType(g->target_data_ref,
7512 : 24982 : get_llvm_type(g, struct_type->data.structure.fields[next_src_field_index].type_entry));
7513 : :
7514 : 13859 : size_t next_offset = next_field_offset(field->offset, struct_type->abi_align,
7515 : 13859 : field_type->abi_size, next_abi_align);
7516 : 13859 : size_t llvm_next_offset = next_field_offset(field->offset, llvm_struct_abi_align,
7517 : 13859 : LLVMABISizeOfType(g->target_data_ref, llvm_type), llvm_next_abi_align);
7518 : :
7519 : 13859 : assert(next_offset >= llvm_next_offset);
7520 [ + + ]: 13859 : if (next_offset > llvm_next_offset) {
7521 : 848 : size_t pad_bytes = next_offset - (field->offset + field_type->abi_size);
7522 [ + - ]: 848 : if (pad_bytes != 0) {
7523 : 848 : LLVMTypeRef pad_llvm_type = LLVMArrayType(LLVMInt8Type(), pad_bytes);
7524 : 848 : element_types[gen_field_index] = pad_llvm_type;
7525 : 848 : gen_field_index += 1;
7526 : : }
7527 : : }
7528 : : }
7529 : 14551 : debug_field_count += 1;
7530 : : }
7531 [ + + ]: 3942 : if (!packed) {
7532 : 3689 : struct_type->data.structure.gen_field_count = gen_field_index;
7533 : : }
7534 : :
7535 [ + + ]: 3942 : if (first_packed_bits_offset_misalign != SIZE_MAX) {
7536 : 40 : size_t full_bit_count = packed_bits_offset - first_packed_bits_offset_misalign;
7537 : 40 : size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes);
7538 : 40 : element_types[gen_field_index] = LLVMIntType((unsigned)full_abi_size * 8);
7539 : 40 : gen_field_index += 1;
7540 : : }
7541 : :
7542 [ + + ]: 3942 : if (type_has_bits(struct_type)) {
7543 : 2989 : LLVMStructSetBody(struct_type->llvm_type, element_types,
7544 : 2989 : (unsigned)struct_type->data.structure.gen_field_count, packed);
7545 : : }
7546 : :
7547 : 3942 : ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(debug_field_count);
7548 : 3942 : size_t debug_field_index = 0;
7549 [ + + ]: 19872 : for (size_t i = 0; i < field_count; i += 1) {
7550 : 15930 : TypeStructField *field = &struct_type->data.structure.fields[i];
7551 : 15930 : size_t gen_field_index = field->gen_index;
7552 [ + + ]: 15930 : if (gen_field_index == SIZE_MAX) {
7553 : 1379 : continue;
7554 : : }
7555 : :
7556 : 14551 : ZigType *field_type = field->type_entry;
7557 : :
7558 : : // if the field is a function, actually the debug info should be a pointer.
7559 : : ZigLLVMDIType *field_di_type;
7560 [ + + ]: 14551 : if (field_type->id == ZigTypeIdFn) {
7561 : 1051 : ZigType *field_ptr_type = get_pointer_to_type(g, field_type, true);
7562 : 1051 : uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, get_llvm_type(g, field_ptr_type));
7563 : 1051 : uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, get_llvm_type(g, field_ptr_type));
7564 : 1051 : field_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, get_llvm_di_type(g, field_type),
7565 : 1051 : debug_size_in_bits, debug_align_in_bits, buf_ptr(&field_ptr_type->name));
7566 : : } else {
7567 : 13500 : field_di_type = get_llvm_di_type(g, field_type);
7568 : : }
7569 : :
7570 : : uint64_t debug_size_in_bits;
7571 : : uint64_t debug_align_in_bits;
7572 : : uint64_t debug_offset_in_bits;
7573 [ + + ]: 14551 : if (packed) {
7574 : 692 : debug_size_in_bits = field->type_entry->size_in_bits;
7575 : 692 : debug_align_in_bits = 8 * field->type_entry->abi_align;
7576 : 692 : debug_offset_in_bits = 8 * field->offset + field->bit_offset_in_host;
7577 : : } else {
7578 : 13859 : debug_size_in_bits = 8 * get_store_size_bytes(field_type->size_in_bits);
7579 : 13859 : debug_align_in_bits = 8 * field_type->abi_align;
7580 : 13859 : debug_offset_in_bits = 8 * field->offset;
7581 : : }
7582 : : unsigned line;
7583 [ + + ]: 14551 : if (decl_node != nullptr) {
7584 : 4815 : AstNode *field_node = decl_node->data.container_decl.fields.at(i);
7585 : 4815 : line = field_node->line + 1;
7586 : : } else {
7587 : 9736 : line = 0;
7588 : : }
7589 : 14551 : di_element_types[debug_field_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
7590 : 14551 : ZigLLVMTypeToScope(struct_type->llvm_di_type), buf_ptr(field->name),
7591 : : di_file, line,
7592 : : debug_size_in_bits,
7593 : : debug_align_in_bits,
7594 : : debug_offset_in_bits,
7595 : : ZigLLVM_DIFlags_Zero, field_di_type);
7596 : 14551 : assert(di_element_types[debug_field_index]);
7597 : 14551 : debug_field_index += 1;
7598 : : }
7599 : :
7600 : 3942 : uint64_t debug_size_in_bits = 8*get_store_size_bytes(struct_type->size_in_bits);
7601 : 3942 : uint64_t debug_align_in_bits = 8*struct_type->abi_align;
7602 : 7884 : ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
7603 : : di_scope,
7604 : 3942 : buf_ptr(&struct_type->name),
7605 : : di_file, line,
7606 : : debug_size_in_bits,
7607 : : debug_align_in_bits,
7608 : : ZigLLVM_DIFlags_Zero,
7609 : 3942 : nullptr, di_element_types, (int)debug_field_count, 0, nullptr, "");
7610 : :
7611 : 3942 : ZigLLVMReplaceTemporary(g->dbuilder, struct_type->llvm_di_type, replacement_di_type);
7612 : 3942 : struct_type->llvm_di_type = replacement_di_type;
7613 : 3942 : struct_type->data.structure.resolve_status = ResolveStatusLLVMFull;
7614 [ + + ]: 3942 : if (struct_type->data.structure.llvm_full_type_queue_index != SIZE_MAX) {
7615 : 584 : ZigType *last = g->type_resolve_stack.last();
7616 : 584 : assert(last->id == ZigTypeIdStruct);
7617 : 584 : last->data.structure.llvm_full_type_queue_index = struct_type->data.structure.llvm_full_type_queue_index;
7618 : 584 : g->type_resolve_stack.swap_remove(struct_type->data.structure.llvm_full_type_queue_index);
7619 : 584 : struct_type->data.structure.llvm_full_type_queue_index = SIZE_MAX;
7620 : : }
7621 : : }
7622 : :
7623 : 8191 : static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatus wanted_resolve_status) {
7624 : 8191 : assert(enum_type->data.enumeration.resolve_status >= ResolveStatusSizeKnown);
7625 [ + + ]: 8191 : if (enum_type->data.enumeration.resolve_status >= wanted_resolve_status) return;
7626 : :
7627 : 577 : Scope *scope = &enum_type->data.enumeration.decls_scope->base;
7628 : 577 : ZigType *import = get_scope_import(scope);
7629 : 577 : AstNode *decl_node = enum_type->data.enumeration.decl_node;
7630 : :
7631 [ - + ]: 577 : if (!type_has_bits(enum_type)) {
7632 : 0 : enum_type->llvm_type = g->builtin_types.entry_void->llvm_type;
7633 : :
7634 : 0 : uint64_t debug_size_in_bits = 0;
7635 : 0 : uint64_t debug_align_in_bits = 0;
7636 : 0 : ZigLLVMDIType **di_element_types = nullptr;
7637 : 0 : size_t debug_field_count = 0;
7638 : 0 : enum_type->llvm_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
7639 : 0 : ZigLLVMFileToScope(import->data.structure.root_struct->di_file),
7640 : 0 : buf_ptr(&enum_type->name),
7641 : 0 : import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
7642 : : debug_size_in_bits,
7643 : : debug_align_in_bits,
7644 : : ZigLLVM_DIFlags_Zero,
7645 : : nullptr, di_element_types, (int)debug_field_count, 0, nullptr, "");
7646 : 0 : enum_type->data.enumeration.resolve_status = ResolveStatusLLVMFull;
7647 : 0 : return;
7648 : : }
7649 : :
7650 : 577 : uint32_t field_count = enum_type->data.enumeration.src_field_count;
7651 : :
7652 : 577 : assert(enum_type->data.enumeration.fields);
7653 : 577 : ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
7654 : :
7655 [ + + ]: 4006 : for (uint32_t i = 0; i < field_count; i += 1) {
7656 : 3429 : TypeEnumField *enum_field = &enum_type->data.enumeration.fields[i];
7657 : :
7658 : : // TODO send patch to LLVM to support APInt in createEnumerator instead of int64_t
7659 : : // http://lists.llvm.org/pipermail/llvm-dev/2017-December/119456.html
7660 : 3429 : di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(enum_field->name),
7661 : 3429 : bigint_as_signed(&enum_field->value));
7662 : : }
7663 : :
7664 : 577 : ZigType *tag_int_type = enum_type->data.enumeration.tag_int_type;
7665 : 577 : enum_type->llvm_type = get_llvm_type(g, tag_int_type);
7666 : :
7667 : : // create debug type for tag
7668 : 577 : uint64_t tag_debug_size_in_bits = tag_int_type->size_in_bits;
7669 : 577 : uint64_t tag_debug_align_in_bits = 8*tag_int_type->abi_align;
7670 : 1154 : ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
7671 : 577 : ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&enum_type->name),
7672 : 1154 : import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
7673 : : tag_debug_size_in_bits,
7674 : : tag_debug_align_in_bits,
7675 : : di_enumerators, field_count,
7676 : 577 : get_llvm_di_type(g, tag_int_type), "");
7677 : :
7678 : 577 : enum_type->llvm_di_type = tag_di_type;
7679 : 577 : enum_type->data.enumeration.resolve_status = ResolveStatusLLVMFull;
7680 : : }
7681 : :
7682 : 3829 : static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveStatus wanted_resolve_status) {
7683 [ + + ]: 4017 : if (union_type->data.unionation.resolve_status >= wanted_resolve_status) return;
7684 : :
7685 : 442 : TypeUnionField *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member;
7686 : 442 : ZigType *tag_type = union_type->data.unionation.tag_type;
7687 : 442 : uint32_t gen_field_count = union_type->data.unionation.gen_field_count;
7688 [ + + ]: 442 : if (gen_field_count == 0) {
7689 [ + + ]: 24 : if (tag_type == nullptr) {
7690 : 8 : union_type->llvm_type = g->builtin_types.entry_void->llvm_type;
7691 : 8 : union_type->llvm_di_type = g->builtin_types.entry_void->llvm_di_type;
7692 : : } else {
7693 : 16 : union_type->llvm_type = get_llvm_type(g, tag_type);
7694 : 16 : union_type->llvm_di_type = get_llvm_di_type(g, tag_type);
7695 : : }
7696 : 24 : union_type->data.unionation.resolve_status = ResolveStatusLLVMFull;
7697 : 24 : return;
7698 : : }
7699 : :
7700 : 418 : Scope *scope = &union_type->data.unionation.decls_scope->base;
7701 : 418 : ZigType *import = get_scope_import(scope);
7702 : 418 : AstNode *decl_node = union_type->data.unionation.decl_node;
7703 : :
7704 [ + + ]: 418 : if (union_type->data.unionation.resolve_status < ResolveStatusLLVMFwdDecl) {
7705 : 358 : union_type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&union_type->name));
7706 [ + - ]: 358 : size_t line = decl_node ? decl_node->line : 0;
7707 : 358 : unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();
7708 : 716 : union_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
7709 : 358 : dwarf_kind, buf_ptr(&union_type->name),
7710 : 358 : ZigLLVMFileToScope(import->data.structure.root_struct->di_file),
7711 : 358 : import->data.structure.root_struct->di_file, (unsigned)(line + 1));
7712 : :
7713 : 358 : union_type->data.unionation.resolve_status = ResolveStatusLLVMFwdDecl;
7714 [ + + ]: 358 : if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;
7715 : : }
7716 : :
7717 : 358 : ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count);
7718 : 358 : uint32_t field_count = union_type->data.unionation.src_field_count;
7719 [ + + ]: 1267 : for (uint32_t i = 0; i < field_count; i += 1) {
7720 : 909 : TypeUnionField *union_field = &union_type->data.unionation.fields[i];
7721 [ + + ]: 909 : if (!type_has_bits(union_field->type_entry))
7722 : 164 : continue;
7723 : :
7724 : 745 : ZigLLVMDIType *field_di_type = get_llvm_di_type(g, union_field->type_entry);
7725 [ - + ]: 745 : if (union_type->data.unionation.resolve_status >= wanted_resolve_status) return;
7726 : :
7727 : 745 : uint64_t store_size_in_bits = union_field->type_entry->size_in_bits;
7728 : 745 : uint64_t abi_align_in_bits = 8*union_field->type_entry->abi_align;
7729 : 745 : AstNode *field_node = decl_node->data.container_decl.fields.at(i);
7730 : 745 : union_inner_di_types[union_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
7731 : 745 : ZigLLVMTypeToScope(union_type->llvm_di_type), buf_ptr(union_field->enum_field->name),
7732 : 1490 : import->data.structure.root_struct->di_file, (unsigned)(field_node->line + 1),
7733 : : store_size_in_bits,
7734 : : abi_align_in_bits,
7735 : : 0,
7736 : : ZigLLVM_DIFlags_Zero, field_di_type);
7737 : :
7738 : : }
7739 : :
7740 [ + + ][ + + ]: 358 : if (tag_type == nullptr || !type_has_bits(tag_type)) {
[ + + ]
7741 : 104 : assert(most_aligned_union_member != nullptr);
7742 : :
7743 : 104 : size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->type_entry->abi_size;
7744 [ + + ]: 104 : if (padding_bytes > 0) {
7745 : 18 : ZigType *u8_type = get_int_type(g, false, 8);
7746 : 18 : ZigType *padding_array = get_array_type(g, u8_type, padding_bytes);
7747 : : LLVMTypeRef union_element_types[] = {
7748 : 18 : most_aligned_union_member->type_entry->llvm_type,
7749 : 18 : get_llvm_type(g, padding_array),
7750 : 36 : };
7751 : 18 : LLVMStructSetBody(union_type->llvm_type, union_element_types, 2, false);
7752 : : } else {
7753 : 86 : LLVMStructSetBody(union_type->llvm_type, &most_aligned_union_member->type_entry->llvm_type, 1, false);
7754 : : }
7755 : 104 : union_type->data.unionation.union_llvm_type = union_type->llvm_type;
7756 : 104 : union_type->data.unionation.gen_tag_index = SIZE_MAX;
7757 : 104 : union_type->data.unionation.gen_union_index = SIZE_MAX;
7758 : :
7759 : : // create debug type for union
7760 : 104 : ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
7761 : 104 : ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&union_type->name),
7762 : 208 : import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
7763 : 104 : union_type->data.unionation.union_abi_size * 8,
7764 : 104 : most_aligned_union_member->align * 8,
7765 : : ZigLLVM_DIFlags_Zero, union_inner_di_types,
7766 : 104 : gen_field_count, 0, "");
7767 : :
7768 : 104 : ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type);
7769 : 104 : union_type->llvm_di_type = replacement_di_type;
7770 : 104 : union_type->data.unionation.resolve_status = ResolveStatusLLVMFull;
7771 : 104 : return;
7772 : : }
7773 : :
7774 : : LLVMTypeRef union_type_ref;
7775 : 254 : size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->type_entry->abi_size;
7776 [ + + ]: 254 : if (padding_bytes == 0) {
7777 : 223 : union_type_ref = get_llvm_type(g, most_aligned_union_member->type_entry);
7778 : : } else {
7779 : 31 : ZigType *u8_type = get_int_type(g, false, 8);
7780 : 31 : ZigType *padding_array = get_array_type(g, u8_type, padding_bytes);
7781 : : LLVMTypeRef union_element_types[] = {
7782 : 31 : get_llvm_type(g, most_aligned_union_member->type_entry),
7783 : 31 : get_llvm_type(g, padding_array),
7784 : 62 : };
7785 : 31 : union_type_ref = LLVMStructType(union_element_types, 2, false);
7786 : : }
7787 : 254 : union_type->data.unionation.union_llvm_type = union_type_ref;
7788 : :
7789 : : LLVMTypeRef root_struct_element_types[2];
7790 : 254 : root_struct_element_types[union_type->data.unionation.gen_tag_index] = get_llvm_type(g, tag_type);
7791 : 254 : root_struct_element_types[union_type->data.unionation.gen_union_index] = union_type_ref;
7792 : 254 : LLVMStructSetBody(union_type->llvm_type, root_struct_element_types, 2, false);
7793 : :
7794 : : // create debug type for union
7795 : 254 : ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
7796 : : ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion",
7797 : 508 : import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
7798 : 508 : most_aligned_union_member->type_entry->size_in_bits, 8*most_aligned_union_member->align,
7799 : 254 : ZigLLVM_DIFlags_Zero, union_inner_di_types, gen_field_count, 0, "");
7800 : :
7801 : 254 : uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->llvm_type,
7802 : 508 : union_type->data.unionation.gen_union_index);
7803 : 254 : uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->llvm_type,
7804 : 508 : union_type->data.unionation.gen_tag_index);
7805 : :
7806 : 254 : ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
7807 : : ZigLLVMTypeToScope(union_type->llvm_di_type), "payload",
7808 : 508 : import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
7809 : 254 : most_aligned_union_member->type_entry->size_in_bits,
7810 : 254 : 8*most_aligned_union_member->align,
7811 : : union_offset_in_bits,
7812 : 254 : ZigLLVM_DIFlags_Zero, union_di_type);
7813 : :
7814 : 254 : uint64_t tag_debug_size_in_bits = tag_type->size_in_bits;
7815 : 254 : uint64_t tag_debug_align_in_bits = 8*tag_type->abi_align;
7816 : :
7817 : 254 : ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
7818 : : ZigLLVMTypeToScope(union_type->llvm_di_type), "tag",
7819 : 508 : import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
7820 : : tag_debug_size_in_bits,
7821 : : tag_debug_align_in_bits,
7822 : : tag_offset_in_bits,
7823 : 254 : ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, tag_type));
7824 : :
7825 : : ZigLLVMDIType *di_root_members[2];
7826 : 254 : di_root_members[union_type->data.unionation.gen_tag_index] = tag_member_di_type;
7827 : 254 : di_root_members[union_type->data.unionation.gen_union_index] = union_member_di_type;
7828 : :
7829 : 254 : uint64_t debug_size_in_bits = union_type->size_in_bits;
7830 : 254 : uint64_t debug_align_in_bits = 8*union_type->abi_align;
7831 : 254 : ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
7832 : 254 : ZigLLVMFileToScope(import->data.structure.root_struct->di_file),
7833 : 254 : buf_ptr(&union_type->name),
7834 : 508 : import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
7835 : : debug_size_in_bits,
7836 : : debug_align_in_bits,
7837 : 254 : ZigLLVM_DIFlags_Zero, nullptr, di_root_members, 2, 0, nullptr, "");
7838 : :
7839 : 254 : ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type);
7840 : 254 : union_type->llvm_di_type = replacement_di_type;
7841 : 254 : union_type->data.unionation.resolve_status = ResolveStatusLLVMFull;
7842 : : }
7843 : :
7844 : 191206 : static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
7845 [ + + ]: 191206 : if (type->llvm_di_type != nullptr) return;
7846 : :
7847 [ - + ]: 10770 : if (resolve_pointer_zero_bits(g, type) != ErrorNone)
7848 : 0 : zig_unreachable();
7849 : :
7850 [ - + ]: 10770 : if (!type_has_bits(type)) {
7851 : 0 : type->llvm_type = g->builtin_types.entry_void->llvm_type;
7852 : 0 : type->llvm_di_type = g->builtin_types.entry_void->llvm_di_type;
7853 : 0 : return;
7854 : : }
7855 : :
7856 : 10770 : ZigType *elem_type = type->data.pointer.child_type;
7857 : :
7858 [ + + ][ + + ]: 10770 : if (type->data.pointer.is_const || type->data.pointer.is_volatile ||
[ + + ]
7859 [ + + ][ + + ]: 6861 : type->data.pointer.explicit_alignment != 0 || type->data.pointer.ptr_len != PtrLenSingle ||
7860 [ - + ]: 6332 : type->data.pointer.bit_offset_in_host != 0 || type->data.pointer.allow_zero)
7861 : : {
7862 : 4438 : ZigType *peer_type = get_pointer_to_type_extra(g, elem_type, false, false,
7863 : 4438 : PtrLenSingle, 0, 0, type->data.pointer.host_int_bytes, false);
7864 : 4438 : type->llvm_type = get_llvm_type(g, peer_type);
7865 : 4438 : type->llvm_di_type = get_llvm_di_type(g, peer_type);
7866 : 4438 : return;
7867 : : }
7868 : :
7869 [ + + ]: 6332 : if (type->data.pointer.host_int_bytes == 0) {
7870 : 6324 : assertNoError(type_resolve(g, elem_type, ResolveStatusLLVMFwdDecl));
7871 : 6324 : type->llvm_type = LLVMPointerType(elem_type->llvm_type, 0);
7872 : 6324 : uint64_t debug_size_in_bits = 8*get_store_size_bytes(type->size_in_bits);
7873 : 6324 : uint64_t debug_align_in_bits = 8*type->abi_align;
7874 : 6324 : type->llvm_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, elem_type->llvm_di_type,
7875 : 6324 : debug_size_in_bits, debug_align_in_bits, buf_ptr(&type->name));
7876 : 6324 : assertNoError(type_resolve(g, elem_type, wanted_resolve_status));
7877 : : } else {
7878 : 8 : ZigType *host_int_type = get_int_type(g, false, type->data.pointer.host_int_bytes * 8);
7879 : 8 : LLVMTypeRef host_int_llvm_type = get_llvm_type(g, host_int_type);
7880 : 8 : type->llvm_type = LLVMPointerType(host_int_llvm_type, 0);
7881 : 8 : uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, host_int_llvm_type);
7882 : 8 : uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, host_int_llvm_type);
7883 : 8 : type->llvm_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, get_llvm_di_type(g, host_int_type),
7884 : 8 : debug_size_in_bits, debug_align_in_bits, buf_ptr(&type->name));
7885 : : }
7886 : : }
7887 : :
7888 : 2660489 : static void resolve_llvm_types_integer(CodeGen *g, ZigType *type) {
7889 [ + + ]: 2660489 : if (type->llvm_di_type != nullptr) return;
7890 : :
7891 [ - + ]: 360 : if (!type_has_bits(type)) {
7892 : 0 : type->llvm_type = g->builtin_types.entry_void->llvm_type;
7893 : 0 : type->llvm_di_type = g->builtin_types.entry_void->llvm_di_type;
7894 : 0 : return;
7895 : : }
7896 : :
7897 : : unsigned dwarf_tag;
7898 [ + + ]: 360 : if (type->data.integral.is_signed) {
7899 [ + + ]: 94 : if (type->size_in_bits == 8) {
7900 : 11 : dwarf_tag = ZigLLVMEncoding_DW_ATE_signed_char();
7901 : : } else {
7902 : 94 : dwarf_tag = ZigLLVMEncoding_DW_ATE_signed();
7903 : : }
7904 : : } else {
7905 [ + + ]: 266 : if (type->size_in_bits == 8) {
7906 : 15 : dwarf_tag = ZigLLVMEncoding_DW_ATE_unsigned_char();
7907 : : } else {
7908 : 251 : dwarf_tag = ZigLLVMEncoding_DW_ATE_unsigned();
7909 : : }
7910 : : }
7911 : :
7912 : 360 : type->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&type->name), type->size_in_bits, dwarf_tag);
7913 : 360 : type->llvm_type = LLVMIntType(type->size_in_bits);
7914 : : }
7915 : :
7916 : 19535 : static void resolve_llvm_types_optional(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
7917 : 19535 : assert(type->id == ZigTypeIdOptional);
7918 : 19535 : assert(type->data.maybe.resolve_status != ResolveStatusInvalid);
7919 : 19535 : assert(type->data.maybe.resolve_status >= ResolveStatusSizeKnown);
7920 [ + + ]: 20112 : if (type->data.maybe.resolve_status >= wanted_resolve_status) return;
7921 : :
7922 : 799 : LLVMTypeRef bool_llvm_type = get_llvm_type(g, g->builtin_types.entry_bool);
7923 : 799 : ZigLLVMDIType *bool_llvm_di_type = get_llvm_di_type(g, g->builtin_types.entry_bool);
7924 : :
7925 : 799 : ZigType *child_type = type->data.maybe.child_type;
7926 [ + + ]: 799 : if (!type_has_bits(child_type)) {
7927 : 24 : type->llvm_type = bool_llvm_type;
7928 : 24 : type->llvm_di_type = bool_llvm_di_type;
7929 : 24 : type->data.maybe.resolve_status = ResolveStatusLLVMFull;
7930 : 24 : return;
7931 : : }
7932 : :
7933 [ + + ][ + + ]: 775 : if (type_is_nonnull_ptr(child_type) || child_type->id == ZigTypeIdErrorSet) {
[ + + ]
7934 : 537 : type->llvm_type = get_llvm_type(g, child_type);
7935 : 537 : type->llvm_di_type = get_llvm_di_type(g, child_type);
7936 : 537 : type->data.maybe.resolve_status = ResolveStatusLLVMFull;
7937 : 537 : return;
7938 : : }
7939 : :
7940 : 238 : ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
7941 : 238 : ZigLLVMDIFile *di_file = nullptr;
7942 : 238 : unsigned line = 0;
7943 : :
7944 [ + + ]: 238 : if (type->data.maybe.resolve_status < ResolveStatusLLVMFwdDecl) {
7945 : 222 : type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&type->name));
7946 : 222 : unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();
7947 : 222 : type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
7948 : 222 : dwarf_kind, buf_ptr(&type->name),
7949 : : compile_unit_scope, di_file, line);
7950 : :
7951 : 222 : type->data.maybe.resolve_status = ResolveStatusLLVMFwdDecl;
7952 [ + + ]: 222 : if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;
7953 : : }
7954 : :
7955 : 222 : LLVMTypeRef child_llvm_type = get_llvm_type(g, child_type);
7956 : 222 : ZigLLVMDIType *child_llvm_di_type = get_llvm_di_type(g, child_type);
7957 [ - + ]: 222 : if (type->data.maybe.resolve_status >= wanted_resolve_status) return;
7958 : :
7959 : : LLVMTypeRef elem_types[] = {
7960 : 222 : get_llvm_type(g, child_type),
7961 : 222 : LLVMInt1Type(),
7962 : 444 : };
7963 : 222 : LLVMStructSetBody(type->llvm_type, elem_types, 2, false);
7964 : :
7965 : 222 : uint64_t val_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, child_llvm_type);
7966 : 222 : uint64_t val_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, child_llvm_type);
7967 : 222 : uint64_t val_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, type->llvm_type, 0);
7968 : :
7969 : 222 : uint64_t maybe_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, bool_llvm_type);
7970 : 222 : uint64_t maybe_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, bool_llvm_type);
7971 : 222 : uint64_t maybe_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, type->llvm_type, 1);
7972 : :
7973 : 222 : uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, type->llvm_type);
7974 : 222 : uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, type->llvm_type);
7975 : :
7976 : : ZigLLVMDIType *di_element_types[] = {
7977 : 222 : ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),
7978 : : "val", di_file, line,
7979 : : val_debug_size_in_bits,
7980 : : val_debug_align_in_bits,
7981 : : val_offset_in_bits,
7982 : : ZigLLVM_DIFlags_Zero, child_llvm_di_type),
7983 : 222 : ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),
7984 : : "maybe", di_file, line,
7985 : : maybe_debug_size_in_bits,
7986 : : maybe_debug_align_in_bits,
7987 : : maybe_offset_in_bits,
7988 : : ZigLLVM_DIFlags_Zero, bool_llvm_di_type),
7989 : 444 : };
7990 : 222 : ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
7991 : : compile_unit_scope,
7992 : 222 : buf_ptr(&type->name),
7993 : : di_file, line, debug_size_in_bits, debug_align_in_bits, ZigLLVM_DIFlags_Zero,
7994 : 222 : nullptr, di_element_types, 2, 0, nullptr, "");
7995 : :
7996 : 222 : ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);
7997 : 222 : type->llvm_di_type = replacement_di_type;
7998 : 222 : type->data.maybe.resolve_status = ResolveStatusLLVMFull;
7999 : : }
8000 : :
8001 : 49990 : static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {
8002 [ + + ]: 49990 : if (type->llvm_di_type != nullptr) return;
8003 : :
8004 : 2100 : ZigType *payload_type = type->data.error_union.payload_type;
8005 : 2100 : ZigType *err_set_type = type->data.error_union.err_set_type;
8006 : :
8007 [ + + ]: 2100 : if (!type_has_bits(payload_type)) {
8008 : 735 : assert(type_has_bits(err_set_type));
8009 : 735 : type->llvm_type = get_llvm_type(g, err_set_type);
8010 : 735 : type->llvm_di_type = get_llvm_di_type(g, err_set_type);
8011 [ - + ]: 1365 : } else if (!type_has_bits(err_set_type)) {
8012 : 0 : type->llvm_type = get_llvm_type(g, payload_type);
8013 : 0 : type->llvm_di_type = get_llvm_di_type(g, payload_type);
8014 : : } else {
8015 : 1365 : LLVMTypeRef err_set_llvm_type = get_llvm_type(g, err_set_type);
8016 : 1365 : LLVMTypeRef payload_llvm_type = get_llvm_type(g, payload_type);
8017 : : LLVMTypeRef elem_types[3];
8018 : 1365 : elem_types[err_union_err_index] = err_set_llvm_type;
8019 : 1365 : elem_types[err_union_payload_index] = payload_llvm_type;
8020 : :
8021 : 1365 : type->llvm_type = LLVMStructType(elem_types, 2, false);
8022 [ + + ]: 1365 : if (LLVMABISizeOfType(g->target_data_ref, type->llvm_type) != type->abi_size) {
8023 : : // we need to do our own padding
8024 : 8 : type->data.error_union.pad_llvm_type = LLVMArrayType(LLVMInt8Type(), type->data.error_union.pad_bytes);
8025 : 8 : elem_types[2] = type->data.error_union.pad_llvm_type;
8026 : 8 : type->llvm_type = LLVMStructType(elem_types, 3, false);
8027 : : }
8028 : :
8029 : 1365 : ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
8030 : 1365 : ZigLLVMDIFile *di_file = nullptr;
8031 : 1365 : unsigned line = 0;
8032 : 1365 : type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
8033 : 1365 : ZigLLVMTag_DW_structure_type(), buf_ptr(&type->name),
8034 : : compile_unit_scope, di_file, line);
8035 : :
8036 : 1365 : uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, err_set_llvm_type);
8037 : 1365 : uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, err_set_llvm_type);
8038 : 1365 : uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, type->llvm_type, err_union_err_index);
8039 : :
8040 : 1365 : uint64_t value_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, payload_llvm_type);
8041 : 1365 : uint64_t value_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, payload_llvm_type);
8042 : 1365 : uint64_t value_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, type->llvm_type,
8043 : 1365 : err_union_payload_index);
8044 : :
8045 : 1365 : uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, type->llvm_type);
8046 : 1365 : uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, type->llvm_type);
8047 : :
8048 : : ZigLLVMDIType *di_element_types[2];
8049 : 1365 : di_element_types[err_union_err_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
8050 : : ZigLLVMTypeToScope(type->llvm_di_type),
8051 : : "tag", di_file, line,
8052 : : tag_debug_size_in_bits,
8053 : : tag_debug_align_in_bits,
8054 : : tag_offset_in_bits,
8055 : : ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, err_set_type));
8056 : 1365 : di_element_types[err_union_payload_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
8057 : : ZigLLVMTypeToScope(type->llvm_di_type),
8058 : : "value", di_file, line,
8059 : : value_debug_size_in_bits,
8060 : : value_debug_align_in_bits,
8061 : : value_offset_in_bits,
8062 : : ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, payload_type));
8063 : :
8064 : 1365 : ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
8065 : : compile_unit_scope,
8066 : 1365 : buf_ptr(&type->name),
8067 : : di_file, line,
8068 : : debug_size_in_bits,
8069 : : debug_align_in_bits,
8070 : : ZigLLVM_DIFlags_Zero,
8071 : 1365 : nullptr, di_element_types, 2, 0, nullptr, "");
8072 : :
8073 : 1365 : ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);
8074 : 1365 : type->llvm_di_type = replacement_di_type;
8075 : : }
8076 : : }
8077 : :
8078 : 26424 : static void resolve_llvm_types_array(CodeGen *g, ZigType *type) {
8079 [ + + ]: 26424 : if (type->llvm_di_type != nullptr) return;
8080 : :
8081 [ - + ]: 2100 : if (!type_has_bits(type)) {
8082 : 0 : type->llvm_type = g->builtin_types.entry_void->llvm_type;
8083 : 0 : type->llvm_di_type = g->builtin_types.entry_void->llvm_di_type;
8084 : 0 : return;
8085 : : }
8086 : :
8087 : 2100 : ZigType *elem_type = type->data.array.child_type;
8088 : :
8089 : : // TODO https://github.com/ziglang/zig/issues/1424
8090 : 2100 : type->llvm_type = LLVMArrayType(get_llvm_type(g, elem_type), (unsigned)type->data.array.len);
8091 : :
8092 : 2100 : uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, type->llvm_type);
8093 : 2100 : uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, type->llvm_type);
8094 : :
8095 : 2100 : type->llvm_di_type = ZigLLVMCreateDebugArrayType(g->dbuilder, debug_size_in_bits,
8096 : 2100 : debug_align_in_bits, get_llvm_di_type(g, elem_type), (int)type->data.array.len);
8097 : : }
8098 : :
8099 : 48337 : static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) {
8100 [ + + ]: 48337 : if (fn_type->llvm_di_type != nullptr) return;
8101 : :
8102 : 9593 : FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
8103 : 9593 : bool first_arg_return = want_first_arg_sret(g, fn_type_id);
8104 : 9593 : bool is_async = fn_type_id->cc == CallingConventionAsync;
8105 : 9593 : bool is_c_abi = fn_type_id->cc == CallingConventionC;
8106 [ + + ][ + - ]: 9593 : bool prefix_arg_error_return_trace = g->have_err_ret_tracing && fn_type_can_fail(fn_type_id);
8107 : : // +1 for maybe making the first argument the return value
8108 : : // +1 for maybe first argument the error return trace
8109 : : // +2 for maybe arguments async allocator and error code pointer
8110 : 9593 : ZigList<LLVMTypeRef> gen_param_types = {};
8111 : : // +1 because 0 is the return type and
8112 : : // +1 for maybe making first arg ret val and
8113 : : // +1 for maybe first argument the error return trace
8114 : : // +2 for maybe arguments async allocator and error code pointer
8115 : 9593 : ZigList<ZigLLVMDIType *> param_di_types = {};
8116 : : ZigType *gen_return_type;
8117 [ + + ]: 9593 : if (is_async) {
8118 : 776 : gen_return_type = g->builtin_types.entry_void;
8119 : 776 : param_di_types.append(get_llvm_di_type(g, gen_return_type));
8120 [ + + ]: 8817 : } else if (!type_has_bits(fn_type_id->return_type)) {
8121 : 2148 : gen_return_type = g->builtin_types.entry_void;
8122 : 2148 : param_di_types.append(get_llvm_di_type(g, gen_return_type));
8123 [ + + ]: 6669 : } else if (first_arg_return) {
8124 : 2312 : gen_return_type = g->builtin_types.entry_void;
8125 : 2312 : param_di_types.append(get_llvm_di_type(g, gen_return_type));
8126 : 2312 : ZigType *gen_type = get_pointer_to_type(g, fn_type_id->return_type, false);
8127 : 2312 : gen_param_types.append(get_llvm_type(g, gen_type));
8128 : 2312 : param_di_types.append(get_llvm_di_type(g, gen_type));
8129 : : } else {
8130 : 4357 : gen_return_type = fn_type_id->return_type;
8131 : 4357 : param_di_types.append(get_llvm_di_type(g, gen_return_type));
8132 : : }
8133 : 9593 : fn_type->data.fn.gen_return_type = gen_return_type;
8134 : :
8135 [ + + ][ + + ]: 9593 : if (prefix_arg_error_return_trace && !is_async) {
8136 : 3276 : ZigType *gen_type = get_pointer_to_type(g, get_stack_trace_type(g), false);
8137 : 3276 : gen_param_types.append(get_llvm_type(g, gen_type));
8138 : 3276 : param_di_types.append(get_llvm_di_type(g, gen_type));
8139 : : }
8140 [ + + ]: 9593 : if (is_async) {
8141 : 776 : fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(2);
8142 : :
8143 : 776 : ZigType *frame_type = get_any_frame_type(g, fn_type_id->return_type);
8144 : 776 : gen_param_types.append(get_llvm_type(g, frame_type));
8145 : 776 : param_di_types.append(get_llvm_di_type(g, frame_type));
8146 : :
8147 : 776 : fn_type->data.fn.gen_param_info[0].src_index = 0;
8148 : 776 : fn_type->data.fn.gen_param_info[0].gen_index = 0;
8149 : 776 : fn_type->data.fn.gen_param_info[0].type = frame_type;
8150 : :
8151 : 776 : gen_param_types.append(get_llvm_type(g, g->builtin_types.entry_usize));
8152 : 776 : param_di_types.append(get_llvm_di_type(g, g->builtin_types.entry_usize));
8153 : :
8154 : 776 : fn_type->data.fn.gen_param_info[1].src_index = 1;
8155 : 776 : fn_type->data.fn.gen_param_info[1].gen_index = 1;
8156 : 776 : fn_type->data.fn.gen_param_info[1].type = g->builtin_types.entry_usize;
8157 : : } else {
8158 : 8817 : fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count);
8159 [ + + ]: 26804 : for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
8160 : 17987 : FnTypeParamInfo *src_param_info = &fn_type->data.fn.fn_type_id.param_info[i];
8161 : 17987 : ZigType *type_entry = src_param_info->type;
8162 : 17987 : FnGenParamInfo *gen_param_info = &fn_type->data.fn.gen_param_info[i];
8163 : :
8164 : 17987 : gen_param_info->src_index = i;
8165 : 17987 : gen_param_info->gen_index = SIZE_MAX;
8166 : :
8167 [ + + ][ + + ]: 17987 : if (is_c_abi || !type_has_bits(type_entry))
[ + + ]
8168 : 825 : continue;
8169 : :
8170 : : ZigType *gen_type;
8171 [ + + ]: 17162 : if (handle_is_ptr(type_entry)) {
8172 : 6005 : gen_type = get_pointer_to_type(g, type_entry, true);
8173 : 6005 : gen_param_info->is_byval = true;
8174 : : } else {
8175 : 11157 : gen_type = type_entry;
8176 : : }
8177 : 17162 : gen_param_info->gen_index = gen_param_types.length;
8178 : 17162 : gen_param_info->type = gen_type;
8179 : 17162 : gen_param_types.append(get_llvm_type(g, gen_type));
8180 : :
8181 : 17162 : param_di_types.append(get_llvm_di_type(g, gen_type));
8182 : : }
8183 : : }
8184 : :
8185 [ + + ]: 9593 : if (is_c_abi) {
8186 : 423 : FnWalk fn_walk = {};
8187 : 423 : fn_walk.id = FnWalkIdTypes;
8188 : 423 : fn_walk.data.types.param_di_types = ¶m_di_types;
8189 : 423 : fn_walk.data.types.gen_param_types = &gen_param_types;
8190 : 423 : walk_function_params(g, fn_type, &fn_walk);
8191 : : }
8192 : :
8193 : 9593 : fn_type->data.fn.gen_param_count = gen_param_types.length;
8194 : :
8195 [ + + ]: 34544 : for (size_t i = 0; i < gen_param_types.length; i += 1) {
8196 : 24951 : assert(gen_param_types.items[i] != nullptr);
8197 : : }
8198 : :
8199 : 9593 : fn_type->data.fn.raw_type_ref = LLVMFunctionType(get_llvm_type(g, gen_return_type),
8200 : 19186 : gen_param_types.items, (unsigned int)gen_param_types.length, fn_type_id->is_var_args);
8201 : 9593 : fn_type->llvm_type = LLVMPointerType(fn_type->data.fn.raw_type_ref, 0);
8202 : 9593 : fn_type->data.fn.raw_di_type = ZigLLVMCreateSubroutineType(g->dbuilder, param_di_types.items, (int)param_di_types.length, 0);
8203 : 9593 : fn_type->llvm_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, fn_type->data.fn.raw_di_type,
8204 : 9593 : LLVMStoreSizeOfType(g->target_data_ref, fn_type->llvm_type),
8205 : 9593 : LLVMABIAlignmentOfType(g->target_data_ref, fn_type->llvm_type), "");
8206 : : }
8207 : :
8208 : 25244 : void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn) {
8209 : : Error err;
8210 [ + + ]: 48840 : if (fn->raw_di_type != nullptr) return;
8211 : :
8212 : 24420 : ZigType *fn_type = fn->type_entry;
8213 [ + + ]: 24420 : if (!fn_is_async(fn)) {
8214 : 23596 : resolve_llvm_types_fn_type(g, fn_type);
8215 : 23596 : fn->raw_type_ref = fn_type->data.fn.raw_type_ref;
8216 : 23596 : fn->raw_di_type = fn_type->data.fn.raw_di_type;
8217 : 23596 : return;
8218 : : }
8219 : :
8220 : 824 : ZigType *gen_return_type = g->builtin_types.entry_void;
8221 : 824 : ZigList<ZigLLVMDIType *> param_di_types = {};
8222 : 824 : ZigList<LLVMTypeRef> gen_param_types = {};
8223 : : // first "parameter" is return value
8224 : 824 : param_di_types.append(get_llvm_di_type(g, gen_return_type));
8225 : :
8226 : 824 : ZigType *frame_type = get_fn_frame_type(g, fn);
8227 : 824 : ZigType *ptr_type = get_pointer_to_type(g, frame_type, false);
8228 [ - + ]: 824 : if ((err = type_resolve(g, ptr_type, ResolveStatusLLVMFwdDecl)))
8229 : 0 : zig_unreachable();
8230 : 824 : gen_param_types.append(ptr_type->llvm_type);
8231 : 824 : param_di_types.append(ptr_type->llvm_di_type);
8232 : :
8233 : : // this parameter is used to pass the result pointer when await completes
8234 : 824 : gen_param_types.append(get_llvm_type(g, g->builtin_types.entry_usize));
8235 : 824 : param_di_types.append(get_llvm_di_type(g, g->builtin_types.entry_usize));
8236 : :
8237 : 824 : fn->raw_type_ref = LLVMFunctionType(get_llvm_type(g, gen_return_type),
8238 : 824 : gen_param_types.items, gen_param_types.length, false);
8239 : 824 : fn->raw_di_type = ZigLLVMCreateSubroutineType(g->dbuilder, param_di_types.items, (int)param_di_types.length, 0);
8240 : : }
8241 : :
8242 : 9 : static void resolve_llvm_types_anyerror(CodeGen *g) {
8243 : 9 : ZigType *entry = g->builtin_types.entry_global_error_set;
8244 : 9 : entry->llvm_type = get_llvm_type(g, g->err_tag_type);
8245 : 9 : ZigList<ZigLLVMDIEnumerator *> err_enumerators = {};
8246 : : // reserve index 0 to indicate no error
8247 : 9 : err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, "(none)", 0));
8248 [ + + ]: 698 : for (size_t i = 1; i < g->errors_by_index.length; i += 1) {
8249 : 689 : ErrorTableEntry *error_entry = g->errors_by_index.at(i);
8250 : 689 : err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(&error_entry->name), i));
8251 : : }
8252 : :
8253 : : // create debug type for error sets
8254 : 9 : uint64_t tag_debug_size_in_bits = g->err_tag_type->size_in_bits;
8255 : 9 : uint64_t tag_debug_align_in_bits = 8*g->err_tag_type->abi_align;
8256 : 9 : ZigLLVMDIFile *err_set_di_file = nullptr;
8257 : 18 : entry->llvm_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
8258 : 9 : ZigLLVMCompileUnitToScope(g->compile_unit), buf_ptr(&entry->name),
8259 : : err_set_di_file, 0,
8260 : : tag_debug_size_in_bits,
8261 : : tag_debug_align_in_bits,
8262 : 9 : err_enumerators.items, err_enumerators.length,
8263 : : get_llvm_di_type(g, g->err_tag_type), "");
8264 : 9 : }
8265 : :
8266 : 6264 : static void resolve_llvm_types_async_frame(CodeGen *g, ZigType *frame_type, ResolveStatus wanted_resolve_status) {
8267 : : Error err;
8268 [ - + ]: 6264 : if ((err = type_resolve(g, frame_type, ResolveStatusSizeKnown)))
8269 : 0 : zig_unreachable();
8270 : :
8271 [ + + ]: 6264 : ZigType *passed_frame_type = fn_is_async(frame_type->data.frame.fn) ? frame_type : nullptr;
8272 : 6264 : resolve_llvm_types_struct(g, frame_type->data.frame.locals_struct, wanted_resolve_status, passed_frame_type);
8273 : 6264 : frame_type->llvm_type = frame_type->data.frame.locals_struct->llvm_type;
8274 : 6264 : frame_type->llvm_di_type = frame_type->data.frame.locals_struct->llvm_di_type;
8275 : 6264 : }
8276 : :
8277 : 4960 : static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, ResolveStatus wanted_resolve_status) {
8278 [ + + ]: 4960 : if (any_frame_type->llvm_di_type != nullptr) return;
8279 : :
8280 : 272 : Buf *name = buf_sprintf("(%s header)", buf_ptr(&any_frame_type->name));
8281 : 272 : LLVMTypeRef frame_header_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(name));
8282 : 272 : any_frame_type->llvm_type = LLVMPointerType(frame_header_type, 0);
8283 : :
8284 : 272 : unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();
8285 : 272 : ZigLLVMDIFile *di_file = nullptr;
8286 : 272 : ZigLLVMDIScope *di_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
8287 : 272 : unsigned line = 0;
8288 : 272 : ZigLLVMDIType *frame_header_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
8289 : 272 : dwarf_kind, buf_ptr(name), di_scope, di_file, line);
8290 : 272 : any_frame_type->llvm_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, frame_header_di_type,
8291 : 272 : 8*g->pointer_size_bytes, 8*g->builtin_types.entry_usize->abi_align, buf_ptr(&any_frame_type->name));
8292 : :
8293 : 272 : LLVMTypeRef llvm_void = LLVMVoidType();
8294 : 272 : LLVMTypeRef arg_types[] = {any_frame_type->llvm_type, g->builtin_types.entry_usize->llvm_type};
8295 : 272 : LLVMTypeRef fn_type = LLVMFunctionType(llvm_void, arg_types, 2, false);
8296 : 272 : LLVMTypeRef usize_type_ref = get_llvm_type(g, g->builtin_types.entry_usize);
8297 : 272 : ZigLLVMDIType *usize_di_type = get_llvm_di_type(g, g->builtin_types.entry_usize);
8298 : 272 : ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
8299 : :
8300 : 272 : ZigType *result_type = any_frame_type->data.any_frame.result_type;
8301 [ + + ]: 272 : ZigType *ptr_result_type = (result_type == nullptr) ? nullptr : get_pointer_to_type(g, result_type, false);
8302 : 272 : LLVMTypeRef ptr_fn_llvm_type = LLVMPointerType(fn_type, 0);
8303 [ + + ]: 272 : if (result_type == nullptr) {
8304 : 8 : g->anyframe_fn_type = ptr_fn_llvm_type;
8305 : : }
8306 : :
8307 : 272 : ZigList<LLVMTypeRef> field_types = {};
8308 : 272 : ZigList<ZigLLVMDIType *> di_element_types = {};
8309 : :
8310 : : // label (grep this): [fn_frame_struct_layout]
8311 : 272 : field_types.append(ptr_fn_llvm_type); // fn_ptr
8312 : 272 : field_types.append(usize_type_ref); // resume_index
8313 : 272 : field_types.append(usize_type_ref); // awaiter
8314 : :
8315 [ + + ][ + + ]: 272 : bool have_result_type = result_type != nullptr && type_has_bits(result_type);
8316 [ + + ]: 272 : if (have_result_type) {
8317 : 256 : field_types.append(get_llvm_type(g, ptr_result_type)); // result_ptr_callee
8318 : 256 : field_types.append(get_llvm_type(g, ptr_result_type)); // result_ptr_awaiter
8319 : 256 : field_types.append(get_llvm_type(g, result_type)); // result
8320 [ + + ]: 256 : if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) {
8321 : 216 : ZigType *ptr_stack_trace = get_pointer_to_type(g, get_stack_trace_type(g), false);
8322 : 216 : field_types.append(get_llvm_type(g, ptr_stack_trace)); // ptr_stack_trace_callee
8323 : 256 : field_types.append(get_llvm_type(g, ptr_stack_trace)); // ptr_stack_trace_awaiter
8324 : : }
8325 : : }
8326 : 272 : LLVMStructSetBody(frame_header_type, field_types.items, field_types.length, false);
8327 : :
8328 : 272 : di_element_types.append(
8329 : : ZigLLVMCreateDebugMemberType(g->dbuilder,
8330 : : ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "fn_ptr",
8331 : : di_file, line,
8332 : 272 : 8*LLVMABISizeOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8333 : 272 : 8*LLVMABIAlignmentOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8334 : 272 : 8*LLVMOffsetOfElement(g->target_data_ref, frame_header_type, di_element_types.length),
8335 : : ZigLLVM_DIFlags_Zero, usize_di_type));
8336 : 272 : di_element_types.append(
8337 : : ZigLLVMCreateDebugMemberType(g->dbuilder,
8338 : : ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "resume_index",
8339 : : di_file, line,
8340 : 272 : 8*LLVMABISizeOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8341 : 272 : 8*LLVMABIAlignmentOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8342 : 272 : 8*LLVMOffsetOfElement(g->target_data_ref, frame_header_type, di_element_types.length),
8343 : : ZigLLVM_DIFlags_Zero, usize_di_type));
8344 : 272 : di_element_types.append(
8345 : : ZigLLVMCreateDebugMemberType(g->dbuilder,
8346 : : ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "awaiter",
8347 : : di_file, line,
8348 : 272 : 8*LLVMABISizeOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8349 : 272 : 8*LLVMABIAlignmentOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8350 : 272 : 8*LLVMOffsetOfElement(g->target_data_ref, frame_header_type, di_element_types.length),
8351 : : ZigLLVM_DIFlags_Zero, usize_di_type));
8352 : :
8353 [ + + ]: 272 : if (have_result_type) {
8354 : 512 : di_element_types.append(
8355 : : ZigLLVMCreateDebugMemberType(g->dbuilder,
8356 : : ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "result_ptr_callee",
8357 : : di_file, line,
8358 : 256 : 8*LLVMABISizeOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8359 : 256 : 8*LLVMABIAlignmentOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8360 : 256 : 8*LLVMOffsetOfElement(g->target_data_ref, frame_header_type, di_element_types.length),
8361 : : ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, ptr_result_type)));
8362 : 512 : di_element_types.append(
8363 : : ZigLLVMCreateDebugMemberType(g->dbuilder,
8364 : : ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "result_ptr_awaiter",
8365 : : di_file, line,
8366 : 256 : 8*LLVMABISizeOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8367 : 256 : 8*LLVMABIAlignmentOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8368 : 256 : 8*LLVMOffsetOfElement(g->target_data_ref, frame_header_type, di_element_types.length),
8369 : : ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, ptr_result_type)));
8370 : 512 : di_element_types.append(
8371 : : ZigLLVMCreateDebugMemberType(g->dbuilder,
8372 : : ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "result",
8373 : : di_file, line,
8374 : 256 : 8*LLVMABISizeOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8375 : 256 : 8*LLVMABIAlignmentOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8376 : 256 : 8*LLVMOffsetOfElement(g->target_data_ref, frame_header_type, di_element_types.length),
8377 : : ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, result_type)));
8378 : :
8379 [ + + ]: 256 : if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) {
8380 : 216 : ZigType *ptr_stack_trace = get_pointer_to_type(g, get_stack_trace_type(g), false);
8381 : 432 : di_element_types.append(
8382 : : ZigLLVMCreateDebugMemberType(g->dbuilder,
8383 : : ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "ptr_stack_trace_callee",
8384 : : di_file, line,
8385 : 216 : 8*LLVMABISizeOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8386 : 216 : 8*LLVMABIAlignmentOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8387 : 216 : 8*LLVMOffsetOfElement(g->target_data_ref, frame_header_type, di_element_types.length),
8388 : : ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, ptr_stack_trace)));
8389 : 472 : di_element_types.append(
8390 : : ZigLLVMCreateDebugMemberType(g->dbuilder,
8391 : : ZigLLVMTypeToScope(any_frame_type->llvm_di_type), "ptr_stack_trace_awaiter",
8392 : : di_file, line,
8393 : 216 : 8*LLVMABISizeOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8394 : 216 : 8*LLVMABIAlignmentOfType(g->target_data_ref, field_types.at(di_element_types.length)),
8395 : 216 : 8*LLVMOffsetOfElement(g->target_data_ref, frame_header_type, di_element_types.length),
8396 : : ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, ptr_stack_trace)));
8397 : : }
8398 : : };
8399 : :
8400 : 816 : ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
8401 : 272 : compile_unit_scope, buf_ptr(name),
8402 : : di_file, line,
8403 : 272 : 8*LLVMABISizeOfType(g->target_data_ref, frame_header_type),
8404 : 272 : 8*LLVMABIAlignmentOfType(g->target_data_ref, frame_header_type),
8405 : : ZigLLVM_DIFlags_Zero,
8406 : 272 : nullptr, di_element_types.items, di_element_types.length, 0, nullptr, "");
8407 : :
8408 : 272 : ZigLLVMReplaceTemporary(g->dbuilder, frame_header_di_type, replacement_di_type);
8409 : : }
8410 : :
8411 : 3296818 : static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
8412 : 3296818 : assert(wanted_resolve_status > ResolveStatusSizeKnown);
8413 [ - + + + : 3296818 : switch (type->id) {
+ + + + +
+ + + + +
+ - ]
8414 : 0 : case ZigTypeIdInvalid:
8415 : : case ZigTypeIdMetaType:
8416 : : case ZigTypeIdComptimeFloat:
8417 : : case ZigTypeIdComptimeInt:
8418 : : case ZigTypeIdEnumLiteral:
8419 : : case ZigTypeIdUndefined:
8420 : : case ZigTypeIdNull:
8421 : : case ZigTypeIdBoundFn:
8422 : : case ZigTypeIdArgTuple:
8423 : 0 : zig_unreachable();
8424 : 107444 : case ZigTypeIdFloat:
8425 : : case ZigTypeIdOpaque:
8426 : : case ZigTypeIdVoid:
8427 : : case ZigTypeIdBool:
8428 : : case ZigTypeIdUnreachable:
8429 : 107444 : assert(type->llvm_di_type != nullptr);
8430 : 107444 : return;
8431 : 182668 : case ZigTypeIdStruct:
8432 [ + + ]: 182668 : if (type->data.structure.is_slice)
8433 : 96996 : return resolve_llvm_types_slice(g, type, wanted_resolve_status);
8434 : : else
8435 : 85672 : return resolve_llvm_types_struct(g, type, wanted_resolve_status, nullptr);
8436 : 8191 : case ZigTypeIdEnum:
8437 : 8191 : return resolve_llvm_types_enum(g, type, wanted_resolve_status);
8438 : 3829 : case ZigTypeIdUnion:
8439 : 3829 : return resolve_llvm_types_union(g, type, wanted_resolve_status);
8440 : 191206 : case ZigTypeIdPointer:
8441 : 191206 : return resolve_llvm_types_pointer(g, type, wanted_resolve_status);
8442 : 2660489 : case ZigTypeIdInt:
8443 : 2660489 : return resolve_llvm_types_integer(g, type);
8444 : 19535 : case ZigTypeIdOptional:
8445 : 19535 : return resolve_llvm_types_optional(g, type, wanted_resolve_status);
8446 : 49990 : case ZigTypeIdErrorUnion:
8447 : 49990 : return resolve_llvm_types_error_union(g, type);
8448 : 26424 : case ZigTypeIdArray:
8449 : 26424 : return resolve_llvm_types_array(g, type);
8450 : 24741 : case ZigTypeIdFn:
8451 : 24741 : return resolve_llvm_types_fn_type(g, type);
8452 : 10316 : case ZigTypeIdErrorSet: {
8453 [ + + ]: 10316 : if (type->llvm_di_type != nullptr) return;
8454 : :
8455 [ + + ]: 1802 : if (g->builtin_types.entry_global_error_set->llvm_type == nullptr) {
8456 : 9 : resolve_llvm_types_anyerror(g);
8457 : : }
8458 : 1802 : type->llvm_type = g->builtin_types.entry_global_error_set->llvm_type;
8459 : 1802 : type->llvm_di_type = g->builtin_types.entry_global_error_set->llvm_di_type;
8460 : 1802 : return;
8461 : : }
8462 : 761 : case ZigTypeIdVector: {
8463 [ + + ]: 761 : if (type->llvm_di_type != nullptr) return;
8464 : :
8465 : 25 : type->llvm_type = LLVMVectorType(get_llvm_type(g, type->data.vector.elem_type), type->data.vector.len);
8466 : 25 : type->llvm_di_type = ZigLLVMDIBuilderCreateVectorType(g->dbuilder, type->size_in_bits,
8467 : : type->abi_align, get_llvm_di_type(g, type->data.vector.elem_type), type->data.vector.len);
8468 : 25 : return;
8469 : : }
8470 : 6264 : case ZigTypeIdFnFrame:
8471 : 6264 : return resolve_llvm_types_async_frame(g, type, wanted_resolve_status);
8472 : 4960 : case ZigTypeIdAnyFrame:
8473 : 4960 : return resolve_llvm_types_any_frame(g, type, wanted_resolve_status);
8474 : : }
8475 : 0 : zig_unreachable();
8476 : : }
8477 : :
8478 : 2148317 : LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type) {
8479 : 2148317 : assertNoError(type_resolve(g, type, ResolveStatusLLVMFull));
8480 [ + - ][ + + ]: 2148317 : assert(type->abi_size == 0 || type->abi_size >= LLVMABISizeOfType(g->target_data_ref, type->llvm_type));
8481 [ + - ][ + + ]: 2148317 : assert(type->abi_align == 0 || type->abi_align >= LLVMABIAlignmentOfType(g->target_data_ref, type->llvm_type));
8482 : 2148317 : return type->llvm_type;
8483 : : }
8484 : :
8485 : 122053 : ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type) {
8486 : 122053 : assertNoError(type_resolve(g, type, ResolveStatusLLVMFull));
8487 : 122053 : return type->llvm_di_type;
8488 : : }
8489 : :
8490 : 159441 : void src_assert(bool ok, AstNode *source_node) {
8491 [ + - ]: 159441 : if (ok) return;
8492 [ # # ]: 0 : if (source_node == nullptr) {
8493 : 0 : fprintf(stderr, "when analyzing (unknown source location): ");
8494 : : } else {
8495 : 0 : fprintf(stderr, "when analyzing %s:%u:%u: ",
8496 : 0 : buf_ptr(source_node->owner->data.structure.root_struct->path),
8497 : 0 : (unsigned)source_node->line + 1, (unsigned)source_node->column + 1);
8498 : : }
8499 : 0 : const char *msg = "assertion failed. This is a bug in the Zig compiler.";
8500 : 0 : stage2_panic(msg, strlen(msg));
8501 : : }
|