| ... | @@ -1914,6 +1914,15 @@ pub const Object = struct { | ... | @@ -1914,6 +1914,15 @@ pub const Object = struct { |
| 1914 | | 1914 | |
| 1915 | const name = try o.builder.metadataStringFmt("{f}", .{ty.fmt(pt)}); | 1915 | const name = try o.builder.metadataStringFmt("{f}", .{ty.fmt(pt)}); |
| 1916 | | 1916 | |
| | 1917 | // lldb cannot handle non-byte-sized types, so in the logic below, bit sizes are padded up. |
| | 1918 | // For instance, `bool` is considered to be 8 bits, and `u60` is considered to be 64 bits. |
| | 1919 | |
| | 1920 | // I tried using variants (DW_TAG_variant_part + DW_TAG_variant) to encode error unions, |
| | 1921 | // tagged unions, etc; this would have told debuggers which field was active, which could |
| | 1922 | // improve UX significantly. GDB handles this perfectly fine, but unfortunately, LLDB has no |
| | 1923 | // handling for variants at all, and will never print fields in them, so I opted not to use |
| | 1924 | // them for now. |
| | 1925 | |
| 1917 | switch (ty.zigTypeTag(zcu)) { | 1926 | switch (ty.zigTypeTag(zcu)) { |
| 1918 | .void, | 1927 | .void, |
| 1919 | .noreturn, | 1928 | .noreturn, |
| ... | @@ -1925,23 +1934,19 @@ pub const Object = struct { | ... | @@ -1925,23 +1934,19 @@ pub const Object = struct { |
| 1925 | .enum_literal, | 1934 | .enum_literal, |
| 1926 | => return o.builder.debugSignedType(name, 0), | 1935 | => return o.builder.debugSignedType(name, 0), |
| 1927 | | 1936 | |
| | 1937 | .float => return o.builder.debugFloatType(name, ty.floatBits(target)), |
| | 1938 | |
| | 1939 | .bool => return o.builder.debugBoolType(name, 8), |
| | 1940 | |
| 1928 | .int => { | 1941 | .int => { |
| 1929 | const info = ty.intInfo(zcu); | 1942 | const info = ty.intInfo(zcu); |
| 1930 | const bits = ty.abiSize(zcu) * 8; // lldb cannot handle non-byte sized types | 1943 | const bits = ty.abiSize(zcu) * 8; |
| 1931 | return switch (info.signedness) { | 1944 | return switch (info.signedness) { |
| 1932 | .signed => try o.builder.debugSignedType(name, bits), | 1945 | .signed => try o.builder.debugSignedType(name, bits), |
| 1933 | .unsigned => try o.builder.debugUnsignedType(name, bits), | 1946 | .unsigned => try o.builder.debugUnsignedType(name, bits), |
| 1934 | }; | 1947 | }; |
| 1935 | }, | 1948 | }, |
| 1936 | .float => { | 1949 | |
| 1937 | return o.builder.debugFloatType(name, ty.floatBits(target)); | | |
| 1938 | }, | | |
| 1939 | .bool => { | | |
| 1940 | return o.builder.debugBoolType( | | |
| 1941 | name, | | |
| 1942 | 8, // lldb cannot handle non-byte sized types | | |
| 1943 | ); | | |
| 1944 | }, | | |
| 1945 | .pointer => { | 1950 | .pointer => { |
| 1946 | const ptr_size = Type.ptrAbiSize(zcu.getTarget()); | 1951 | const ptr_size = Type.ptrAbiSize(zcu.getTarget()); |
| 1947 | const ptr_align = Type.ptrAbiAlignment(zcu.getTarget()); | 1952 | const ptr_align = Type.ptrAbiAlignment(zcu.getTarget()); |
| ... | @@ -1949,20 +1954,20 @@ pub const Object = struct { | ... | @@ -1949,20 +1954,20 @@ pub const Object = struct { |
| 1949 | if (ty.isSlice(zcu)) { | 1954 | if (ty.isSlice(zcu)) { |
| 1950 | const debug_ptr_type = try o.builder.debugMemberType( | 1955 | const debug_ptr_type = try o.builder.debugMemberType( |
| 1951 | try o.builder.metadataString("ptr"), | 1956 | try o.builder.metadataString("ptr"), |
| 1952 | null, // File | 1957 | null, // file |
| 1953 | ty_fwd_ref, | 1958 | ty_fwd_ref, |
| 1954 | 0, // Line | 1959 | 0, // line |
| 1955 | try o.getDebugType(pt, ty.slicePtrFieldType(zcu)), | 1960 | try o.getDebugType(pt, ty.slicePtrFieldType(zcu)), |
| 1956 | ptr_size * 8, | 1961 | ptr_size * 8, |
| 1957 | ptr_align.toByteUnits().? * 8, | 1962 | ptr_align.toByteUnits().? * 8, |
| 1958 | 0, // Offset | 1963 | 0, // offset |
| 1959 | ); | 1964 | ); |
| 1960 | | 1965 | |
| 1961 | const debug_len_type = try o.builder.debugMemberType( | 1966 | const debug_len_type = try o.builder.debugMemberType( |
| 1962 | try o.builder.metadataString("len"), | 1967 | try o.builder.metadataString("len"), |
| 1963 | null, // File | 1968 | null, // file |
| 1964 | ty_fwd_ref, | 1969 | ty_fwd_ref, |
| 1965 | 0, // Line | 1970 | 0, // line |
| 1966 | try o.getDebugType(pt, .usize), | 1971 | try o.getDebugType(pt, .usize), |
| 1967 | ptr_size * 8, | 1972 | ptr_size * 8, |
| 1968 | ptr_align.toByteUnits().? * 8, | 1973 | ptr_align.toByteUnits().? * 8, |
| ... | @@ -1971,10 +1976,10 @@ pub const Object = struct { | ... | @@ -1971,10 +1976,10 @@ pub const Object = struct { |
| 1971 | | 1976 | |
| 1972 | return o.builder.debugStructType( | 1977 | return o.builder.debugStructType( |
| 1973 | name, | 1978 | name, |
| 1974 | null, // File | 1979 | null, // file |
| 1975 | o.debug_compile_unit.unwrap().?, // Scope | 1980 | o.debug_compile_unit.unwrap().?, // scope |
| 1976 | 0, // Line | 1981 | 0, // line |
| 1977 | null, // Underlying type | 1982 | null, // underlying type |
| 1978 | ptr_size * 2 * 8, | 1983 | ptr_size * 2 * 8, |
| 1979 | ptr_align.toByteUnits().? * 8, | 1984 | ptr_align.toByteUnits().? * 8, |
| 1980 | try o.builder.metadataTuple(&.{ | 1985 | try o.builder.metadataTuple(&.{ |
| ... | @@ -1986,36 +1991,34 @@ pub const Object = struct { | ... | @@ -1986,36 +1991,34 @@ pub const Object = struct { |
| 1986 | | 1991 | |
| 1987 | return o.builder.debugPointerType( | 1992 | return o.builder.debugPointerType( |
| 1988 | name, | 1993 | name, |
| 1989 | null, // File | 1994 | null, // file |
| 1990 | null, // Scope | 1995 | o.debug_compile_unit.unwrap().?, // scope |
| 1991 | 0, // Line | 1996 | 0, // line |
| 1992 | try o.getDebugType(pt, ty.childType(zcu)), | 1997 | try o.getDebugType(pt, ty.childType(zcu)), |
| 1993 | ptr_size * 8, | 1998 | ptr_size * 8, |
| 1994 | ptr_align.toByteUnits().? * 8, | 1999 | ptr_align.toByteUnits().? * 8, |
| 1995 | 0, // Offset | 2000 | 0, // offset |
| 1996 | ); | | |
| 1997 | }, | | |
| 1998 | .array => { | | |
| 1999 | return o.builder.debugArrayType( | | |
| 2000 | null, // Name | | |
| 2001 | null, // File | | |
| 2002 | null, // Scope | | |
| 2003 | 0, // Line | | |
| 2004 | try o.getDebugType(pt, ty.childType(zcu)), | | |
| 2005 | ty.abiSize(zcu) * 8, | | |
| 2006 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | | |
| 2007 | try o.builder.metadataTuple(&.{ | | |
| 2008 | try o.builder.debugSubrange( | | |
| 2009 | try o.builder.metadataConstant(try o.builder.intConst(.i64, 0)), | | |
| 2010 | try o.builder.metadataConstant(try o.builder.intConst(.i64, ty.arrayLen(zcu))), | | |
| 2011 | ), | | |
| 2012 | }), | | |
| 2013 | ); | 2001 | ); |
| 2014 | }, | 2002 | }, |
| | 2003 | .array => return o.builder.debugArrayType( |
| | 2004 | name, |
| | 2005 | null, // file |
| | 2006 | o.debug_compile_unit.unwrap().?, // scope |
| | 2007 | 0, // line |
| | 2008 | try o.getDebugType(pt, ty.childType(zcu)), |
| | 2009 | ty.abiSize(zcu) * 8, |
| | 2010 | ty.abiAlignment(zcu).toByteUnits().? * 8, |
| | 2011 | try o.builder.metadataTuple(&.{ |
| | 2012 | try o.builder.debugSubrange( |
| | 2013 | try o.builder.metadataConstant(try o.builder.intConst(.i64, 0)), |
| | 2014 | try o.builder.metadataConstant(try o.builder.intConst(.i64, ty.arrayLen(zcu))), |
| | 2015 | ), |
| | 2016 | }), |
| | 2017 | ), |
| 2015 | .vector => { | 2018 | .vector => { |
| 2016 | const elem_ty = ty.childType(zcu); | 2019 | const elem_ty = ty.childType(zcu); |
| 2017 | // Vector elements cannot be padded since that would make | 2020 | // Vector elements cannot be padded since that would make |
| 2018 | // @bitSizOf(elem) * len > @bitSizOf(vec). | 2021 | // @bitSizeOf(elem) * len > @bitSizOf(vec). |
| 2019 | // Neither gdb nor lldb seem to be able to display non-byte sized | 2022 | // Neither gdb nor lldb seem to be able to display non-byte sized |
| 2020 | // vectors properly. | 2023 | // vectors properly. |
| 2021 | const debug_elem_type = switch (elem_ty.zigTypeTag(zcu)) { | 2024 | const debug_elem_type = switch (elem_ty.zigTypeTag(zcu)) { |
| ... | @@ -2027,18 +2030,19 @@ pub const Object = struct { | ... | @@ -2027,18 +2030,19 @@ pub const Object = struct { |
| 2027 | }; | 2030 | }; |
| 2028 | }, | 2031 | }, |
| 2029 | .bool => try o.builder.debugBoolType(try o.builder.metadataString("bool"), 1), | 2032 | .bool => try o.builder.debugBoolType(try o.builder.metadataString("bool"), 1), |
| | 2033 | // We don't pad pointers or floats, so we can lower those normally. |
| 2030 | .pointer, .optional, .float => try o.getDebugType(pt, elem_ty), | 2034 | .pointer, .optional, .float => try o.getDebugType(pt, elem_ty), |
| 2031 | else => unreachable, | 2035 | else => unreachable, |
| 2032 | }; | 2036 | }; |
| 2033 | | 2037 | |
| 2034 | return o.builder.debugVectorType( | 2038 | return o.builder.debugVectorType( |
| 2035 | null, // Name | 2039 | name, |
| 2036 | null, // File | 2040 | null, // file |
| 2037 | null, // Scope | 2041 | o.debug_compile_unit.unwrap().?, // scope |
| 2038 | 0, // Line | 2042 | 0, // line |
| 2039 | debug_elem_type, | 2043 | debug_elem_type, |
| 2040 | ty.abiSize(zcu) * 8, | 2044 | ty.abiSize(zcu) * 8, |
| 2041 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | 2045 | ty.abiAlignment(zcu).toByteUnits().? * 8, |
| 2042 | try o.builder.metadataTuple(&.{ | 2046 | try o.builder.metadataTuple(&.{ |
| 2043 | try o.builder.debugSubrange( | 2047 | try o.builder.debugSubrange( |
| 2044 | try o.builder.metadataConstant(try o.builder.intConst(.i64, 0)), | 2048 | try o.builder.metadataConstant(try o.builder.intConst(.i64, 0)), |
| ... | @@ -2050,26 +2054,15 @@ pub const Object = struct { | ... | @@ -2050,26 +2054,15 @@ pub const Object = struct { |
| 2050 | .optional => { | 2054 | .optional => { |
| 2051 | const payload_ty = ty.optionalChild(zcu); | 2055 | const payload_ty = ty.optionalChild(zcu); |
| 2052 | if (ty.optionalReprIsPayload(zcu)) { | 2056 | if (ty.optionalReprIsPayload(zcu)) { |
| 2053 | // MLUGG TODO: these should use DW_TAG_typedef instead, but std.zig.llvm.Builder currently lacks support for those. | 2057 | return o.builder.debugTypedefType( |
| 2054 | const payload_member = try o.builder.debugMemberType( | | |
| 2055 | try o.builder.metadataString("payload"), | | |
| 2056 | null, // file | | |
| 2057 | ty_fwd_ref, | | |
| 2058 | 0, // line | | |
| 2059 | try o.getDebugType(pt, .anyerror), | | |
| 2060 | ty.abiSize(zcu) * 8, | | |
| 2061 | ty.abiAlignment(zcu).toByteUnits().? * 8, | | |
| 2062 | 0, // offset | | |
| 2063 | ); | | |
| 2064 | return o.builder.debugStructType( | | |
| 2065 | name, | 2058 | name, |
| 2066 | null, // file | 2059 | null, // file |
| 2067 | o.debug_compile_unit.unwrap().?, // scope | 2060 | o.debug_compile_unit.unwrap().?, // scope |
| 2068 | 0, // line | 2061 | 0, // line |
| 2069 | null, // underlying type | 2062 | try o.getDebugType(pt, payload_ty), |
| 2070 | ty.abiSize(zcu) * 8, | 2063 | ty.abiSize(zcu) * 8, |
| 2071 | ty.abiAlignment(zcu).toByteUnits().? * 8, | 2064 | ty.abiAlignment(zcu).toByteUnits().? * 8, |
| 2072 | try o.builder.metadataTuple(&.{payload_member}), | 2065 | 0, // offset |
| 2073 | ); | 2066 | ); |
| 2074 | } | 2067 | } |
| 2075 | | 2068 | |
| ... | @@ -2083,7 +2076,7 @@ pub const Object = struct { | ... | @@ -2083,7 +2076,7 @@ pub const Object = struct { |
| 2083 | const debug_payload_type = try o.builder.debugMemberType( | 2076 | const debug_payload_type = try o.builder.debugMemberType( |
| 2084 | try o.builder.metadataString("payload"), | 2077 | try o.builder.metadataString("payload"), |
| 2085 | null, // file | 2078 | null, // file |
| 2086 | ty_fwd_ref, | 2079 | ty_fwd_ref, // scope |
| 2087 | 0, // line | 2080 | 0, // line |
| 2088 | try o.getDebugType(pt, payload_ty), | 2081 | try o.getDebugType(pt, payload_ty), |
| 2089 | payload_size * 8, | 2082 | payload_size * 8, |
| ... | @@ -2104,12 +2097,12 @@ pub const Object = struct { | ... | @@ -2104,12 +2097,12 @@ pub const Object = struct { |
| 2104 | | 2097 | |
| 2105 | return o.builder.debugStructType( | 2098 | return o.builder.debugStructType( |
| 2106 | name, | 2099 | name, |
| 2107 | null, // File | 2100 | null, // file |
| 2108 | o.debug_compile_unit.unwrap().?, // Scope | 2101 | o.debug_compile_unit.unwrap().?, // scope |
| 2109 | 0, // Line | 2102 | 0, // line |
| 2110 | null, // Underlying type | 2103 | null, // underlying type |
| 2111 | ty.abiSize(zcu) * 8, | 2104 | ty.abiSize(zcu) * 8, |
| 2112 | (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, | 2105 | ty.abiAlignment(zcu).toByteUnits().? * 8, |
| 2113 | try o.builder.metadataTuple(&.{ | 2106 | try o.builder.metadataTuple(&.{ |
| 2114 | debug_payload_type, | 2107 | debug_payload_type, |
| 2115 | debug_some_type, | 2108 | debug_some_type, |
| ... | @@ -2125,30 +2118,29 @@ pub const Object = struct { | ... | @@ -2125,30 +2118,29 @@ pub const Object = struct { |
| 2125 | const payload_size = payload_ty.abiSize(zcu); | 2118 | const payload_size = payload_ty.abiSize(zcu); |
| 2126 | const payload_align = payload_ty.abiAlignment(zcu); | 2119 | const payload_align = payload_ty.abiAlignment(zcu); |
| 2127 | | 2120 | |
| 2128 | const error_index: u1, const payload_index: u1, const error_offset: u64, const payload_offset: u64 = fields: { | 2121 | const error_offset: u64, const payload_offset: u64 = offsets: { |
| 2129 | if (error_align.compare(.gt, payload_align)) { | 2122 | if (error_align.compare(.gt, payload_align)) { |
| 2130 | break :fields .{ 0, 1, 0, payload_align.forward(error_size) }; | 2123 | break :offsets .{ 0, payload_align.forward(error_size) }; |
| 2131 | } else { | 2124 | } else { |
| 2132 | break :fields .{ 1, 0, error_align.forward(payload_size), 0 }; | 2125 | break :offsets .{ error_align.forward(payload_size), 0 }; |
| 2133 | } | 2126 | } |
| 2134 | }; | 2127 | }; |
| 2135 | | 2128 | |
| 2136 | var fields: [2]Builder.Metadata = undefined; | 2129 | const error_field = try o.builder.debugMemberType( |
| 2137 | fields[error_index] = try o.builder.debugMemberType( | | |
| 2138 | try o.builder.metadataString("error"), | 2130 | try o.builder.metadataString("error"), |
| 2139 | null, // File | 2131 | null, // file |
| 2140 | ty_fwd_ref, | 2132 | ty_fwd_ref, |
| 2141 | 0, // Line | 2133 | 0, // line |
| 2142 | try o.getDebugType(pt, error_ty), | 2134 | try o.getDebugType(pt, error_ty), |
| 2143 | error_size * 8, | 2135 | error_size * 8, |
| 2144 | error_align.toByteUnits().? * 8, | 2136 | error_align.toByteUnits().? * 8, |
| 2145 | error_offset * 8, | 2137 | error_offset * 8, |
| 2146 | ); | 2138 | ); |
| 2147 | fields[payload_index] = try o.builder.debugMemberType( | 2139 | const payload_field = try o.builder.debugMemberType( |
| 2148 | try o.builder.metadataString("payload"), | 2140 | try o.builder.metadataString("payload"), |
| 2149 | null, // File | 2141 | null, // file |
| 2150 | ty_fwd_ref, | 2142 | ty_fwd_ref, // scope |
| 2151 | 0, // Line | 2143 | 0, // line |
| 2152 | try o.getDebugType(pt, payload_ty), | 2144 | try o.getDebugType(pt, payload_ty), |
| 2153 | payload_size * 8, | 2145 | payload_size * 8, |
| 2154 | payload_align.toByteUnits().? * 8, | 2146 | payload_align.toByteUnits().? * 8, |
| ... | @@ -2163,32 +2155,21 @@ pub const Object = struct { | ... | @@ -2163,32 +2155,21 @@ pub const Object = struct { |
| 2163 | null, // Underlying type | 2155 | null, // Underlying type |
| 2164 | ty.abiSize(zcu) * 8, | 2156 | ty.abiSize(zcu) * 8, |
| 2165 | ty.abiAlignment(zcu).toByteUnits().? * 8, | 2157 | ty.abiAlignment(zcu).toByteUnits().? * 8, |
| 2166 | try o.builder.metadataTuple(&fields), | 2158 | try o.builder.metadataTuple(&.{ error_field, payload_field }), |
| 2167 | ); | 2159 | ); |
| 2168 | }, | 2160 | }, |
| 2169 | .error_set => { | 2161 | .error_set => { |
| 2170 | assert(ty.toIntern() != .anyerror_type); // handled specially in `updateConst`; will be populated by `emit` instead | 2162 | assert(ty.toIntern() != .anyerror_type); // handled specially in `updateConst`; will be populated by `emit` instead |
| 2171 | // Error sets are just named wrappers around `anyerror`. | 2163 | // Error sets are just named wrappers around `anyerror`. |
| 2172 | // MLUGG TODO: these should use DW_TAG_typedef instead, but std.zig.llvm.Builder currently lacks support for those. | 2164 | return o.builder.debugTypedefType( |
| 2173 | const anyerror_member = try o.builder.debugMemberType( | | |
| 2174 | try o.builder.metadataString("error"), | | |
| 2175 | null, // file | | |
| 2176 | ty_fwd_ref, | | |
| 2177 | 0, // line | | |
| 2178 | try o.getDebugType(pt, .anyerror), | | |
| 2179 | ty.abiSize(zcu) * 8, | | |
| 2180 | ty.abiAlignment(zcu).toByteUnits().? * 8, | | |
| 2181 | 0, // offset | | |
| 2182 | ); | | |
| 2183 | return o.builder.debugStructType( | | |
| 2184 | name, | 2165 | name, |
| 2185 | null, // file | 2166 | null, // file |
| 2186 | o.debug_compile_unit.unwrap().?, // scope | 2167 | o.debug_compile_unit.unwrap().?, // scope |
| 2187 | 0, // line | 2168 | 0, // line |
| 2188 | null, // underlying type | 2169 | try o.getDebugType(pt, .anyerror), |
| 2189 | ty.abiSize(zcu) * 8, | 2170 | ty.abiSize(zcu) * 8, |
| 2190 | ty.abiAlignment(zcu).toByteUnits().? * 8, | 2171 | ty.abiAlignment(zcu).toByteUnits().? * 8, |
| 2191 | try o.builder.metadataTuple(&.{anyerror_member}), | 2172 | 0, // offset |
| 2192 | ); | 2173 | ); |
| 2193 | }, | 2174 | }, |
| 2194 | .@"fn" => { | 2175 | .@"fn" => { |
| ... | @@ -2570,14 +2551,22 @@ pub const Object = struct { | ... | @@ -2570,14 +2551,22 @@ pub const Object = struct { |
| 2570 | const error_set_bits = zcu.errorSetBits(); | 2551 | const error_set_bits = zcu.errorSetBits(); |
| 2571 | const error_names = ip.global_error_set.getNamesFromMainThread(); | 2552 | const error_names = ip.global_error_set.getNamesFromMainThread(); |
| 2572 | | 2553 | |
| 2573 | const enumerators = try gpa.alloc(Builder.Metadata, error_names.len); | 2554 | const enumerators = try gpa.alloc(Builder.Metadata, error_names.len + 1); |
| 2574 | defer gpa.free(enumerators); | 2555 | defer gpa.free(enumerators); |
| 2575 | | 2556 | |
| 2576 | for (enumerators, error_names, 1..) |*out, error_name, error_value| { | 2557 | // The value 0 means "no error" in optionals and error unions. |
| | 2558 | enumerators[0] = try o.builder.debugEnumerator( |
| | 2559 | try o.builder.metadataString("null"), |
| | 2560 | true, // unsigned, |
| | 2561 | error_set_bits, |
| | 2562 | .{ .limbs = &.{0}, .positive = true }, // zero |
| | 2563 | ); |
| | 2564 | |
| | 2565 | for (enumerators[1..], error_names, 1..) |*out, error_name, error_value| { |
| 2577 | var space: Value.BigIntSpace = undefined; | 2566 | var space: Value.BigIntSpace = undefined; |
| 2578 | var bigint: std.math.big.int.Mutable = .init(&space.limbs, error_value); | 2567 | var bigint: std.math.big.int.Mutable = .init(&space.limbs, error_value); |
| 2579 | out.* = try o.builder.debugEnumerator( | 2568 | out.* = try o.builder.debugEnumerator( |
| 2580 | try o.builder.metadataString(error_name.toSlice(ip)), | 2569 | try o.builder.metadataStringFmt("error.{f}", .{error_name.fmtId(ip)}), |
| 2581 | true, // unsigned | 2570 | true, // unsigned |
| 2582 | error_set_bits, | 2571 | error_set_bits, |
| 2583 | bigint.toConst(), | 2572 | bigint.toConst(), |
| ... | @@ -3452,84 +3441,6 @@ pub const Object = struct { | ... | @@ -3452,84 +3441,6 @@ pub const Object = struct { |
| 3452 | ); | 3441 | ); |
| 3453 | } | 3442 | } |
| 3454 | | 3443 | |
| 3455 | fn lowerValueToInt(o: *Object, pt: Zcu.PerThread, llvm_int_ty: Builder.Type, arg_val: InternPool.Index) Error!Builder.Constant { | | |
| 3456 | const zcu = pt.zcu; | | |
| 3457 | const ip = &zcu.intern_pool; | | |
| 3458 | const target = zcu.getTarget(); | | |
| 3459 | | | |
| 3460 | const val = Value.fromInterned(arg_val); | | |
| 3461 | const val_key = ip.indexToKey(val.toIntern()); | | |
| 3462 | | | |
| 3463 | if (val.isUndef(zcu)) return o.builder.undefConst(llvm_int_ty); | | |
| 3464 | | | |
| 3465 | const ty = Type.fromInterned(val_key.typeOf()); | | |
| 3466 | switch (val_key) { | | |
| 3467 | .@"extern" => |@"extern"| { | | |
| 3468 | const function_index = try o.resolveLlvmFunction(pt, @"extern".owner_nav); | | |
| 3469 | const ptr = function_index.ptrConst(&o.builder).global.toConst(); | | |
| 3470 | return o.builder.convConst(ptr, llvm_int_ty); | | |
| 3471 | }, | | |
| 3472 | .func => |func| { | | |
| 3473 | const function_index = try o.resolveLlvmFunction(pt, func.owner_nav); | | |
| 3474 | const ptr = function_index.ptrConst(&o.builder).global.toConst(); | | |
| 3475 | return o.builder.convConst(ptr, llvm_int_ty); | | |
| 3476 | }, | | |
| 3477 | .ptr => return o.builder.convConst(try o.lowerPtr(pt, arg_val, 0), llvm_int_ty), | | |
| 3478 | .aggregate => switch (ip.indexToKey(ty.toIntern())) { | | |
| 3479 | .struct_type, .vector_type => {}, | | |
| 3480 | else => unreachable, | | |
| 3481 | }, | | |
| 3482 | .un => |un| { | | |
| 3483 | const layout = ty.unionGetLayout(zcu); | | |
| 3484 | if (layout.payload_size == 0) return o.lowerValue(pt, un.tag); | | |
| 3485 | | | |
| 3486 | const union_obj = zcu.typeToUnion(ty).?; | | |
| 3487 | const container_layout = union_obj.layout; | | |
| 3488 | | | |
| 3489 | assert(container_layout == .@"packed"); | | |
| 3490 | | | |
| 3491 | var need_unnamed = false; | | |
| 3492 | if (un.tag == .none) { | | |
| 3493 | assert(layout.tag_size == 0); | | |
| 3494 | const union_val = try o.lowerValueToInt(pt, llvm_int_ty, un.val); | | |
| 3495 | | | |
| 3496 | need_unnamed = true; | | |
| 3497 | return union_val; | | |
| 3498 | } | | |
| 3499 | const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?; | | |
| 3500 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | | |
| 3501 | if (!field_ty.hasRuntimeBits(zcu)) return o.builder.intConst(llvm_int_ty, 0); | | |
| 3502 | return o.lowerValueToInt(pt, llvm_int_ty, un.val); | | |
| 3503 | }, | | |
| 3504 | .simple_value => |simple_value| switch (simple_value) { | | |
| 3505 | .false, .true => {}, | | |
| 3506 | else => unreachable, | | |
| 3507 | }, | | |
| 3508 | .int, | | |
| 3509 | .float, | | |
| 3510 | .enum_tag, | | |
| 3511 | => {}, | | |
| 3512 | .opt => {}, // pointer like optional expected | | |
| 3513 | else => unreachable, | | |
| 3514 | } | | |
| 3515 | var stack = std.heap.stackFallback(32, o.gpa); | | |
| 3516 | const allocator = stack.get(); | | |
| 3517 | | | |
| 3518 | const bits: usize = @intCast(ty.bitSize(zcu)); | | |
| 3519 | | | |
| 3520 | const buffer = try allocator.alloc(u8, (bits + 7) / 8); | | |
| 3521 | defer allocator.free(buffer); | | |
| 3522 | const limbs = try allocator.alloc(std.math.big.Limb, std.math.big.int.calcTwosCompLimbCount(bits)); | | |
| 3523 | defer allocator.free(limbs); | | |
| 3524 | | | |
| 3525 | val.writeToPackedMemory(pt, buffer, 0) catch unreachable; | | |
| 3526 | | | |
| 3527 | var big: std.math.big.int.Mutable = .init(limbs, 0); | | |
| 3528 | big.readTwosComplement(buffer, bits, target.cpu.arch.endian(), .unsigned); | | |
| 3529 | | | |
| 3530 | return o.builder.bigIntConst(llvm_int_ty, big.toConst()); | | |
| 3531 | } | | |
| 3532 | | | |
| 3533 | fn lowerValue(o: *Object, pt: Zcu.PerThread, arg_val: InternPool.Index) Error!Builder.Constant { | 3444 | fn lowerValue(o: *Object, pt: Zcu.PerThread, arg_val: InternPool.Index) Error!Builder.Constant { |
| 3534 | const zcu = pt.zcu; | 3445 | const zcu = pt.zcu; |
| 3535 | const ip = &zcu.intern_pool; | 3446 | const ip = &zcu.intern_pool; |