File: zir_sema.zig

package info (click to toggle)
cloc 2.06-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 8,064 kB
  • sloc: perl: 30,146; cpp: 1,219; python: 623; ansic: 334; asm: 267; makefile: 244; sh: 186; sql: 144; java: 136; ruby: 111; cs: 104; pascal: 52; lisp: 50; haskell: 35; f90: 35; cobol: 35; objc: 25; php: 22; javascript: 15; fortran: 9; ml: 8; xml: 7; tcl: 2
file content (140 lines) | stat: -rw-r--r-- 11,731 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// https://github.com/ziglang/zig/raw/master/src-self-hosted/zir_sema.zig
//
//! This file operates on a `Module` instance, transforming untyped ZIR
//! instructions into semantically-analyzed IR instructions. It does type
//! checking, comptime control flow, and safety-check generation. This is the
//! the heart of the Zig compiler.
//! When deciding if something goes into this file or into Module, here is a
//! guiding principle: if it has to do with (untyped) ZIR instructions, it goes
//! here. If the analysis operates on typed IR instructions, it goes in Module.

const std = @import("std");
const mem = std.mem;
const Allocator = std.mem.Allocator;
const Value = @import("value.zig").Value;
const Type = @import("type.zig").Type;
const TypedValue = @import("TypedValue.zig");
const assert = std.debug.assert;
const ir = @import("ir.zig");
const zir = @import("zir.zig");
const Module = @import("Module.zig");
const Inst = ir.Inst;
const Body = ir.Body;
const trace = @import("tracy.zig").trace;
const Scope = Module.Scope;
const InnerError = Module.InnerError;
const Decl = Module.Decl;

pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Inst {
    switch (old_inst.tag) {
        .alloc => return analyzeInstAlloc(mod, scope, old_inst.castTag(.alloc).?),
        .alloc_inferred => return analyzeInstAllocInferred(mod, scope, old_inst.castTag(.alloc_inferred).?),
        .arg => return analyzeInstArg(mod, scope, old_inst.castTag(.arg).?),
        .bitcast_ref => return analyzeInstBitCastRef(mod, scope, old_inst.castTag(.bitcast_ref).?),
        .bitcast_result_ptr => return analyzeInstBitCastResultPtr(mod, scope, old_inst.castTag(.bitcast_result_ptr).?),
        .block => return analyzeInstBlock(mod, scope, old_inst.castTag(.block).?, false),
        .block_comptime => return analyzeInstBlock(mod, scope, old_inst.castTag(.block_comptime).?, true),
        .block_flat => return analyzeInstBlockFlat(mod, scope, old_inst.castTag(.block_flat).?, false),
        .block_comptime_flat => return analyzeInstBlockFlat(mod, scope, old_inst.castTag(.block_comptime_flat).?, true),
        .@"break" => return analyzeInstBreak(mod, scope, old_inst.castTag(.@"break").?),
        .breakpoint => return analyzeInstBreakpoint(mod, scope, old_inst.castTag(.breakpoint).?),
        .breakvoid => return analyzeInstBreakVoid(mod, scope, old_inst.castTag(.breakvoid).?),
        .call => return analyzeInstCall(mod, scope, old_inst.castTag(.call).?),
        .coerce_result_block_ptr => return analyzeInstCoerceResultBlockPtr(mod, scope, old_inst.castTag(.coerce_result_block_ptr).?),
        .coerce_result_ptr => return analyzeInstCoerceResultPtr(mod, scope, old_inst.castTag(.coerce_result_ptr).?),
        .coerce_to_ptr_elem => return analyzeInstCoerceToPtrElem(mod, scope, old_inst.castTag(.coerce_to_ptr_elem).?),
        .compileerror => return analyzeInstCompileError(mod, scope, old_inst.castTag(.compileerror).?),
        .@"const" => return analyzeInstConst(mod, scope, old_inst.castTag(.@"const").?),
        .dbg_stmt => return analyzeInstDbgStmt(mod, scope, old_inst.castTag(.dbg_stmt).?),
        .declref => return analyzeInstDeclRef(mod, scope, old_inst.castTag(.declref).?),
        .declref_str => return analyzeInstDeclRefStr(mod, scope, old_inst.castTag(.declref_str).?),
        .declval => return analyzeInstDeclVal(mod, scope, old_inst.castTag(.declval).?),
        .declval_in_module => return analyzeInstDeclValInModule(mod, scope, old_inst.castTag(.declval_in_module).?),
        .ensure_result_used => return analyzeInstEnsureResultUsed(mod, scope, old_inst.castTag(.ensure_result_used).?),
        .ensure_result_non_error => return analyzeInstEnsureResultNonError(mod, scope, old_inst.castTag(.ensure_result_non_error).?),
        .ensure_indexable => return analyzeInstEnsureIndexable(mod, scope, old_inst.castTag(.ensure_indexable).?),
        .ref => return analyzeInstRef(mod, scope, old_inst.castTag(.ref).?),
        .ret_ptr => return analyzeInstRetPtr(mod, scope, old_inst.castTag(.ret_ptr).?),
        .ret_type => return analyzeInstRetType(mod, scope, old_inst.castTag(.ret_type).?),
        .single_const_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.single_const_ptr_type).?, false, .One),
        .single_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.single_mut_ptr_type).?, true, .One),
        .many_const_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.many_const_ptr_type).?, false, .Many),
        .many_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.many_mut_ptr_type).?, true, .Many),
        .c_const_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.c_const_ptr_type).?, false, .C),
        .c_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.c_mut_ptr_type).?, true, .C),
        .const_slice_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.const_slice_type).?, false, .Slice),
        .mut_slice_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.mut_slice_type).?, true, .Slice),
        .ptr_type => return analyzeInstPtrType(mod, scope, old_inst.castTag(.ptr_type).?),
        .store => return analyzeInstStore(mod, scope, old_inst.castTag(.store).?),
        .str => return analyzeInstStr(mod, scope, old_inst.castTag(.str).?),
        .int => {
            const big_int = old_inst.castTag(.int).?.positionals.int;
            return mod.constIntBig(scope, old_inst.src, Type.initTag(.comptime_int), big_int);
        },
        .inttype => return analyzeInstIntType(mod, scope, old_inst.castTag(.inttype).?),
        .loop => return analyzeInstLoop(mod, scope, old_inst.castTag(.loop).?),
        .param_type => return analyzeInstParamType(mod, scope, old_inst.castTag(.param_type).?),
        .ptrtoint => return analyzeInstPtrToInt(mod, scope, old_inst.castTag(.ptrtoint).?),
        .fieldptr => return analyzeInstFieldPtr(mod, scope, old_inst.castTag(.fieldptr).?),
        .deref => return analyzeInstDeref(mod, scope, old_inst.castTag(.deref).?),
        .as => return analyzeInstAs(mod, scope, old_inst.castTag(.as).?),
        .@"asm" => return analyzeInstAsm(mod, scope, old_inst.castTag(.@"asm").?),
        .@"unreachable" => return analyzeInstUnreachable(mod, scope, old_inst.castTag(.@"unreachable").?, true),
        .unreach_nocheck => return analyzeInstUnreachable(mod, scope, old_inst.castTag(.unreach_nocheck).?, false),
        .@"return" => return analyzeInstRet(mod, scope, old_inst.castTag(.@"return").?),
        .returnvoid => return analyzeInstRetVoid(mod, scope, old_inst.castTag(.returnvoid).?),
        .@"fn" => return analyzeInstFn(mod, scope, old_inst.castTag(.@"fn").?),
        .@"export" => return analyzeInstExport(mod, scope, old_inst.castTag(.@"export").?),
        .primitive => return analyzeInstPrimitive(mod, scope, old_inst.castTag(.primitive).?),
        .fntype => return analyzeInstFnType(mod, scope, old_inst.castTag(.fntype).?),
        .intcast => return analyzeInstIntCast(mod, scope, old_inst.castTag(.intcast).?),
        .bitcast => return analyzeInstBitCast(mod, scope, old_inst.castTag(.bitcast).?),
        .floatcast => return analyzeInstFloatCast(mod, scope, old_inst.castTag(.floatcast).?),
        .elemptr => return analyzeInstElemPtr(mod, scope, old_inst.castTag(.elemptr).?),
        .add => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.add).?),
        .addwrap => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.addwrap).?),
        .sub => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.sub).?),
        .subwrap => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.subwrap).?),
        .mul => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.mul).?),
        .mulwrap => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.mulwrap).?),
        .div => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.div).?),
        .mod_rem => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.mod_rem).?),
        .array_cat => return analyzeInstArrayCat(mod, scope, old_inst.castTag(.array_cat).?),
        .array_mul => return analyzeInstArrayMul(mod, scope, old_inst.castTag(.array_mul).?),
        .bitand => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitand).?),
        .bitnot => return analyzeInstBitNot(mod, scope, old_inst.castTag(.bitnot).?),
        .bitor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitor).?),
        .xor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.xor).?),
        .shl => return analyzeInstShl(mod, scope, old_inst.castTag(.shl).?),
        .shr => return analyzeInstShr(mod, scope, old_inst.castTag(.shr).?),
        .cmp_lt => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_lt).?, .lt),
        .cmp_lte => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_lte).?, .lte),
        .cmp_eq => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_eq).?, .eq),
        .cmp_gte => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_gte).?, .gte),
        .cmp_gt => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_gt).?, .gt),
        .cmp_neq => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_neq).?, .neq),
        .condbr => return analyzeInstCondBr(mod, scope, old_inst.castTag(.condbr).?),
        .isnull => return analyzeInstIsNonNull(mod, scope, old_inst.castTag(.isnull).?, true),
        .isnonnull => return analyzeInstIsNonNull(mod, scope, old_inst.castTag(.isnonnull).?, false),
   // a comment
        .iserr => return analyzeInstIsErr(mod, scope, old_inst.castTag(.iserr).?),  // another comment
        .boolnot => return analyzeInstBoolNot(mod, scope, old_inst.castTag(.boolnot).?),
        .typeof => return analyzeInstTypeOf(mod, scope, old_inst.castTag(.typeof).?),
        .optional_type => return analyzeInstOptionalType(mod, scope, old_inst.castTag(.optional_type).?),
        .unwrap_optional_safe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_safe).?, true),
        .unwrap_optional_unsafe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_unsafe).?, false),
        .unwrap_err_safe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_safe).?, true),
        .unwrap_err_unsafe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_unsafe).?, false),
        .unwrap_err_code => return analyzeInstUnwrapErrCode(mod, scope, old_inst.castTag(.unwrap_err_code).?),
        .ensure_err_payload_void => return analyzeInstEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?),
        .array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?),
        .array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?),
        .enum_literal => return analyzeInstEnumLiteral(mod, scope, old_inst.castTag(.enum_literal).?),
        .merge_error_sets => return analyzeInstMergeErrorSets(mod, scope, old_inst.castTag(.merge_error_sets).?),
        .error_union_type => return analyzeInstErrorUnionType(mod, scope, old_inst.castTag(.error_union_type).?),
        .anyframe_type => return analyzeInstAnyframeType(mod, scope, old_inst.castTag(.anyframe_type).?),
        .error_set => return analyzeInstErrorSet(mod, scope, old_inst.castTag(.error_set).?),
        .slice => return analyzeInstSlice(mod, scope, old_inst.castTag(.slice).?),
        .slice_start => return analyzeInstSliceStart(mod, scope, old_inst.castTag(.slice_start).?),
    }
}