authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-04 15:28:17-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-04 15:28:17-05:00
log42004f9013ba2d06b457f858e0e269ef4ad23554
treeee99dd89c9ce7e7c30a76e7bf0d9f7da7c0c64c7
parentafe3aae582d5051406832e32fc01374f2a0029b7
parenta966275e509670e750ef54a37f7202078aa4cf07

Merge branch 'master' into llvm6


57 files changed, 2602 insertions(+), 1580 deletions(-)

CMakeLists.txt+8-3
......@@ -47,15 +47,20 @@ option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF)
4747option(ZIG_FORCE_EXTERNAL_LLD "If your system has the LLD patches use it instead of the embedded LLD" OFF)
4848
4949find_package(llvm)
50include_directories(${LLVM_INCLUDE_DIRS})
51
5250find_package(clang)
53include_directories(${CLANG_INCLUDE_DIRS})
5451
5552if(ZIG_FORCE_EXTERNAL_LLD)
5653 find_package(lld)
54 include_directories(${LLVM_INCLUDE_DIRS})
5755 include_directories(${LLD_INCLUDE_DIRS})
56 include_directories(${CLANG_INCLUDE_DIRS})
5857else()
58 # This goes first so that we find embedded LLD instead
59 # of system LLD.
60 include_directories("${CMAKE_SOURCE_DIR}/deps/lld/include")
61
62 include_directories(${LLVM_INCLUDE_DIRS})
63 include_directories(${CLANG_INCLUDE_DIRS})
5964 set(EMBEDDED_LLD_LIB_SOURCES
6065 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Driver/DarwinLdDriver.cpp"
6166 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Config/Version.cpp"
c_headers/avx512fintrin.h+229-395
......@@ -4543,37 +4543,6 @@ _mm512_maskz_unpacklo_epi64 (__mmask8 __U, __m512i __A, __m512i __B)
45434543 (__v8di)_mm512_setzero_si512());
45444544}
45454545
4546/* Bit Test */
4547
4548static __inline __mmask16 __DEFAULT_FN_ATTRS
4549_mm512_test_epi32_mask(__m512i __A, __m512i __B)
4550{
4551 return (__mmask16) __builtin_ia32_ptestmd512 ((__v16si) __A,
4552 (__v16si) __B,
4553 (__mmask16) -1);
4554}
4555
4556static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4557_mm512_mask_test_epi32_mask (__mmask16 __U, __m512i __A, __m512i __B)
4558{
4559 return (__mmask16) __builtin_ia32_ptestmd512 ((__v16si) __A,
4560 (__v16si) __B, __U);
4561}
4562
4563static __inline __mmask8 __DEFAULT_FN_ATTRS
4564_mm512_test_epi64_mask(__m512i __A, __m512i __B)
4565{
4566 return (__mmask8) __builtin_ia32_ptestmq512 ((__v8di) __A,
4567 (__v8di) __B,
4568 (__mmask8) -1);
4569}
4570
4571static __inline__ __mmask8 __DEFAULT_FN_ATTRS
4572_mm512_mask_test_epi64_mask (__mmask8 __U, __m512i __A, __m512i __B)
4573{
4574 return (__mmask8) __builtin_ia32_ptestmq512 ((__v8di) __A, (__v8di) __B, __U);
4575}
4576
45774546
45784547/* SIMD load ops */
45794548
......@@ -4844,293 +4813,105 @@ _mm512_knot(__mmask16 __M)
48444813
48454814/* Integer compare */
48464815
4847static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4848_mm512_cmpeq_epi32_mask(__m512i __a, __m512i __b) {
4849 return (__mmask16)__builtin_ia32_pcmpeqd512_mask((__v16si)__a, (__v16si)__b,
4850 (__mmask16)-1);
4851}
4852
4853static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4854_mm512_mask_cmpeq_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) {
4855 return (__mmask16)__builtin_ia32_pcmpeqd512_mask((__v16si)__a, (__v16si)__b,
4856 __u);
4857}
4858
4859static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4860_mm512_cmpeq_epu32_mask(__m512i __a, __m512i __b) {
4861 return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 0,
4862 (__mmask16)-1);
4863}
4864
4865static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4866_mm512_mask_cmpeq_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) {
4867 return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 0,
4868 __u);
4869}
4870
4871static __inline__ __mmask8 __DEFAULT_FN_ATTRS
4872_mm512_mask_cmpeq_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) {
4873 return (__mmask8)__builtin_ia32_pcmpeqq512_mask((__v8di)__a, (__v8di)__b,
4874 __u);
4875}
4876
4877static __inline__ __mmask8 __DEFAULT_FN_ATTRS
4878_mm512_cmpeq_epi64_mask(__m512i __a, __m512i __b) {
4879 return (__mmask8)__builtin_ia32_pcmpeqq512_mask((__v8di)__a, (__v8di)__b,
4880 (__mmask8)-1);
4881}
4882
4883static __inline__ __mmask8 __DEFAULT_FN_ATTRS
4884_mm512_cmpeq_epu64_mask(__m512i __a, __m512i __b) {
4885 return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 0,
4886 (__mmask8)-1);
4887}
4888
4889static __inline__ __mmask8 __DEFAULT_FN_ATTRS
4890_mm512_mask_cmpeq_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) {
4891 return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 0,
4892 __u);
4893}
4894
4895static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4896_mm512_cmpge_epi32_mask(__m512i __a, __m512i __b) {
4897 return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 5,
4898 (__mmask16)-1);
4899}
4900
4901static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4902_mm512_mask_cmpge_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) {
4903 return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 5,
4904 __u);
4905}
4906
4907static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4908_mm512_cmpge_epu32_mask(__m512i __a, __m512i __b) {
4909 return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 5,
4910 (__mmask16)-1);
4911}
4912
4913static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4914_mm512_mask_cmpge_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) {
4915 return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 5,
4916 __u);
4917}
4918
4919static __inline__ __mmask8 __DEFAULT_FN_ATTRS
4920_mm512_cmpge_epi64_mask(__m512i __a, __m512i __b) {
4921 return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 5,
4922 (__mmask8)-1);
4923}
4924
4925static __inline__ __mmask8 __DEFAULT_FN_ATTRS
4926_mm512_mask_cmpge_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) {
4927 return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 5,
4928 __u);
4929}
4930
4931static __inline__ __mmask8 __DEFAULT_FN_ATTRS
4932_mm512_cmpge_epu64_mask(__m512i __a, __m512i __b) {
4933 return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 5,
4934 (__mmask8)-1);
4935}
4936
4937static __inline__ __mmask8 __DEFAULT_FN_ATTRS
4938_mm512_mask_cmpge_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) {
4939 return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 5,
4940 __u);
4941}
4942
4943static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4944_mm512_cmpgt_epi32_mask(__m512i __a, __m512i __b) {
4945 return (__mmask16)__builtin_ia32_pcmpgtd512_mask((__v16si)__a, (__v16si)__b,
4946 (__mmask16)-1);
4947}
4948
4949static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4950_mm512_mask_cmpgt_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) {
4951 return (__mmask16)__builtin_ia32_pcmpgtd512_mask((__v16si)__a, (__v16si)__b,
4952 __u);
4953}
4954
4955static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4956_mm512_cmpgt_epu32_mask(__m512i __a, __m512i __b) {
4957 return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 6,
4958 (__mmask16)-1);
4959}
4960
4961static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4962_mm512_mask_cmpgt_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) {
4963 return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 6,
4964 __u);
4965}
4966
4967static __inline__ __mmask8 __DEFAULT_FN_ATTRS
4968_mm512_mask_cmpgt_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) {
4969 return (__mmask8)__builtin_ia32_pcmpgtq512_mask((__v8di)__a, (__v8di)__b,
4970 __u);
4971}
4972
4973static __inline__ __mmask8 __DEFAULT_FN_ATTRS
4974_mm512_cmpgt_epi64_mask(__m512i __a, __m512i __b) {
4975 return (__mmask8)__builtin_ia32_pcmpgtq512_mask((__v8di)__a, (__v8di)__b,
4976 (__mmask8)-1);
4977}
4978
4979static __inline__ __mmask8 __DEFAULT_FN_ATTRS
4980_mm512_cmpgt_epu64_mask(__m512i __a, __m512i __b) {
4981 return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 6,
4982 (__mmask8)-1);
4983}
4984
4985static __inline__ __mmask8 __DEFAULT_FN_ATTRS
4986_mm512_mask_cmpgt_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) {
4987 return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 6,
4988 __u);
4989}
4990
4991static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4992_mm512_cmple_epi32_mask(__m512i __a, __m512i __b) {
4993 return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 2,
4994 (__mmask16)-1);
4995}
4996
4997static __inline__ __mmask16 __DEFAULT_FN_ATTRS
4998_mm512_mask_cmple_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) {
4999 return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 2,
5000 __u);
5001}
5002
5003static __inline__ __mmask16 __DEFAULT_FN_ATTRS
5004_mm512_cmple_epu32_mask(__m512i __a, __m512i __b) {
5005 return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 2,
5006 (__mmask16)-1);
5007}
5008
5009static __inline__ __mmask16 __DEFAULT_FN_ATTRS
5010_mm512_mask_cmple_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) {
5011 return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 2,
5012 __u);
5013}
5014
5015static __inline__ __mmask8 __DEFAULT_FN_ATTRS
5016_mm512_cmple_epi64_mask(__m512i __a, __m512i __b) {
5017 return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 2,
5018 (__mmask8)-1);
5019}
5020
5021static __inline__ __mmask8 __DEFAULT_FN_ATTRS
5022_mm512_mask_cmple_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) {
5023 return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 2,
5024 __u);
5025}
5026
5027static __inline__ __mmask8 __DEFAULT_FN_ATTRS
5028_mm512_cmple_epu64_mask(__m512i __a, __m512i __b) {
5029 return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 2,
5030 (__mmask8)-1);
5031}
5032
5033static __inline__ __mmask8 __DEFAULT_FN_ATTRS
5034_mm512_mask_cmple_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) {
5035 return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 2,
5036 __u);
5037}
5038
5039static __inline__ __mmask16 __DEFAULT_FN_ATTRS
5040_mm512_cmplt_epi32_mask(__m512i __a, __m512i __b) {
5041 return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 1,
5042 (__mmask16)-1);
5043}
5044
5045static __inline__ __mmask16 __DEFAULT_FN_ATTRS
5046_mm512_mask_cmplt_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) {
5047 return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 1,
5048 __u);
5049}
5050
5051static __inline__ __mmask16 __DEFAULT_FN_ATTRS
5052_mm512_cmplt_epu32_mask(__m512i __a, __m512i __b) {
5053 return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 1,
5054 (__mmask16)-1);
5055}
5056
5057static __inline__ __mmask16 __DEFAULT_FN_ATTRS
5058_mm512_mask_cmplt_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) {
5059 return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 1,
5060 __u);
5061}
5062
5063static __inline__ __mmask8 __DEFAULT_FN_ATTRS
5064_mm512_cmplt_epi64_mask(__m512i __a, __m512i __b) {
5065 return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 1,
5066 (__mmask8)-1);
5067}
5068
5069static __inline__ __mmask8 __DEFAULT_FN_ATTRS
5070_mm512_mask_cmplt_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) {
5071 return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 1,
5072 __u);
5073}
5074
5075static __inline__ __mmask8 __DEFAULT_FN_ATTRS
5076_mm512_cmplt_epu64_mask(__m512i __a, __m512i __b) {
5077 return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 1,
5078 (__mmask8)-1);
5079}
5080
5081static __inline__ __mmask8 __DEFAULT_FN_ATTRS
5082_mm512_mask_cmplt_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) {
5083 return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 1,
5084 __u);
5085}
5086
5087static __inline__ __mmask16 __DEFAULT_FN_ATTRS
5088_mm512_cmpneq_epi32_mask(__m512i __a, __m512i __b) {
5089 return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 4,
5090 (__mmask16)-1);
5091}
5092
5093static __inline__ __mmask16 __DEFAULT_FN_ATTRS
5094_mm512_mask_cmpneq_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) {
5095 return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 4,
5096 __u);
5097}
5098
5099static __inline__ __mmask16 __DEFAULT_FN_ATTRS
5100_mm512_cmpneq_epu32_mask(__m512i __a, __m512i __b) {
5101 return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 4,
5102 (__mmask16)-1);
5103}
5104
5105static __inline__ __mmask16 __DEFAULT_FN_ATTRS
5106_mm512_mask_cmpneq_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) {
5107 return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 4,
5108 __u);
5109}
5110
5111static __inline__ __mmask8 __DEFAULT_FN_ATTRS
5112_mm512_cmpneq_epi64_mask(__m512i __a, __m512i __b) {
5113 return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 4,
5114 (__mmask8)-1);
5115}
5116
5117static __inline__ __mmask8 __DEFAULT_FN_ATTRS
5118_mm512_mask_cmpneq_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) {
5119 return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 4,
5120 __u);
5121}
5122
5123static __inline__ __mmask8 __DEFAULT_FN_ATTRS
5124_mm512_cmpneq_epu64_mask(__m512i __a, __m512i __b) {
5125 return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 4,
5126 (__mmask8)-1);
5127}
5128
5129static __inline__ __mmask8 __DEFAULT_FN_ATTRS
5130_mm512_mask_cmpneq_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) {
5131 return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 4,
5132 __u);
5133}
4816#define _mm512_cmpeq_epi32_mask(A, B) \
4817 _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_EQ)
4818#define _mm512_mask_cmpeq_epi32_mask(k, A, B) \
4819 _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_EQ)
4820#define _mm512_cmpge_epi32_mask(A, B) \
4821 _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_GE)
4822#define _mm512_mask_cmpge_epi32_mask(k, A, B) \
4823 _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GE)
4824#define _mm512_cmpgt_epi32_mask(A, B) \
4825 _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_GT)
4826#define _mm512_mask_cmpgt_epi32_mask(k, A, B) \
4827 _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GT)
4828#define _mm512_cmple_epi32_mask(A, B) \
4829 _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_LE)
4830#define _mm512_mask_cmple_epi32_mask(k, A, B) \
4831 _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LE)
4832#define _mm512_cmplt_epi32_mask(A, B) \
4833 _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_LT)
4834#define _mm512_mask_cmplt_epi32_mask(k, A, B) \
4835 _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LT)
4836#define _mm512_cmpneq_epi32_mask(A, B) \
4837 _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_NE)
4838#define _mm512_mask_cmpneq_epi32_mask(k, A, B) \
4839 _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_NE)
4840
4841#define _mm512_cmpeq_epu32_mask(A, B) \
4842 _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_EQ)
4843#define _mm512_mask_cmpeq_epu32_mask(k, A, B) \
4844 _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_EQ)
4845#define _mm512_cmpge_epu32_mask(A, B) \
4846 _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_GE)
4847#define _mm512_mask_cmpge_epu32_mask(k, A, B) \
4848 _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GE)
4849#define _mm512_cmpgt_epu32_mask(A, B) \
4850 _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_GT)
4851#define _mm512_mask_cmpgt_epu32_mask(k, A, B) \
4852 _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GT)
4853#define _mm512_cmple_epu32_mask(A, B) \
4854 _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_LE)
4855#define _mm512_mask_cmple_epu32_mask(k, A, B) \
4856 _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LE)
4857#define _mm512_cmplt_epu32_mask(A, B) \
4858 _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_LT)
4859#define _mm512_mask_cmplt_epu32_mask(k, A, B) \
4860 _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LT)
4861#define _mm512_cmpneq_epu32_mask(A, B) \
4862 _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_NE)
4863#define _mm512_mask_cmpneq_epu32_mask(k, A, B) \
4864 _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_NE)
4865
4866#define _mm512_cmpeq_epi64_mask(A, B) \
4867 _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_EQ)
4868#define _mm512_mask_cmpeq_epi64_mask(k, A, B) \
4869 _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_EQ)
4870#define _mm512_cmpge_epi64_mask(A, B) \
4871 _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_GE)
4872#define _mm512_mask_cmpge_epi64_mask(k, A, B) \
4873 _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GE)
4874#define _mm512_cmpgt_epi64_mask(A, B) \
4875 _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_GT)
4876#define _mm512_mask_cmpgt_epi64_mask(k, A, B) \
4877 _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GT)
4878#define _mm512_cmple_epi64_mask(A, B) \
4879 _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_LE)
4880#define _mm512_mask_cmple_epi64_mask(k, A, B) \
4881 _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LE)
4882#define _mm512_cmplt_epi64_mask(A, B) \
4883 _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_LT)
4884#define _mm512_mask_cmplt_epi64_mask(k, A, B) \
4885 _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LT)
4886#define _mm512_cmpneq_epi64_mask(A, B) \
4887 _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_NE)
4888#define _mm512_mask_cmpneq_epi64_mask(k, A, B) \
4889 _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_NE)
4890
4891#define _mm512_cmpeq_epu64_mask(A, B) \
4892 _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_EQ)
4893#define _mm512_mask_cmpeq_epu64_mask(k, A, B) \
4894 _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_EQ)
4895#define _mm512_cmpge_epu64_mask(A, B) \
4896 _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_GE)
4897#define _mm512_mask_cmpge_epu64_mask(k, A, B) \
4898 _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GE)
4899#define _mm512_cmpgt_epu64_mask(A, B) \
4900 _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_GT)
4901#define _mm512_mask_cmpgt_epu64_mask(k, A, B) \
4902 _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GT)
4903#define _mm512_cmple_epu64_mask(A, B) \
4904 _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_LE)
4905#define _mm512_mask_cmple_epu64_mask(k, A, B) \
4906 _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LE)
4907#define _mm512_cmplt_epu64_mask(A, B) \
4908 _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_LT)
4909#define _mm512_mask_cmplt_epu64_mask(k, A, B) \
4910 _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LT)
4911#define _mm512_cmpneq_epu64_mask(A, B) \
4912 _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_NE)
4913#define _mm512_mask_cmpneq_epu64_mask(k, A, B) \
4914 _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_NE)
51344915
51354916static __inline__ __m512i __DEFAULT_FN_ATTRS
51364917_mm512_cvtepi8_epi32(__m128i __A)
......@@ -6797,35 +6578,6 @@ _mm512_maskz_permutex2var_ps (__mmask16 __U, __m512 __A, __m512i __I,
67976578 (__mmask16) __U);
67986579}
67996580
6800static __inline__ __mmask16 __DEFAULT_FN_ATTRS
6801_mm512_testn_epi32_mask (__m512i __A, __m512i __B)
6802{
6803 return (__mmask16) __builtin_ia32_ptestnmd512 ((__v16si) __A,
6804 (__v16si) __B,
6805 (__mmask16) -1);
6806}
6807
6808static __inline__ __mmask16 __DEFAULT_FN_ATTRS
6809_mm512_mask_testn_epi32_mask (__mmask16 __U, __m512i __A, __m512i __B)
6810{
6811 return (__mmask16) __builtin_ia32_ptestnmd512 ((__v16si) __A,
6812 (__v16si) __B, __U);
6813}
6814
6815static __inline__ __mmask8 __DEFAULT_FN_ATTRS
6816_mm512_testn_epi64_mask (__m512i __A, __m512i __B)
6817{
6818 return (__mmask8) __builtin_ia32_ptestnmq512 ((__v8di) __A,
6819 (__v8di) __B,
6820 (__mmask8) -1);
6821}
6822
6823static __inline__ __mmask8 __DEFAULT_FN_ATTRS
6824_mm512_mask_testn_epi64_mask (__mmask8 __U, __m512i __A, __m512i __B)
6825{
6826 return (__mmask8) __builtin_ia32_ptestnmq512 ((__v8di) __A,
6827 (__v8di) __B, __U);
6828}
68296581
68306582#define _mm512_cvtt_roundpd_epu32(A, R) __extension__ ({ \
68316583 (__m256i)__builtin_ia32_cvttpd2udq512_mask((__v8df)(__m512d)(A), \
......@@ -7194,76 +6946,100 @@ _mm512_maskz_srai_epi64(__mmask8 __U, __m512i __A, int __B)
71946946}
71956947
71966948#define _mm512_shuffle_f32x4(A, B, imm) __extension__ ({ \
7197 (__m512)__builtin_ia32_shuf_f32x4_mask((__v16sf)(__m512)(A), \
7198 (__v16sf)(__m512)(B), (int)(imm), \
7199 (__v16sf)_mm512_undefined_ps(), \
7200 (__mmask16)-1); })
6949 (__m512)__builtin_shufflevector((__v16sf)(__m512)(A), \
6950 (__v16sf)(__m512)(B), \
6951 0 + ((((imm) >> 0) & 0x3) * 4), \
6952 1 + ((((imm) >> 0) & 0x3) * 4), \
6953 2 + ((((imm) >> 0) & 0x3) * 4), \
6954 3 + ((((imm) >> 0) & 0x3) * 4), \
6955 0 + ((((imm) >> 2) & 0x3) * 4), \
6956 1 + ((((imm) >> 2) & 0x3) * 4), \
6957 2 + ((((imm) >> 2) & 0x3) * 4), \
6958 3 + ((((imm) >> 2) & 0x3) * 4), \
6959 16 + ((((imm) >> 4) & 0x3) * 4), \
6960 17 + ((((imm) >> 4) & 0x3) * 4), \
6961 18 + ((((imm) >> 4) & 0x3) * 4), \
6962 19 + ((((imm) >> 4) & 0x3) * 4), \
6963 16 + ((((imm) >> 6) & 0x3) * 4), \
6964 17 + ((((imm) >> 6) & 0x3) * 4), \
6965 18 + ((((imm) >> 6) & 0x3) * 4), \
6966 19 + ((((imm) >> 6) & 0x3) * 4)); })
72016967
72026968#define _mm512_mask_shuffle_f32x4(W, U, A, B, imm) __extension__ ({ \
7203 (__m512)__builtin_ia32_shuf_f32x4_mask((__v16sf)(__m512)(A), \
7204 (__v16sf)(__m512)(B), (int)(imm), \
7205 (__v16sf)(__m512)(W), \
7206 (__mmask16)(U)); })
6969 (__m512)__builtin_ia32_selectps_512((__mmask16)(U), \
6970 (__v16sf)_mm512_shuffle_f32x4((A), (B), (imm)), \
6971 (__v16sf)(__m512)(W)); })
72076972
72086973#define _mm512_maskz_shuffle_f32x4(U, A, B, imm) __extension__ ({ \
7209 (__m512)__builtin_ia32_shuf_f32x4_mask((__v16sf)(__m512)(A), \
7210 (__v16sf)(__m512)(B), (int)(imm), \
7211 (__v16sf)_mm512_setzero_ps(), \
7212 (__mmask16)(U)); })
6974 (__m512)__builtin_ia32_selectps_512((__mmask16)(U), \
6975 (__v16sf)_mm512_shuffle_f32x4((A), (B), (imm)), \
6976 (__v16sf)_mm512_setzero_ps()); })
72136977
72146978#define _mm512_shuffle_f64x2(A, B, imm) __extension__ ({ \
7215 (__m512d)__builtin_ia32_shuf_f64x2_mask((__v8df)(__m512d)(A), \
7216 (__v8df)(__m512d)(B), (int)(imm), \
7217 (__v8df)_mm512_undefined_pd(), \
7218 (__mmask8)-1); })
6979 (__m512d)__builtin_shufflevector((__v8df)(__m512d)(A), \
6980 (__v8df)(__m512d)(B), \
6981 0 + ((((imm) >> 0) & 0x3) * 2), \
6982 1 + ((((imm) >> 0) & 0x3) * 2), \
6983 0 + ((((imm) >> 2) & 0x3) * 2), \
6984 1 + ((((imm) >> 2) & 0x3) * 2), \
6985 8 + ((((imm) >> 4) & 0x3) * 2), \
6986 9 + ((((imm) >> 4) & 0x3) * 2), \
6987 8 + ((((imm) >> 6) & 0x3) * 2), \
6988 9 + ((((imm) >> 6) & 0x3) * 2)); })
72196989
72206990#define _mm512_mask_shuffle_f64x2(W, U, A, B, imm) __extension__ ({ \
7221 (__m512d)__builtin_ia32_shuf_f64x2_mask((__v8df)(__m512d)(A), \
7222 (__v8df)(__m512d)(B), (int)(imm), \
7223 (__v8df)(__m512d)(W), \
7224 (__mmask8)(U)); })
6991 (__m512d)__builtin_ia32_selectpd_512((__mmask8)(U), \
6992 (__v8df)_mm512_shuffle_f64x2((A), (B), (imm)), \
6993 (__v8df)(__m512d)(W)); })
72256994
72266995#define _mm512_maskz_shuffle_f64x2(U, A, B, imm) __extension__ ({ \
7227 (__m512d)__builtin_ia32_shuf_f64x2_mask((__v8df)(__m512d)(A), \
7228 (__v8df)(__m512d)(B), (int)(imm), \
7229 (__v8df)_mm512_setzero_pd(), \
7230 (__mmask8)(U)); })
6996 (__m512d)__builtin_ia32_selectpd_512((__mmask8)(U), \
6997 (__v8df)_mm512_shuffle_f64x2((A), (B), (imm)), \
6998 (__v8df)_mm512_setzero_pd()); })
72316999
72327000#define _mm512_shuffle_i32x4(A, B, imm) __extension__ ({ \
7233 (__m512i)__builtin_ia32_shuf_i32x4_mask((__v16si)(__m512i)(A), \
7234 (__v16si)(__m512i)(B), (int)(imm), \
7235 (__v16si)_mm512_setzero_si512(), \
7236 (__mmask16)-1); })
7001 (__m512i)__builtin_shufflevector((__v8di)(__m512i)(A), \
7002 (__v8di)(__m512i)(B), \
7003 0 + ((((imm) >> 0) & 0x3) * 2), \
7004 1 + ((((imm) >> 0) & 0x3) * 2), \
7005 0 + ((((imm) >> 2) & 0x3) * 2), \
7006 1 + ((((imm) >> 2) & 0x3) * 2), \
7007 8 + ((((imm) >> 4) & 0x3) * 2), \
7008 9 + ((((imm) >> 4) & 0x3) * 2), \
7009 8 + ((((imm) >> 6) & 0x3) * 2), \
7010 9 + ((((imm) >> 6) & 0x3) * 2)); })
72377011
72387012#define _mm512_mask_shuffle_i32x4(W, U, A, B, imm) __extension__ ({ \
7239 (__m512i)__builtin_ia32_shuf_i32x4_mask((__v16si)(__m512i)(A), \
7240 (__v16si)(__m512i)(B), (int)(imm), \
7241 (__v16si)(__m512i)(W), \
7242 (__mmask16)(U)); })
7013 (__m512i)__builtin_ia32_selectd_512((__mmask16)(U), \
7014 (__v16si)_mm512_shuffle_i32x4((A), (B), (imm)), \
7015 (__v16si)(__m512i)(W)); })
72437016
72447017#define _mm512_maskz_shuffle_i32x4(U, A, B, imm) __extension__ ({ \
7245 (__m512i)__builtin_ia32_shuf_i32x4_mask((__v16si)(__m512i)(A), \
7246 (__v16si)(__m512i)(B), (int)(imm), \
7247 (__v16si)_mm512_setzero_si512(), \
7248 (__mmask16)(U)); })
7018 (__m512i)__builtin_ia32_selectd_512((__mmask16)(U), \
7019 (__v16si)_mm512_shuffle_i32x4((A), (B), (imm)), \
7020 (__v16si)_mm512_setzero_si512()); })
72497021
72507022#define _mm512_shuffle_i64x2(A, B, imm) __extension__ ({ \
7251 (__m512i)__builtin_ia32_shuf_i64x2_mask((__v8di)(__m512i)(A), \
7252 (__v8di)(__m512i)(B), (int)(imm), \
7253 (__v8di)_mm512_setzero_si512(), \
7254 (__mmask8)-1); })
7023 (__m512i)__builtin_shufflevector((__v8di)(__m512i)(A), \
7024 (__v8di)(__m512i)(B), \
7025 0 + ((((imm) >> 0) & 0x3) * 2), \
7026 1 + ((((imm) >> 0) & 0x3) * 2), \
7027 0 + ((((imm) >> 2) & 0x3) * 2), \
7028 1 + ((((imm) >> 2) & 0x3) * 2), \
7029 8 + ((((imm) >> 4) & 0x3) * 2), \
7030 9 + ((((imm) >> 4) & 0x3) * 2), \
7031 8 + ((((imm) >> 6) & 0x3) * 2), \
7032 9 + ((((imm) >> 6) & 0x3) * 2)); })
72557033
72567034#define _mm512_mask_shuffle_i64x2(W, U, A, B, imm) __extension__ ({ \
7257 (__m512i)__builtin_ia32_shuf_i64x2_mask((__v8di)(__m512i)(A), \
7258 (__v8di)(__m512i)(B), (int)(imm), \
7259 (__v8di)(__m512i)(W), \
7260 (__mmask8)(U)); })
7035 (__m512i)__builtin_ia32_selectq_512((__mmask8)(U), \
7036 (__v8di)_mm512_shuffle_i64x2((A), (B), (imm)), \
7037 (__v8di)(__m512i)(W)); })
72617038
72627039#define _mm512_maskz_shuffle_i64x2(U, A, B, imm) __extension__ ({ \
7263 (__m512i)__builtin_ia32_shuf_i64x2_mask((__v8di)(__m512i)(A), \
7264 (__v8di)(__m512i)(B), (int)(imm), \
7265 (__v8di)_mm512_setzero_si512(), \
7266 (__mmask8)(U)); })
7040 (__m512i)__builtin_ia32_selectq_512((__mmask8)(U), \
7041 (__v8di)_mm512_shuffle_i64x2((A), (B), (imm)), \
7042 (__v8di)_mm512_setzero_si512()); })
72677043
72687044#define _mm512_shuffle_pd(A, B, M) __extension__ ({ \
72697045 (__m512d)__builtin_shufflevector((__v8df)(__m512d)(A), \
......@@ -9166,6 +8942,64 @@ _mm512_maskz_compress_epi32 (__mmask16 __U, __m512i __A)
91668942 (__mmask8)(M), \
91678943 _MM_FROUND_CUR_DIRECTION); })
91688944
8945/* Bit Test */
8946
8947static __inline __mmask16 __DEFAULT_FN_ATTRS
8948_mm512_test_epi32_mask (__m512i __A, __m512i __B)
8949{
8950 return _mm512_cmpneq_epi32_mask (_mm512_and_epi32(__A, __B),
8951 _mm512_setzero_epi32());
8952}
8953
8954static __inline__ __mmask16 __DEFAULT_FN_ATTRS
8955_mm512_mask_test_epi32_mask (__mmask16 __U, __m512i __A, __m512i __B)
8956{
8957 return _mm512_mask_cmpneq_epi32_mask (__U, _mm512_and_epi32 (__A, __B),
8958 _mm512_setzero_epi32());
8959}
8960
8961static __inline __mmask8 __DEFAULT_FN_ATTRS
8962_mm512_test_epi64_mask (__m512i __A, __m512i __B)
8963{
8964 return _mm512_cmpneq_epi64_mask (_mm512_and_epi32 (__A, __B),
8965 _mm512_setzero_epi32());
8966}
8967
8968static __inline__ __mmask8 __DEFAULT_FN_ATTRS
8969_mm512_mask_test_epi64_mask (__mmask8 __U, __m512i __A, __m512i __B)
8970{
8971 return _mm512_mask_cmpneq_epi64_mask (__U, _mm512_and_epi32 (__A, __B),
8972 _mm512_setzero_epi32());
8973}
8974
8975static __inline__ __mmask16 __DEFAULT_FN_ATTRS
8976_mm512_testn_epi32_mask (__m512i __A, __m512i __B)
8977{
8978 return _mm512_cmpeq_epi32_mask (_mm512_and_epi32 (__A, __B),
8979 _mm512_setzero_epi32());
8980}
8981
8982static __inline__ __mmask16 __DEFAULT_FN_ATTRS
8983_mm512_mask_testn_epi32_mask (__mmask16 __U, __m512i __A, __m512i __B)
8984{
8985 return _mm512_mask_cmpeq_epi32_mask (__U, _mm512_and_epi32 (__A, __B),
8986 _mm512_setzero_epi32());
8987}
8988
8989static __inline__ __mmask8 __DEFAULT_FN_ATTRS
8990_mm512_testn_epi64_mask (__m512i __A, __m512i __B)
8991{
8992 return _mm512_cmpeq_epi64_mask (_mm512_and_epi32 (__A, __B),
8993 _mm512_setzero_epi32());
8994}
8995
8996static __inline__ __mmask8 __DEFAULT_FN_ATTRS
8997_mm512_mask_testn_epi64_mask (__mmask8 __U, __m512i __A, __m512i __B)
8998{
8999 return _mm512_mask_cmpeq_epi64_mask (__U, _mm512_and_epi32 (__A, __B),
9000 _mm512_setzero_epi32());
9001}
9002
91699003static __inline__ __m512 __DEFAULT_FN_ATTRS
91709004_mm512_movehdup_ps (__m512 __A)
91719005{
deps/lld-prebuilt/lld/Config/Version.inc+2-2
......@@ -1,5 +1,5 @@
1#define LLD_VERSION 5.0.0
2#define LLD_VERSION_STRING "5.0.0"
1#define LLD_VERSION 5.0.1
2#define LLD_VERSION_STRING "5.0.1"
33#define LLD_VERSION_MAJOR 5
44#define LLD_VERSION_MINOR 0
55#define LLD_REVISION_STRING ""
deps/lld/COFF/Config.h+1
......@@ -157,6 +157,7 @@ struct Configuration {
157157 uint32_t MinorImageVersion = 0;
158158 uint32_t MajorOSVersion = 6;
159159 uint32_t MinorOSVersion = 0;
160 bool CanExitEarly = false;
160161 bool DynamicBase = true;
161162 bool NxCompat = true;
162163 bool AllowIsolation = true;
deps/lld/COFF/Driver.cpp+8-2
......@@ -52,15 +52,21 @@ BumpPtrAllocator BAlloc;
5252StringSaver Saver{BAlloc};
5353std::vector<SpecificAllocBase *> SpecificAllocBase::Instances;
5454
55bool link(ArrayRef<const char *> Args, raw_ostream &Diag) {
55bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) {
5656 ErrorCount = 0;
5757 ErrorOS = &Diag;
5858 Config = make<Configuration>();
5959 Config->Argv = {Args.begin(), Args.end()};
6060 Config->ColorDiagnostics =
6161 (ErrorOS == &llvm::errs() && Process::StandardErrHasColors());
62 Config->CanExitEarly = CanExitEarly;
6263 Driver = make<LinkerDriver>();
6364 Driver->link(Args);
65
66 // Call exit() if we can to avoid calling destructors.
67 if (CanExitEarly)
68 exitLld(ErrorCount ? 1 : 0);
69
6470 freeArena();
6571 return !ErrorCount;
6672}
......@@ -1123,7 +1129,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
11231129 // This is useful because MSVC link.exe can generate complete PDBs.
11241130 if (Args.hasArg(OPT_msvclto)) {
11251131 invokeMSVC(Args);
1126 exit(0);
1132 return;
11271133 }
11281134
11291135 // Do LTO by compiling bitcode input files to a set of native COFF files then
deps/lld/COFF/Error.cpp+3-2
......@@ -32,7 +32,7 @@ namespace coff {
3232uint64_t ErrorCount;
3333raw_ostream *ErrorOS;
3434
35static LLVM_ATTRIBUTE_NORETURN void exitLld(int Val) {
35LLVM_ATTRIBUTE_NORETURN void exitLld(int Val) {
3636 // Dealloc/destroy ManagedStatic variables before calling
3737 // _exit(). In a non-LTO build, this is a nop. In an LTO
3838 // build allows us to get the output of -time-passes.
......@@ -78,7 +78,8 @@ void error(const Twine &Msg) {
7878 print("error: ", raw_ostream::RED);
7979 *ErrorOS << "too many errors emitted, stopping now"
8080 << " (use /ERRORLIMIT:0 to see all errors)\n";
81 exitLld(1);
81 if (Config->CanExitEarly)
82 exitLld(1);
8283 }
8384
8485 ++ErrorCount;
deps/lld/COFF/Error.h+2
......@@ -27,6 +27,8 @@ LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
2727LLVM_ATTRIBUTE_NORETURN void fatal(std::error_code EC, const Twine &Prefix);
2828LLVM_ATTRIBUTE_NORETURN void fatal(llvm::Error &Err, const Twine &Prefix);
2929
30LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
31
3032template <class T> T check(ErrorOr<T> V, const Twine &Prefix) {
3133 if (auto EC = V.getError())
3234 fatal(EC, Prefix);
deps/lld/ELF/SyntheticSections.cpp+9-3
......@@ -427,10 +427,11 @@ CieRecord *EhFrameSection<ELFT>::addCie(EhSectionPiece &Piece,
427427 &Sec->template getFile<ELFT>()->getRelocTargetSym(Rels[FirstRelI]);
428428
429429 // Search for an existing CIE by CIE contents/relocation target pair.
430 CieRecord *Cie = &CieMap[{Piece.data(), Personality}];
430 CieRecord *&Cie = CieMap[{Piece.data(), Personality}];
431431
432432 // If not found, create a new one.
433 if (Cie->Piece == nullptr) {
433 if (!Cie) {
434 Cie = make<CieRecord>();
434435 Cie->Piece = &Piece;
435436 Cies.push_back(Cie);
436437 }
......@@ -522,9 +523,14 @@ template <class ELFT>
522523static void writeCieFde(uint8_t *Buf, ArrayRef<uint8_t> D) {
523524 memcpy(Buf, D.data(), D.size());
524525
526 size_t Aligned = alignTo(D.size(), sizeof(typename ELFT::uint));
527
528 // Zero-clear trailing padding if it exists.
529 memset(Buf + D.size(), 0, Aligned - D.size());
530
525531 // Fix the size field. -4 since size does not include the size field itself.
526532 const endianness E = ELFT::TargetEndianness;
527 write32<E>(Buf, alignTo(D.size(), sizeof(typename ELFT::uint)) - 4);
533 write32<E>(Buf, Aligned - 4);
528534}
529535
530536template <class ELFT> void EhFrameSection<ELFT>::finalizeContents() {
deps/lld/ELF/SyntheticSections.h+2-1
......@@ -103,7 +103,8 @@ private:
103103 std::vector<CieRecord *> Cies;
104104
105105 // CIE records are uniquified by their contents and personality functions.
106 llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord> CieMap;
106 llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord *>
107 CieMap;
107108};
108109
109110class GotSection : public SyntheticSection {
deps/lld/include/lld/Driver/Driver.h+1-1
......@@ -15,7 +15,7 @@
1515
1616namespace lld {
1717namespace coff {
18bool link(llvm::ArrayRef<const char *> Args,
18bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly,
1919 llvm::raw_ostream &Diag = llvm::errs());
2020}
2121
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp-1
......@@ -621,7 +621,6 @@ void ArchHandler_x86_64::applyFixupFinal(
621621 // Fall into llvm_unreachable().
622622 break;
623623 }
624 return;
625624}
626625
627626void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref,
deps/lld/test/ELF/eh-frame-padding-no-rosegment.s created+64
......@@ -0,0 +1,64 @@
1// REQUIRES: x86
2
3.cfi_startproc
4.cfi_personality 0x1b, bar
5.cfi_endproc
6
7.global bar
8.hidden bar
9bar:
10
11// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
12
13// Check the size of the CIE (0x18 + 4) and FDE (0x10 + 4)
14// RUN: llvm-readobj -s -section-data %t.o | FileCheck --check-prefix=OBJ %s
15
16// OBJ: Name: .eh_frame
17// OBJ-NEXT: Type:
18// OBJ-NEXT: Flags [
19// OBJ-NEXT: SHF_ALLOC
20// OBJ-NEXT: ]
21// OBJ-NEXT: Address:
22// OBJ-NEXT: Offset:
23// OBJ-NEXT: Size:
24// OBJ-NEXT: Link:
25// OBJ-NEXT: Info:
26// OBJ-NEXT: AddressAlignment:
27// OBJ-NEXT: EntrySize:
28// OBJ-NEXT: SectionData (
29// OBJ-NEXT: 0000: 18000000 00000000 017A5052 00017810
30// OBJ-NEXT: 0010: 061B0000 00001B0C 07089001 10000000
31// OBJ-NEXT: 0020: 20000000 00000000 00000000 00000000
32// OBJ-NEXT: )
33
34// RUN: ld.lld %t.o -no-rosegment -o %t -shared
35
36// Check that .eh_frame is in the same segment as .text
37// RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=PHDR %s
38
39// PHDR: Segment Sections
40// PHDR: .text
41// PHDR-SAME: .eh_frame
42
43// Check that the CIE and FDE are padded with 0x00 and not 0xCC when the
44// .eh_frame section is placed in the executable segment
45// RUN: llvm-readobj -s -section-data %t | FileCheck %s
46
47// CHECK: Name: .eh_frame
48// CHECK-NEXT: Type:
49// CHECK-NEXT: Flags
50// CHECK-NEXT: SHF_ALLOC
51// CHECK-NEXT: ]
52// CHECK-NEXT: Address:
53// CHECK-NEXT: Offset:
54// CHECK-NEXT: Size:
55// CHECK-NEXT: Link:
56// CHECK-NEXT: Info:
57// CHECK-NEXT: AddressAlignment:
58// CHECK-NEXT: EntrySize:
59// CHECK-NEXT: SectionData (
60// CHECK-NEXT: 0000: 1C000000 00000000 017A5052 00017810
61// CHECK-NEXT: 0010: 061BBEFF FFFF1B0C 07089001 00000000
62// CHECK-NEXT: 0020: 14000000 24000000 A8FFFFFF 00000000
63// CHECK-NEXT: 0030: 00000000 00000000
64// CHECK-NEXT: )
deps/lld/tools/lld/lld.cpp+1-1
......@@ -103,7 +103,7 @@ int main(int Argc, const char **Argv) {
103103 case Gnu:
104104 return !elf::link(Args, true);
105105 case WinLink:
106 return !coff::link(Args);
106 return !coff::link(Args, true);
107107 case Darwin:
108108 return !mach_o::link(Args);
109109 default:
doc/langref.html.in+177-53
......@@ -136,7 +136,8 @@
136136 <li><a href="#builtin-divFloor">@divFloor</a></li>
137137 <li><a href="#builtin-divTrunc">@divTrunc</a></li>
138138 <li><a href="#builtin-embedFile">@embedFile</a></li>
139 <li><a href="#builtin-enumTagName">@enumTagName</a></li>
139 <li><a href="#builtin-tagName">@tagName</a></li>
140 <li><a href="#builtin-EnumTagType">@EnumTagType</a></li>
140141 <li><a href="#builtin-errorName">@errorName</a></li>
141142 <li><a href="#builtin-fence">@fence</a></li>
142143 <li><a href="#builtin-fieldParentPtr">@fieldParentPtr</a></li>
......@@ -2095,30 +2096,38 @@ const Type = enum {
20952096 NotOk,
20962097};
20972098
2098// Enums are sum types, and can hold more complex data of different types.
2099const ComplexType = enum {
2100 Ok: u8,
2101 NotOk: void,
2102};
2103
21042099// Declare a specific instance of the enum variant.
2105const c = ComplexType.Ok { 0 };
2100const c = Type.Ok;
21062101
2107// The ordinal value of a simple enum with no data members can be
2108// retrieved by a simple cast.
2109// The value starts from 0, counting up for each member.
2110const Value = enum {
2102// If you want access to the ordinal value of an enum, you
2103// can specify the tag type.
2104const Value = enum(u2) {
21112105 Zero,
21122106 One,
21132107 Two,
21142108};
2109
2110// Now you can cast between u2 and Value.
2111// The ordinal value starts from 0, counting up for each member.
21152112test "enum ordinal value" {
2116 assert(usize(Value.Zero) == 0);
2117 assert(usize(Value.One) == 1);
2118 assert(usize(Value.Two) == 2);
2113 assert(u2(Value.Zero) == 0);
2114 assert(u2(Value.One) == 1);
2115 assert(u2(Value.Two) == 2);
2116}
2117
2118// You can override the ordinal value for an enum.
2119const Value2 = enum(u32) {
2120 Hundred = 100,
2121 Thousand = 1000,
2122 Million = 1000000,
2123};
2124test "set enum ordinal value" {
2125 assert(u32(Value2.Hundred) == 100);
2126 assert(u32(Value2.Thousand) == 1000);
2127 assert(u32(Value2.Million) == 1000000);
21192128}
21202129
2121// Enums can have methods, the same as structs.
2130// Enums can have methods, the same as structs and unions.
21222131// Enum methods are not special, they are only namespaced
21232132// functions that you can call with dot syntax.
21242133const Suit = enum {
......@@ -2127,26 +2136,120 @@ const Suit = enum {
21272136 Diamonds,
21282137 Hearts,
21292138
2130 pub fn ordinal(self: &amp;const Suit) -&gt; u8 {
2131 u8(*self)
2139 pub fn isClubs(self: Suit) -&gt; bool {
2140 return self == Suit.Clubs;
21322141 }
21332142};
21342143test "enum method" {
21352144 const p = Suit.Spades;
2136 assert(p.ordinal() == 1);
2145 assert(!p.isClubs());
21372146}
21382147
21392148// An enum variant of different types can be switched upon.
2140// The associated data can be retrieved using `|...|` syntax.
2141//
2142// A void type is not required on a tag-only member.
21432149const Foo = enum {
2150 String,
2151 Number,
2152 None,
2153};
2154test "enum variant switch" {
2155 const p = Foo.Number;
2156 const what_is_it = switch (p) {
2157 Foo.String =&gt; "this is a string",
2158 Foo.Number =&gt; "this is a number",
2159 Foo.None =&gt; "this is a none",
2160 };
2161 assert(mem.eql(u8, what_is_it, "this is a number"));
2162}
2163
2164// @TagType can be used to access the integer tag type of an enum.
2165const Small = enum {
2166 One,
2167 Two,
2168 Three,
2169 Four,
2170};
2171test "@TagType" {
2172 assert(@TagType(Small) == u2);
2173}
2174
2175// @memberCount tells how many fields an enum has:
2176test "@memberCount" {
2177 assert(@memberCount(Small) == 4);
2178}
2179
2180// @memberName tells the name of a field in an enum:
2181test "@memberName" {
2182 assert(mem.eql(u8, @memberName(Small, 1), "Two"));
2183}
2184
2185// @tagName gives a []const u8 representation of an enum value:
2186test "@tagName" {
2187 assert(mem.eql(u8, @tagName(Small.Three), "Three"));
2188}</code></pre>
2189 <p>TODO extern enum</p>
2190 <p>TODO packed enum</p>
2191 <pre><code class="sh">$ zig test enum.zig
2192Test 1/8 enum ordinal value...OK
2193Test 2/8 set enum ordinal value...OK
2194Test 3/8 enum method...OK
2195Test 4/8 enum variant switch...OK
2196Test 5/8 @TagType...OK
2197Test 6/8 @memberCount...OK
2198Test 7/8 @memberName...OK
2199Test 8/8 @tagName...OK</code></pre>
2200 <p>See also:</p>
2201 <ul>
2202 <li><a href="#builtin-memberName">@memberName</a></li>
2203 <li><a href="#builtin-memberCount">@memberCount</a></li>
2204 <li><a href="#builtin-tagName">@tagName</a></li>
2205 </ul>
2206 <h2 id="union">union</h2>
2207 <pre><code class="zig">const assert = @import("std").debug.assert;
2208const mem = @import("std").mem;
2209
2210// A union has only 1 active field at a time.
2211const Payload = union {
2212 Int: i64,
2213 Float: f64,
2214 Bool: bool,
2215};
2216test "simple union" {
2217 var payload = Payload {.Int = 1234};
2218 // payload.Float = 12.34; // ERROR! field not active
2219 assert(payload.Int == 1234);
2220 // You can activate another field by assigning the entire union.
2221 payload = Payload {.Float = 12.34};
2222 assert(payload.Float == 12.34);
2223}
2224
2225// Unions can be given an enum tag type:
2226const ComplexTypeTag = enum { Ok, NotOk };
2227const ComplexType = union(ComplexTypeTag) {
2228 Ok: u8,
2229 NotOk: void,
2230};
2231
2232// Declare a specific instance of the union variant.
2233test "declare union value" {
2234 const c = ComplexType { .Ok = 0 };
2235 assert(ComplexTypeTag(c) == ComplexTypeTag.Ok);
2236}
2237
2238// @TagType can be used to access the enum tag type of a union.
2239test "@TagType" {
2240 assert(@TagType(ComplexType) == ComplexTypeTag);
2241}
2242
2243// Unions can be made to infer the enum tag type.
2244const Foo = union(enum) {
21442245 String: []const u8,
21452246 Number: u64,
2247
2248 // void can be omitted when inferring enum tag type.
21462249 None,
21472250};
2148test "enum variant switch" {
2149 const p = Foo.Number { 54 };
2251test "union variant switch" {
2252 const p = Foo { .Number = 54 };
21502253 const what_is_it = switch (p) {
21512254 // Capture by reference
21522255 Foo.String =&gt; |*x| {
......@@ -2155,6 +2258,7 @@ test "enum variant switch" {
21552258
21562259 // Capture by value
21572260 Foo.Number =&gt; |x| {
2261 assert(x == 54);
21582262 "this is a number"
21592263 },
21602264
......@@ -2162,37 +2266,50 @@ test "enum variant switch" {
21622266 "this is a none"
21632267 }
21642268 };
2269 assert(mem.eql(u8, what_is_it, "this is a number"));
21652270}
21662271
2167// The @enumTagName and @memberCount builtin functions can be used to
2168// the string representation and number of members respectively.
2169const BuiltinType = enum {
2170 A: f32,
2171 B: u32,
2172 C,
2272// TODO union methods
2273
2274
2275const Small = union {
2276 A: i32,
2277 B: bool,
2278 C: u8,
21732279};
21742280
2175test "enum builtins" {
2176 assert(mem.eql(u8, @enumTagName(BuiltinType.A { 0 }), "A"));
2177 assert(mem.eql(u8, @enumTagName(BuiltinType.C), "C"));
2178 assert(@memberCount(BuiltinType) == 3);
2281// @memberCount tells how many fields a union has:
2282test "@memberCount" {
2283 assert(@memberCount(Small) == 3);
2284}
2285
2286// @memberName tells the name of a field in an enum:
2287test "@memberName" {
2288 assert(mem.eql(u8, @memberName(Small, 1), "B"));
2289}
2290
2291// @tagName gives a []const u8 representation of an enum value,
2292// but only if the union has an enum tag type.
2293const Small2 = union(enum) {
2294 A: i32,
2295 B: bool,
2296 C: u8,
2297};
2298test "@tagName" {
2299 assert(mem.eql(u8, @tagName(Small2.C), "C"));
21792300}</code></pre>
2180 <pre><code class="sh">$ zig test enum.zig
2181Test 1/4 enum ordinal value...OK
2182Test 2/4 enum method...OK
2183Test 3/4 enum variant switch...OK
2184Test 4/4 enum builtins...OK</code></pre>
2185 <p>
2186 Enums are generated as a struct with a tag field and union field. Zig
2301 <pre><code class="sh">$ zig test union.zig
2302Test 1/7 simple union...OK
2303Test 2/7 declare union value...OK
2304Test 3/7 @TagType...OK
2305Test 4/7 union variant switch...OK
2306Test 5/7 @memberCount...OK
2307Test 6/7 @memberName...OK
2308Test 7/7 @tagName...OK</code></pre>
2309 <p>
2310 Unions with an enum tag are generated as a struct with a tag field and union field. Zig
21872311 sorts the order of the tag and union field by the largest alignment.
21882312 </p>
2189 <p>See also:</p>
2190 <ul>
2191 <li><a href="#builtin-enumTagName">@enumTagName</a></li>
2192 <li><a href="#builtin-memberCount">@memberCount</a></li>
2193 </ul>
2194 <h2 id="union">union</h2>
2195 <p>TODO union documentation</p>
21962313 <h2 id="switch">switch</h2>
21972314 <pre><code class="zig">const assert = @import("std").debug.assert;
21982315const builtin = @import("builtin");
......@@ -4251,10 +4368,15 @@ test.zig:6:2: error: found compile log statement
42514368 <ul>
42524369 <li><a href="#builtin-import">@import</a></li>
42534370 </ul>
4254 <h3 id="builtin-enumTagName">@enumTagName</h3>
4255 <pre><code class="zig">@enumTagName(value: var) -&gt; []const u8</code></pre>
4371 <h3 id="builtin-tagName">@tagName</h3>
4372 <pre><code class="zig">@tagName(value: var) -&gt; []const u8</code></pre>
4373 <p>
4374 Converts an enum value or union value to a slice of bytes representing the name.
4375 </p>
4376 <h3 id="builtin-EnumTagType">@EnumTagType</h3>
4377 <pre><code class="zig">@EnumTagType(T: type) -&gt; type</code></pre>
42564378 <p>
4257 Converts an enum tag name to a slice of bytes.
4379 Returns the integer type that is used to store the enumeration value.
42584380 </p>
42594381 <h3 id="builtin-errorName">@errorName</h3>
42604382 <pre><code class="zig">@errorName(err: error) -&gt; []u8</code></pre>
......@@ -5703,7 +5825,7 @@ VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" Typ
57035825
57045826ContainerMember = (ContainerField | FnDef | GlobalVarDecl)
57055827
5706ContainerField = Symbol option(":" Expression) ","
5828ContainerField = Symbol option(":" PrefixOpExpression option("=" PrefixOpExpression ","
57075829
57085830UseDecl = "use" Expression ";"
57095831
......@@ -5837,7 +5959,9 @@ GroupedExpression = "(" Expression ")"
58375959
58385960KeywordLiteral = "true" | "false" | "null" | "continue" | "undefined" | "error" | "this" | "unreachable"
58395961
5840ContainerDecl = option("extern" | "packed") ("struct" | "enum" | "union") "{" many(ContainerMember) "}"</code></pre>
5962ContainerDecl = option("extern" | "packed")
5963 ("struct" option(GroupedExpression) | "union" option("enum" option(GroupedExpression) | GroupedExpression) | ("enum" option(GroupedExpression)))
5964 "{" many(ContainerMember) "}"</code></pre>
58415965 <h2 id="zen">Zen</h2>
58425966 <ul>
58435967 <li>Communicate intent precisely.</li>
example/guess_number/main.zig+2-1
......@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
12const std = @import("std");
23const io = std.io;
34const fmt = std.fmt;
......@@ -15,7 +16,7 @@ pub fn main() -> %void {
1516
1617 var seed_bytes: [@sizeOf(usize)]u8 = undefined;
1718 %%os.getRandomBytes(seed_bytes[0..]);
18 const seed = std.mem.readInt(seed_bytes, usize, true);
19 const seed = std.mem.readInt(seed_bytes, usize, builtin.Endian.Big);
1920 var rand = Rand.init(seed);
2021
2122 const answer = rand.range(u8, 0, 100) + 1;
src/all_types.hpp+23-54
......@@ -97,18 +97,13 @@ struct ConstParent {
9797 } data;
9898};
9999
100struct ConstEnumValue {
101 uint64_t tag;
102 ConstExprValue *payload;
103};
104
105100struct ConstStructValue {
106101 ConstExprValue *fields;
107102 ConstParent parent;
108103};
109104
110105struct ConstUnionValue {
111 uint64_t tag;
106 BigInt tag;
112107 ConstExprValue *payload;
113108 ConstParent parent;
114109};
......@@ -249,7 +244,7 @@ struct ConstExprValue {
249244 ConstExprValue *x_maybe;
250245 ConstErrValue x_err_union;
251246 ErrorTableEntry *x_pure_err;
252 ConstEnumValue x_enum;
247 BigInt x_enum_tag;
253248 ConstStructValue x_struct;
254249 ConstUnionValue x_union;
255250 ConstArrayValue x_array;
......@@ -345,15 +340,14 @@ struct TldCompTime {
345340
346341struct TypeEnumField {
347342 Buf *name;
348 TypeTableEntry *type_entry;
349 uint32_t value;
350 uint32_t gen_index;
343 BigInt value;
344 uint32_t decl_index;
351345};
352346
353347struct TypeUnionField {
354348 Buf *name;
349 TypeEnumField *enum_field;
355350 TypeTableEntry *type_entry;
356 uint32_t value;
357351 uint32_t gen_index;
358352};
359353
......@@ -773,13 +767,15 @@ struct AstNodeContainerDecl {
773767 ZigList<AstNode *> fields;
774768 ZigList<AstNode *> decls;
775769 ContainerLayout layout;
776 AstNode *init_arg_expr; // enum(T) or struct(endianness)
770 AstNode *init_arg_expr; // enum(T), struct(endianness), or union(T), or union(enum(T))
771 bool auto_enum; // union(enum)
777772};
778773
779774struct AstNodeStructField {
780775 VisibMod visib_mod;
781776 Buf *name;
782777 AstNode *type;
778 AstNode *value;
783779};
784780
785781struct AstNodeStringLiteral {
......@@ -1009,12 +1005,9 @@ struct TypeTableEntryEnum {
10091005 AstNode *decl_node;
10101006 ContainerLayout layout;
10111007 uint32_t src_field_count;
1012 // number of fields in the union. 0 if enum with no payload
1013 uint32_t gen_field_count;
10141008 TypeEnumField *fields;
10151009 bool is_invalid; // true if any fields are invalid
1016 TypeTableEntry *tag_type;
1017 LLVMTypeRef union_type_ref;
1010 TypeTableEntry *tag_int_type;
10181011
10191012 ScopeDecls *decls_scope;
10201013
......@@ -1026,18 +1019,7 @@ struct TypeTableEntryEnum {
10261019
10271020 bool zero_bits_loop_flag;
10281021 bool zero_bits_known;
1029 uint32_t abi_alignment; // also figured out with zero_bits pass
1030
1031 size_t gen_union_index;
1032 size_t gen_tag_index;
1033
1034 uint32_t union_size_bytes;
1035 TypeTableEntry *most_aligned_union_member;
1036};
10371022
1038struct TypeTableEntryEnumTag {
1039 TypeTableEntry *enum_type;
1040 TypeTableEntry *int_type;
10411023 bool generate_name_table;
10421024 LLVMValueRef name_table;
10431025};
......@@ -1052,7 +1034,7 @@ struct TypeTableEntryUnion {
10521034 uint32_t gen_field_count;
10531035 TypeUnionField *fields;
10541036 bool is_invalid; // true if any fields are invalid
1055 TypeTableEntry *tag_type;
1037 TypeTableEntry *tag_type; // always an enum or null
10561038 LLVMTypeRef union_type_ref;
10571039
10581040 ScopeDecls *decls_scope;
......@@ -1117,7 +1099,6 @@ enum TypeTableEntryId {
11171099 TypeTableEntryIdErrorUnion,
11181100 TypeTableEntryIdPureError,
11191101 TypeTableEntryIdEnum,
1120 TypeTableEntryIdEnumTag,
11211102 TypeTableEntryIdUnion,
11221103 TypeTableEntryIdFn,
11231104 TypeTableEntryIdNamespace,
......@@ -1146,7 +1127,6 @@ struct TypeTableEntry {
11461127 TypeTableEntryMaybe maybe;
11471128 TypeTableEntryError error;
11481129 TypeTableEntryEnum enumeration;
1149 TypeTableEntryEnumTag enum_tag;
11501130 TypeTableEntryUnion unionation;
11511131 TypeTableEntryFn fn;
11521132 TypeTableEntryBoundFn bound_fn;
......@@ -1285,7 +1265,8 @@ enum BuiltinFnId {
12851265 BuiltinFnIdBitCast,
12861266 BuiltinFnIdIntToPtr,
12871267 BuiltinFnIdPtrToInt,
1288 BuiltinFnIdEnumTagName,
1268 BuiltinFnIdTagName,
1269 BuiltinFnIdTagType,
12891270 BuiltinFnIdFieldParentPtr,
12901271 BuiltinFnIdOffsetOf,
12911272 BuiltinFnIdInlineCall,
......@@ -1829,7 +1810,6 @@ enum IrInstructionId {
18291810 IrInstructionIdStorePtr,
18301811 IrInstructionIdFieldPtr,
18311812 IrInstructionIdStructFieldPtr,
1832 IrInstructionIdEnumFieldPtr,
18331813 IrInstructionIdUnionFieldPtr,
18341814 IrInstructionIdElemPtr,
18351815 IrInstructionIdVarPtr,
......@@ -1854,7 +1834,7 @@ enum IrInstructionId {
18541834 IrInstructionIdTestNonNull,
18551835 IrInstructionIdUnwrapMaybe,
18561836 IrInstructionIdMaybeWrap,
1857 IrInstructionIdEnumTag,
1837 IrInstructionIdUnionTag,
18581838 IrInstructionIdClz,
18591839 IrInstructionIdCtz,
18601840 IrInstructionIdImport,
......@@ -1893,7 +1873,6 @@ enum IrInstructionId {
18931873 IrInstructionIdErrWrapPayload,
18941874 IrInstructionIdFnProto,
18951875 IrInstructionIdTestComptime,
1896 IrInstructionIdInitEnum,
18971876 IrInstructionIdPtrCast,
18981877 IrInstructionIdBitCast,
18991878 IrInstructionIdWidenOrShorten,
......@@ -1910,7 +1889,8 @@ enum IrInstructionId {
19101889 IrInstructionIdSetGlobalLinkage,
19111890 IrInstructionIdDeclRef,
19121891 IrInstructionIdPanic,
1913 IrInstructionIdEnumTagName,
1892 IrInstructionIdTagName,
1893 IrInstructionIdTagType,
19141894 IrInstructionIdFieldParentPtr,
19151895 IrInstructionIdOffsetOf,
19161896 IrInstructionIdTypeId,
......@@ -2088,14 +2068,6 @@ struct IrInstructionStructFieldPtr {
20882068 bool is_const;
20892069};
20902070
2091struct IrInstructionEnumFieldPtr {
2092 IrInstruction base;
2093
2094 IrInstruction *enum_ptr;
2095 TypeEnumField *field;
2096 bool is_const;
2097};
2098
20992071struct IrInstructionUnionFieldPtr {
21002072 IrInstruction base;
21012073
......@@ -2299,7 +2271,7 @@ struct IrInstructionClz {
22992271 IrInstruction *value;
23002272};
23012273
2302struct IrInstructionEnumTag {
2274struct IrInstructionUnionTag {
23032275 IrInstruction base;
23042276
23052277 IrInstruction *value;
......@@ -2569,15 +2541,6 @@ struct IrInstructionTestComptime {
25692541 IrInstruction *value;
25702542};
25712543
2572struct IrInstructionInitEnum {
2573 IrInstruction base;
2574
2575 TypeTableEntry *enum_type;
2576 TypeEnumField *field;
2577 IrInstruction *init_value;
2578 LLVMValueRef tmp_ptr;
2579};
2580
25812544struct IrInstructionPtrCast {
25822545 IrInstruction base;
25832546
......@@ -2689,7 +2652,13 @@ struct IrInstructionPanic {
26892652 IrInstruction *msg;
26902653};
26912654
2692struct IrInstructionEnumTagName {
2655struct IrInstructionTagName {
2656 IrInstruction base;
2657
2658 IrInstruction *target;
2659};
2660
2661struct IrInstructionTagType {
26932662 IrInstruction base;
26942663
26952664 IrInstruction *target;
src/analyze.cpp+501-317
......@@ -223,7 +223,6 @@ bool type_is_complete(TypeTableEntry *type_entry) {
223223 case TypeTableEntryIdNamespace:
224224 case TypeTableEntryIdBlock:
225225 case TypeTableEntryIdBoundFn:
226 case TypeTableEntryIdEnumTag:
227226 case TypeTableEntryIdArgTuple:
228227 return true;
229228 }
......@@ -260,7 +259,6 @@ bool type_has_zero_bits_known(TypeTableEntry *type_entry) {
260259 case TypeTableEntryIdNamespace:
261260 case TypeTableEntryIdBlock:
262261 case TypeTableEntryIdBoundFn:
263 case TypeTableEntryIdEnumTag:
264262 case TypeTableEntryIdArgTuple:
265263 case TypeTableEntryIdOpaque:
266264 return true;
......@@ -1175,7 +1173,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
11751173 case TypeTableEntryIdEnum:
11761174 case TypeTableEntryIdUnion:
11771175 case TypeTableEntryIdFn:
1178 case TypeTableEntryIdEnumTag:
11791176 ensure_complete_type(g, type_entry);
11801177 if (fn_type_id.cc == CallingConventionUnspecified && !type_is_copyable(g, type_entry)) {
11811178 add_node_error(g, param_node->data.param_decl.type,
......@@ -1239,7 +1236,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
12391236 case TypeTableEntryIdEnum:
12401237 case TypeTableEntryIdUnion:
12411238 case TypeTableEntryIdFn:
1242 case TypeTableEntryIdEnumTag:
12431239 break;
12441240 }
12451241
......@@ -1263,22 +1259,6 @@ bool type_is_invalid(TypeTableEntry *type_entry) {
12631259}
12641260
12651261
1266TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type) {
1267 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnumTag);
1268
1269 buf_resize(&entry->name, 0);
1270 buf_appendf(&entry->name, "@enumTagType(%s)", buf_ptr(&enum_type->name));
1271
1272 entry->is_copyable = true;
1273 entry->data.enum_tag.enum_type = enum_type;
1274 entry->data.enum_tag.int_type = int_type;
1275 entry->type_ref = int_type->type_ref;
1276 entry->di_type = int_type->di_type;
1277 entry->zero_bits = int_type->zero_bits;
1278
1279 return entry;
1280}
1281
12821262static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
12831263 assert(enum_type->id == TypeTableEntryIdEnum);
12841264
......@@ -1308,14 +1288,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
13081288 assert(enum_type->data.enumeration.fields);
13091289 ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
13101290
1311 uint32_t gen_field_count = enum_type->data.enumeration.gen_field_count;
1312 ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count);
1313
1314 TypeTableEntry *most_aligned_union_member = nullptr;
1315 uint64_t size_of_most_aligned_member_in_bits = 0;
1316 uint64_t biggest_align_in_bits = 0;
1317 uint64_t biggest_size_in_bits = 0;
1318
13191291 Scope *scope = &enum_type->data.enumeration.decls_scope->base;
13201292 ImportTableEntry *import = get_scope_import(scope);
13211293
......@@ -1323,49 +1295,17 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
13231295 enum_type->data.enumeration.embedded_in_current = true;
13241296
13251297 for (uint32_t i = 0; i < field_count; i += 1) {
1326 AstNode *field_node = decl_node->data.container_decl.fields.at(i);
1327 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];
1328 TypeTableEntry *field_type = type_enum_field->type_entry;
1329
1330 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);
1331
1332 ensure_complete_type(g, field_type);
1333 if (type_is_invalid(field_type)) {
1334 enum_type->data.enumeration.is_invalid = true;
1335 continue;
1336 }
1337
1338 if (!type_has_bits(field_type))
1339 continue;
1340
1341 uint64_t store_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);
1342 uint64_t abi_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref);
1343
1344 assert(store_size_in_bits > 0);
1345 assert(abi_align_in_bits > 0);
1346
1347 union_inner_di_types[type_enum_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
1348 ZigLLVMTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name),
1349 import->di_file, (unsigned)(field_node->line + 1),
1350 store_size_in_bits,
1351 abi_align_in_bits,
1352 0,
1353 0, field_type->di_type);
1354
1355 biggest_size_in_bits = max(biggest_size_in_bits, store_size_in_bits);
1298 TypeEnumField *enum_field = &enum_type->data.enumeration.fields[i];
13561299
1357 if (!most_aligned_union_member || abi_align_in_bits > biggest_align_in_bits) {
1358 most_aligned_union_member = field_type;
1359 biggest_align_in_bits = abi_align_in_bits;
1360 size_of_most_aligned_member_in_bits = store_size_in_bits;
1361 }
1300 // TODO send patch to LLVM to support APInt in createEnumerator instead of int64_t
1301 // http://lists.llvm.org/pipermail/llvm-dev/2017-December/119456.html
1302 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(enum_field->name),
1303 bigint_as_signed(&enum_field->value));
13621304 }
13631305
13641306 // unset temporary flag
13651307 enum_type->data.enumeration.embedded_in_current = false;
13661308 enum_type->data.enumeration.complete = true;
1367 enum_type->data.enumeration.union_size_bytes = biggest_size_in_bits / 8;
1368 enum_type->data.enumeration.most_aligned_union_member = most_aligned_union_member;
13691309
13701310 if (enum_type->data.enumeration.is_invalid)
13711311 return;
......@@ -1390,118 +1330,21 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
13901330 return;
13911331 }
13921332
1393 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
1394 TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type);
1395 enum_type->data.enumeration.tag_type = tag_type_entry;
1396
1397 uint64_t align_of_tag_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);
1398
1399 if (most_aligned_union_member) {
1400 // create llvm type for union
1401 uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits;
1402 LLVMTypeRef union_type_ref;
1403 if (padding_in_bits > 0) {
1404 TypeTableEntry *u8_type = get_int_type(g, false, 8);
1405 TypeTableEntry *padding_array = get_array_type(g, u8_type, padding_in_bits / 8);
1406 LLVMTypeRef union_element_types[] = {
1407 most_aligned_union_member->type_ref,
1408 padding_array->type_ref,
1409 };
1410 union_type_ref = LLVMStructType(union_element_types, 2, false);
1411 } else {
1412 union_type_ref = most_aligned_union_member->type_ref;
1413 }
1414 enum_type->data.enumeration.union_type_ref = union_type_ref;
1415
1416 assert(8*LLVMABIAlignmentOfType(g->target_data_ref, union_type_ref) >= biggest_align_in_bits);
1417 assert(8*LLVMStoreSizeOfType(g->target_data_ref, union_type_ref) >= biggest_size_in_bits);
1418
1419 if (align_of_tag_in_bits >= biggest_align_in_bits) {
1420 enum_type->data.enumeration.gen_tag_index = 0;
1421 enum_type->data.enumeration.gen_union_index = 1;
1422 } else {
1423 enum_type->data.enumeration.gen_union_index = 0;
1424 enum_type->data.enumeration.gen_tag_index = 1;
1425 }
1426
1427 // create llvm type for root struct
1428 LLVMTypeRef root_struct_element_types[2];
1429 root_struct_element_types[enum_type->data.enumeration.gen_tag_index] = tag_type_entry->type_ref;
1430 root_struct_element_types[enum_type->data.enumeration.gen_union_index] = union_type_ref;
1431 LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false);
1432
1433 // create debug type for tag
1434 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref);
1435 uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type_entry->type_ref);
1436 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
1437 ZigLLVMTypeToScope(enum_type->di_type), "AnonEnum",
1438 import->di_file, (unsigned)(decl_node->line + 1),
1439 tag_debug_size_in_bits, tag_debug_align_in_bits, di_enumerators, field_count,
1440 tag_type_entry->di_type, "");
1441
1442 // create debug type for union
1443 ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
1444 ZigLLVMTypeToScope(enum_type->di_type), "AnonUnion",
1445 import->di_file, (unsigned)(decl_node->line + 1),
1446 biggest_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types,
1447 gen_field_count, 0, "");
1448
1449 // create debug types for members of root struct
1450 uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref,
1451 enum_type->data.enumeration.gen_tag_index);
1452 ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
1453 ZigLLVMTypeToScope(enum_type->di_type), "tag_field",
1454 import->di_file, (unsigned)(decl_node->line + 1),
1455 tag_debug_size_in_bits,
1456 tag_debug_align_in_bits,
1457 tag_offset_in_bits,
1458 0, tag_di_type);
1459
1460 uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref,
1461 enum_type->data.enumeration.gen_union_index);
1462 ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
1463 ZigLLVMTypeToScope(enum_type->di_type), "union_field",
1464 import->di_file, (unsigned)(decl_node->line + 1),
1465 biggest_size_in_bits,
1466 biggest_align_in_bits,
1467 union_offset_in_bits,
1468 0, union_di_type);
1469
1470 // create debug type for root struct
1471 ZigLLVMDIType *di_root_members[2];
1472 di_root_members[enum_type->data.enumeration.gen_tag_index] = tag_member_di_type;
1473 di_root_members[enum_type->data.enumeration.gen_union_index] = union_member_di_type;
1474
1475 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, enum_type->type_ref);
1476 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, enum_type->type_ref);
1477 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
1478 ZigLLVMFileToScope(import->di_file),
1479 buf_ptr(&enum_type->name),
1480 import->di_file, (unsigned)(decl_node->line + 1),
1481 debug_size_in_bits,
1482 debug_align_in_bits,
1483 0, nullptr, di_root_members, 2, 0, nullptr, "");
1484
1485 ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, replacement_di_type);
1486 enum_type->di_type = replacement_di_type;
1487 } else {
1488 // create llvm type for root struct
1489 enum_type->type_ref = tag_type_entry->type_ref;
1333 TypeTableEntry *tag_int_type = enum_type->data.enumeration.tag_int_type;
14901334
1491 // create debug type for tag
1492 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref);
1493 uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type_entry->type_ref);
1494 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
1495 ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name),
1496 import->di_file, (unsigned)(decl_node->line + 1),
1497 tag_debug_size_in_bits,
1498 tag_debug_align_in_bits,
1499 di_enumerators, field_count,
1500 tag_type_entry->di_type, "");
1335 // create debug type for tag
1336 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_int_type->type_ref);
1337 uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);
1338 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
1339 ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name),
1340 import->di_file, (unsigned)(decl_node->line + 1),
1341 tag_debug_size_in_bits,
1342 tag_debug_align_in_bits,
1343 di_enumerators, field_count,
1344 tag_int_type->di_type, "");
15011345
1502 ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type);
1503 enum_type->di_type = tag_di_type;
1504 }
1346 ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type);
1347 enum_type->di_type = tag_di_type;
15051348}
15061349
15071350static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
......@@ -1517,8 +1360,6 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
15171360 case TypeTableEntryIdNullLit:
15181361 case TypeTableEntryIdErrorUnion:
15191362 case TypeTableEntryIdPureError:
1520 case TypeTableEntryIdEnum:
1521 case TypeTableEntryIdEnumTag:
15221363 case TypeTableEntryIdNamespace:
15231364 case TypeTableEntryIdBlock:
15241365 case TypeTableEntryIdBoundFn:
......@@ -1541,6 +1382,8 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
15411382 TypeTableEntry *child_type = type_entry->data.maybe.child_type;
15421383 return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
15431384 }
1385 case TypeTableEntryIdEnum:
1386 return type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr;
15441387 }
15451388 zig_unreachable();
15461389}
......@@ -1658,7 +1501,6 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
16581501 TypeTableEntry *field_type = type_struct_field->type_entry;
16591502
16601503 ensure_complete_type(g, field_type);
1661
16621504 if (type_is_invalid(field_type)) {
16631505 struct_type->data.structure.is_invalid = true;
16641506 break;
......@@ -1849,6 +1691,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
18491691 if (union_type->data.unionation.embedded_in_current) {
18501692 if (!union_type->data.unionation.reported_infinite_err) {
18511693 union_type->data.unionation.reported_infinite_err = true;
1694 union_type->data.unionation.is_invalid = true;
18521695 add_node_error(g, decl_node, buf_sprintf("union '%s' contains itself", buf_ptr(&union_type->name)));
18531696 }
18541697 return;
......@@ -1870,19 +1713,17 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
18701713 uint64_t biggest_align_in_bits = 0;
18711714 uint64_t biggest_size_in_bits = 0;
18721715
1873 bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);
1874 ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
1875
18761716 Scope *scope = &union_type->data.unionation.decls_scope->base;
18771717 ImportTableEntry *import = get_scope_import(scope);
18781718
18791719 // set temporary flag
18801720 union_type->data.unionation.embedded_in_current = true;
18811721
1722
18821723 for (uint32_t i = 0; i < field_count; i += 1) {
18831724 AstNode *field_node = decl_node->data.container_decl.fields.at(i);
1884 TypeUnionField *type_union_field = &union_type->data.unionation.fields[i];
1885 TypeTableEntry *field_type = type_union_field->type_entry;
1725 TypeUnionField *union_field = &union_type->data.unionation.fields[i];
1726 TypeTableEntry *field_type = union_field->type_entry;
18861727
18871728 ensure_complete_type(g, field_type);
18881729 if (type_is_invalid(field_type)) {
......@@ -1893,16 +1734,14 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
18931734 if (!type_has_bits(field_type))
18941735 continue;
18951736
1896 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(type_union_field->name), i);
1897
18981737 uint64_t store_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);
18991738 uint64_t abi_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref);
19001739
19011740 assert(store_size_in_bits > 0);
19021741 assert(abi_align_in_bits > 0);
19031742
1904 union_inner_di_types[type_union_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
1905 ZigLLVMTypeToScope(union_type->di_type), buf_ptr(type_union_field->name),
1743 union_inner_di_types[union_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
1744 ZigLLVMTypeToScope(union_type->di_type), buf_ptr(union_field->enum_field->name),
19061745 import->di_file, (unsigned)(field_node->line + 1),
19071746 store_size_in_bits,
19081747 abi_align_in_bits,
......@@ -1918,6 +1757,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
19181757 }
19191758 }
19201759
1760
19211761 // unset temporary flag
19221762 union_type->data.unionation.embedded_in_current = false;
19231763 union_type->data.unionation.complete = true;
......@@ -1947,13 +1787,12 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
19471787 return;
19481788 }
19491789
1950 assert(most_aligned_union_member != nullptr);
1951
1952 bool want_safety = auto_layout && (field_count >= 2);
19531790 uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits;
19541791
1792 TypeTableEntry *tag_type = union_type->data.unionation.tag_type;
1793 if (tag_type == nullptr) {
1794 assert(most_aligned_union_member != nullptr);
19551795
1956 if (!want_safety) {
19571796 if (padding_in_bits > 0) {
19581797 TypeTableEntry *u8_type = get_int_type(g, false, 8);
19591798 TypeTableEntry *padding_array = get_array_type(g, u8_type, padding_in_bits / 8);
......@@ -1993,6 +1832,14 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
19931832 padding_array->type_ref,
19941833 };
19951834 union_type_ref = LLVMStructType(union_element_types, 2, false);
1835 } else if (most_aligned_union_member == nullptr) {
1836 union_type->data.unionation.gen_tag_index = SIZE_MAX;
1837 union_type->data.unionation.gen_union_index = SIZE_MAX;
1838 union_type->type_ref = tag_type->type_ref;
1839
1840 ZigLLVMReplaceTemporary(g->dbuilder, union_type->di_type, tag_type->di_type);
1841 union_type->di_type = tag_type->di_type;
1842 return;
19961843 } else {
19971844 union_type_ref = most_aligned_union_member->type_ref;
19981845 }
......@@ -2002,9 +1849,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
20021849 assert(8*LLVMStoreSizeOfType(g->target_data_ref, union_type_ref) >= biggest_size_in_bits);
20031850
20041851 // create llvm type for root struct
2005 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
2006 TypeTableEntry *tag_type_entry = tag_int_type;
2007 union_type->data.unionation.tag_type = tag_type_entry;
1852 TypeTableEntry *tag_int_type = tag_type->data.enumeration.tag_int_type;
20081853 uint64_t align_of_tag_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);
20091854
20101855 if (align_of_tag_in_bits >= biggest_align_in_bits) {
......@@ -2016,22 +1861,11 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
20161861 }
20171862
20181863 LLVMTypeRef root_struct_element_types[2];
2019 root_struct_element_types[union_type->data.unionation.gen_tag_index] = tag_type_entry->type_ref;
1864 root_struct_element_types[union_type->data.unionation.gen_tag_index] = tag_type->type_ref;
20201865 root_struct_element_types[union_type->data.unionation.gen_union_index] = union_type_ref;
20211866 LLVMStructSetBody(union_type->type_ref, root_struct_element_types, 2, false);
20221867
20231868
2024 // create debug type for root struct
2025
2026 // create debug type for tag
2027 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref);
2028 uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type_entry->type_ref);
2029 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
2030 ZigLLVMTypeToScope(union_type->di_type), "AnonEnum",
2031 import->di_file, (unsigned)(decl_node->line + 1),
2032 tag_debug_size_in_bits, tag_debug_align_in_bits, di_enumerators, field_count,
2033 tag_type_entry->di_type, "");
2034
20351869 // create debug type for union
20361870 ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
20371871 ZigLLVMTypeToScope(union_type->di_type), "AnonUnion",
......@@ -2045,19 +1879,23 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
20451879 union_type->data.unionation.gen_tag_index);
20461880
20471881 ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
2048 ZigLLVMTypeToScope(union_type->di_type), "union_field",
1882 ZigLLVMTypeToScope(union_type->di_type), "payload",
20491883 import->di_file, (unsigned)(decl_node->line + 1),
20501884 biggest_size_in_bits,
20511885 biggest_align_in_bits,
20521886 union_offset_in_bits,
20531887 0, union_di_type);
1888
1889 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref);
1890 uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref);
1891
20541892 ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
2055 ZigLLVMTypeToScope(union_type->di_type), "tag_field",
1893 ZigLLVMTypeToScope(union_type->di_type), "tag",
20561894 import->di_file, (unsigned)(decl_node->line + 1),
20571895 tag_debug_size_in_bits,
20581896 tag_debug_align_in_bits,
20591897 tag_offset_in_bits,
2060 0, tag_di_type);
1898 0, tag_type->di_type);
20611899
20621900 ZigLLVMDIType *di_root_members[2];
20631901 di_root_members[union_type->data.unionation.gen_tag_index] = tag_member_di_type;
......@@ -2096,51 +1934,124 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type) {
20961934
20971935 assert(!enum_type->data.enumeration.fields);
20981936 uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length;
1937 if (field_count == 0) {
1938 add_node_error(g, decl_node, buf_sprintf("enums must have 1 or more fields"));
1939
1940 enum_type->data.enumeration.src_field_count = field_count;
1941 enum_type->data.enumeration.fields = nullptr;
1942 enum_type->data.enumeration.is_invalid = true;
1943 enum_type->data.enumeration.zero_bits_loop_flag = false;
1944 enum_type->data.enumeration.zero_bits_known = true;
1945 return;
1946 }
1947
20991948 enum_type->data.enumeration.src_field_count = field_count;
21001949 enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
21011950
2102 uint32_t biggest_align_bytes = 0;
2103
21041951 Scope *scope = &enum_type->data.enumeration.decls_scope->base;
21051952
2106 uint32_t gen_field_index = 0;
2107 for (uint32_t i = 0; i < field_count; i += 1) {
2108 AstNode *field_node = decl_node->data.container_decl.fields.at(i);
2109 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];
2110 type_enum_field->name = field_node->data.struct_field.name;
2111 TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type);
2112 type_enum_field->type_entry = field_type;
2113 type_enum_field->value = i;
1953 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};
1954 occupied_tag_values.init(field_count);
21141955
2115 type_ensure_zero_bits_known(g, field_type);
2116 if (type_is_invalid(field_type)) {
1956 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
1957
1958 if (decl_node->data.container_decl.init_arg_expr != nullptr) {
1959 TypeTableEntry *wanted_tag_int_type = analyze_type_expr(g, scope, decl_node->data.container_decl.init_arg_expr);
1960 if (type_is_invalid(wanted_tag_int_type)) {
21171961 enum_type->data.enumeration.is_invalid = true;
2118 continue;
1962 } else if (wanted_tag_int_type->id != TypeTableEntryIdInt) {
1963 enum_type->data.enumeration.is_invalid = true;
1964 add_node_error(g, decl_node->data.container_decl.init_arg_expr,
1965 buf_sprintf("expected integer, found '%s'", buf_ptr(&wanted_tag_int_type->name)));
1966 } else if (wanted_tag_int_type->data.integral.is_signed) {
1967 enum_type->data.enumeration.is_invalid = true;
1968 add_node_error(g, decl_node->data.container_decl.init_arg_expr,
1969 buf_sprintf("expected unsigned integer, found '%s'", buf_ptr(&wanted_tag_int_type->name)));
1970 } else if (wanted_tag_int_type->data.integral.bit_count < tag_int_type->data.integral.bit_count) {
1971 enum_type->data.enumeration.is_invalid = true;
1972 add_node_error(g, decl_node->data.container_decl.init_arg_expr,
1973 buf_sprintf("'%s' too small to hold all bits; must be at least '%s'",
1974 buf_ptr(&wanted_tag_int_type->name), buf_ptr(&tag_int_type->name)));
1975 } else {
1976 tag_int_type = wanted_tag_int_type;
21191977 }
1978 }
1979 enum_type->data.enumeration.tag_int_type = tag_int_type;
1980 enum_type->type_ref = tag_int_type->type_ref;
21201981
2121 if (!type_has_bits(field_type))
2122 continue;
1982 for (uint32_t field_i = 0; field_i < field_count; field_i += 1) {
1983 AstNode *field_node = decl_node->data.container_decl.fields.at(field_i);
1984 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i];
1985 type_enum_field->name = field_node->data.struct_field.name;
1986 type_enum_field->decl_index = field_i;
21231987
2124 type_enum_field->gen_index = gen_field_index;
2125 gen_field_index += 1;
1988 if (field_node->data.struct_field.type != nullptr) {
1989 ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.type,
1990 buf_sprintf("structs and unions, not enums, support field types"));
1991 add_error_note(g, msg, decl_node,
1992 buf_sprintf("consider 'union(enum)' here"));
1993 }
21261994
2127 uint32_t field_align_bytes = get_abi_alignment(g, field_type);
2128 if (field_align_bytes > biggest_align_bytes) {
2129 biggest_align_bytes = field_align_bytes;
1995 AstNode *tag_value = field_node->data.struct_field.value;
1996
1997 // In this first pass we resolve explicit tag values.
1998 // In a second pass we will fill in the unspecified ones.
1999 if (tag_value != nullptr) {
2000 IrInstruction *result_inst = analyze_const_value(g, scope, tag_value, tag_int_type, nullptr);
2001 if (result_inst->value.type->id == TypeTableEntryIdInvalid) {
2002 enum_type->data.enumeration.is_invalid = true;
2003 continue;
2004 }
2005 assert(result_inst->value.special != ConstValSpecialRuntime);
2006 assert(result_inst->value.type->id == TypeTableEntryIdInt);
2007 auto entry = occupied_tag_values.put_unique(result_inst->value.data.x_bigint, tag_value);
2008 if (entry == nullptr) {
2009 bigint_init_bigint(&type_enum_field->value, &result_inst->value.data.x_bigint);
2010 } else {
2011 Buf *val_buf = buf_alloc();
2012 bigint_append_buf(val_buf, &result_inst->value.data.x_bigint, 10);
2013
2014 ErrorMsg *msg = add_node_error(g, tag_value,
2015 buf_sprintf("enum tag value %s already taken", buf_ptr(val_buf)));
2016 add_error_note(g, msg, entry->value,
2017 buf_sprintf("other occurrence here"));
2018 enum_type->data.enumeration.is_invalid = true;
2019 continue;
2020 }
21302021 }
21312022 }
21322023
2133 enum_type->data.enumeration.zero_bits_loop_flag = false;
2134 enum_type->data.enumeration.gen_field_count = gen_field_index;
2135 enum_type->zero_bits = (gen_field_index == 0 && field_count < 2);
2136 enum_type->data.enumeration.zero_bits_known = true;
2024 // Now iterate again and populate the unspecified tag values
2025 uint32_t next_maybe_unoccupied_index = 0;
2026
2027 for (uint32_t field_i = 0; field_i < field_count; field_i += 1) {
2028 AstNode *field_node = decl_node->data.container_decl.fields.at(field_i);
2029 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i];
2030 AstNode *tag_value = field_node->data.struct_field.value;
21372031
2138 // also compute abi_alignment
2139 if (!enum_type->zero_bits) {
2140 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count);
2141 uint32_t align_of_tag_in_bytes = LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);
2142 enum_type->data.enumeration.abi_alignment = max(align_of_tag_in_bytes, biggest_align_bytes);
2032 if (tag_value == nullptr) {
2033 if (occupied_tag_values.size() == 0) {
2034 bigint_init_unsigned(&type_enum_field->value, next_maybe_unoccupied_index);
2035 next_maybe_unoccupied_index += 1;
2036 } else {
2037 BigInt proposed_value;
2038 for (;;) {
2039 bigint_init_unsigned(&proposed_value, next_maybe_unoccupied_index);
2040 next_maybe_unoccupied_index += 1;
2041 auto entry = occupied_tag_values.put_unique(proposed_value, field_node);
2042 if (entry != nullptr) {
2043 continue;
2044 }
2045 break;
2046 }
2047 bigint_init_bigint(&type_enum_field->value, &proposed_value);
2048 }
2049 }
21432050 }
2051
2052 enum_type->data.enumeration.zero_bits_loop_flag = false;
2053 enum_type->zero_bits = (field_count < 2);
2054 enum_type->data.enumeration.zero_bits_known = true;
21442055}
21452056
21462057static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) {
......@@ -2184,11 +2095,23 @@ static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) {
21842095 AstNode *field_node = decl_node->data.container_decl.fields.at(i);
21852096 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
21862097 type_struct_field->name = field_node->data.struct_field.name;
2098
2099 if (field_node->data.struct_field.type == nullptr) {
2100 add_node_error(g, field_node, buf_sprintf("struct field missing type"));
2101 struct_type->data.structure.is_invalid = true;
2102 continue;
2103 }
2104
21872105 TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type);
21882106 type_struct_field->type_entry = field_type;
21892107 type_struct_field->src_index = i;
21902108 type_struct_field->gen_index = SIZE_MAX;
21912109
2110 if (field_node->data.struct_field.value != nullptr) {
2111 add_node_error(g, field_node->data.struct_field.value,
2112 buf_sprintf("enums, not structs, support field assignment"));
2113 }
2114
21922115 type_ensure_zero_bits_known(g, field_type);
21932116 if (type_is_invalid(field_type)) {
21942117 struct_type->data.structure.is_invalid = true;
......@@ -2225,8 +2148,23 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
22252148 if (union_type->data.unionation.zero_bits_known)
22262149 return;
22272150
2151 if (type_is_invalid(union_type))
2152 return;
2153
22282154 if (union_type->data.unionation.zero_bits_loop_flag) {
2155 // If we get here it's due to recursion. From this we conclude that the struct is
2156 // not zero bits, and if abi_alignment == 0 we further conclude that the first field
2157 // is a pointer to this very struct, or a function pointer with parameters that
2158 // reference such a type.
22292159 union_type->data.unionation.zero_bits_known = true;
2160 if (union_type->data.unionation.abi_alignment == 0) {
2161 if (union_type->data.unionation.layout == ContainerLayoutPacked) {
2162 union_type->data.unionation.abi_alignment = 1;
2163 } else {
2164 union_type->data.unionation.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref,
2165 LLVMPointerType(LLVMInt8Type(), 0));
2166 }
2167 }
22302168 return;
22312169 }
22322170
......@@ -2238,6 +2176,16 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
22382176
22392177 assert(!union_type->data.unionation.fields);
22402178 uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length;
2179 if (field_count == 0) {
2180 add_node_error(g, decl_node, buf_sprintf("unions must have 1 or more fields"));
2181
2182 union_type->data.unionation.src_field_count = field_count;
2183 union_type->data.unionation.fields = nullptr;
2184 union_type->data.unionation.is_invalid = true;
2185 union_type->data.unionation.zero_bits_loop_flag = false;
2186 union_type->data.unionation.zero_bits_known = true;
2187 return;
2188 }
22412189 union_type->data.unionation.src_field_count = field_count;
22422190 union_type->data.unionation.fields = allocate<TypeUnionField>(field_count);
22432191
......@@ -2245,44 +2193,261 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
22452193
22462194 Scope *scope = &union_type->data.unionation.decls_scope->base;
22472195
2196 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {};
2197
2198 AstNode *enum_type_node = decl_node->data.container_decl.init_arg_expr;
2199 bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);
2200 bool want_safety = (field_count >= 2) && (auto_layout || enum_type_node != nullptr);
2201 TypeTableEntry *tag_type;
2202 bool create_enum_type = decl_node->data.container_decl.auto_enum || (enum_type_node == nullptr && want_safety);
2203 bool *covered_enum_fields;
2204 ZigLLVMDIEnumerator **di_enumerators;
2205 if (create_enum_type) {
2206 occupied_tag_values.init(field_count);
2207
2208 di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
2209
2210 TypeTableEntry *tag_int_type;
2211 if (enum_type_node != nullptr) {
2212 tag_int_type = analyze_type_expr(g, scope, enum_type_node);
2213 if (type_is_invalid(tag_int_type)) {
2214 union_type->data.unionation.is_invalid = true;
2215 return;
2216 }
2217 if (tag_int_type->id != TypeTableEntryIdInt) {
2218 add_node_error(g, enum_type_node,
2219 buf_sprintf("expected integer tag type, found '%s'", buf_ptr(&tag_int_type->name)));
2220 union_type->data.unionation.is_invalid = true;
2221 return;
2222 }
2223 } else {
2224 tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
2225 }
2226 union_type->data.unionation.abi_alignment = get_abi_alignment(g, tag_int_type);
2227
2228 tag_type = new_type_table_entry(TypeTableEntryIdEnum);
2229 buf_resize(&tag_type->name, 0);
2230 buf_appendf(&tag_type->name, "@EnumTagType(%s)", buf_ptr(&union_type->name));
2231 tag_type->is_copyable = true;
2232 tag_type->type_ref = tag_int_type->type_ref;
2233 tag_type->zero_bits = tag_int_type->zero_bits;
2234
2235 tag_type->data.enumeration.tag_int_type = tag_int_type;
2236 tag_type->data.enumeration.zero_bits_known = true;
2237 tag_type->data.enumeration.decl_node = decl_node;
2238 tag_type->data.enumeration.layout = ContainerLayoutAuto;
2239 tag_type->data.enumeration.src_field_count = field_count;
2240 tag_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
2241 tag_type->data.enumeration.decls_scope = union_type->data.unionation.decls_scope;
2242 tag_type->data.enumeration.complete = true;
2243 } else if (enum_type_node != nullptr) {
2244 TypeTableEntry *enum_type = analyze_type_expr(g, scope, enum_type_node);
2245 if (type_is_invalid(enum_type)) {
2246 union_type->data.unionation.is_invalid = true;
2247 union_type->data.unionation.embedded_in_current = false;
2248 return;
2249 }
2250 if (enum_type->id != TypeTableEntryIdEnum) {
2251 union_type->data.unionation.is_invalid = true;
2252 union_type->data.unionation.embedded_in_current = false;
2253 add_node_error(g, enum_type_node,
2254 buf_sprintf("expected enum tag type, found '%s'", buf_ptr(&enum_type->name)));
2255 return;
2256 }
2257 tag_type = enum_type;
2258 covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);
2259 union_type->data.unionation.abi_alignment = get_abi_alignment(g, enum_type);
2260 } else {
2261 tag_type = nullptr;
2262 }
2263 union_type->data.unionation.tag_type = tag_type;
2264
22482265 uint32_t gen_field_index = 0;
22492266 for (uint32_t i = 0; i < field_count; i += 1) {
22502267 AstNode *field_node = decl_node->data.container_decl.fields.at(i);
2251 TypeUnionField *type_union_field = &union_type->data.unionation.fields[i];
2252 type_union_field->name = field_node->data.struct_field.name;
2253 TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type);
2254 type_union_field->type_entry = field_type;
2255 type_union_field->value = i;
2268 Buf *field_name = field_node->data.struct_field.name;
2269 TypeUnionField *union_field = &union_type->data.unionation.fields[i];
2270 union_field->name = field_node->data.struct_field.name;
2271
2272 TypeTableEntry *field_type;
2273 if (field_node->data.struct_field.type == nullptr) {
2274 if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) {
2275 field_type = g->builtin_types.entry_void;
2276 } else {
2277 add_node_error(g, field_node, buf_sprintf("union field missing type"));
2278 union_type->data.unionation.is_invalid = true;
2279 continue;
2280 }
2281 } else {
2282 field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type);
2283 type_ensure_zero_bits_known(g, field_type);
2284 if (type_is_invalid(field_type)) {
2285 union_type->data.unionation.is_invalid = true;
2286 continue;
2287 }
2288 }
2289 union_field->type_entry = field_type;
22562290
2257 type_ensure_zero_bits_known(g, field_type);
2258 if (type_is_invalid(field_type)) {
2259 union_type->data.unionation.is_invalid = true;
2260 continue;
2291 if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) {
2292 ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value,
2293 buf_sprintf("non-enum union field assignment"));
2294 add_error_note(g, msg, decl_node,
2295 buf_sprintf("consider 'union(enum)' here"));
2296 }
2297
2298 if (create_enum_type) {
2299 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(field_name), i);
2300 union_field->enum_field = &tag_type->data.enumeration.fields[i];
2301 union_field->enum_field->name = field_name;
2302 union_field->enum_field->decl_index = i;
2303
2304 AstNode *tag_value = field_node->data.struct_field.value;
2305 // In this first pass we resolve explicit tag values.
2306 // In a second pass we will fill in the unspecified ones.
2307 if (tag_value != nullptr) {
2308 TypeTableEntry *tag_int_type = tag_type->data.enumeration.tag_int_type;
2309 IrInstruction *result_inst = analyze_const_value(g, scope, tag_value, tag_int_type, nullptr);
2310 if (result_inst->value.type->id == TypeTableEntryIdInvalid) {
2311 union_type->data.unionation.is_invalid = true;
2312 continue;
2313 }
2314 assert(result_inst->value.special != ConstValSpecialRuntime);
2315 assert(result_inst->value.type->id == TypeTableEntryIdInt);
2316 auto entry = occupied_tag_values.put_unique(result_inst->value.data.x_bigint, tag_value);
2317 if (entry == nullptr) {
2318 bigint_init_bigint(&union_field->enum_field->value, &result_inst->value.data.x_bigint);
2319 } else {
2320 Buf *val_buf = buf_alloc();
2321 bigint_append_buf(val_buf, &result_inst->value.data.x_bigint, 10);
2322
2323 ErrorMsg *msg = add_node_error(g, tag_value,
2324 buf_sprintf("enum tag value %s already taken", buf_ptr(val_buf)));
2325 add_error_note(g, msg, entry->value,
2326 buf_sprintf("other occurrence here"));
2327 union_type->data.unionation.is_invalid = true;
2328 continue;
2329 }
2330 }
2331 } else if (enum_type_node != nullptr) {
2332 union_field->enum_field = find_enum_type_field(tag_type, field_name);
2333 if (union_field->enum_field == nullptr) {
2334 ErrorMsg *msg = add_node_error(g, field_node,
2335 buf_sprintf("enum field not found: '%s'", buf_ptr(field_name)));
2336 add_error_note(g, msg, tag_type->data.enumeration.decl_node,
2337 buf_sprintf("enum declared here"));
2338 union_type->data.unionation.is_invalid = true;
2339 continue;
2340 }
2341 covered_enum_fields[union_field->enum_field->decl_index] = true;
2342 } else {
2343 union_field->enum_field = allocate<TypeEnumField>(1);
2344 union_field->enum_field->name = field_name;
2345 union_field->enum_field->decl_index = i;
2346 bigint_init_unsigned(&union_field->enum_field->value, i);
22612347 }
2348 assert(union_field->enum_field != nullptr);
22622349
22632350 if (!type_has_bits(field_type))
22642351 continue;
22652352
2266 type_union_field->gen_index = gen_field_index;
2353 union_field->gen_index = gen_field_index;
22672354 gen_field_index += 1;
22682355
22692356 uint32_t field_align_bytes = get_abi_alignment(g, field_type);
22702357 if (field_align_bytes > biggest_align_bytes) {
22712358 biggest_align_bytes = field_align_bytes;
2359 if (biggest_align_bytes > union_type->data.unionation.abi_alignment) {
2360 union_type->data.unionation.abi_alignment = biggest_align_bytes;
2361 }
22722362 }
22732363 }
22742364
2275 bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);
2365 if (union_type->data.unionation.is_invalid)
2366 return;
2367
2368 bool src_have_tag = decl_node->data.container_decl.auto_enum ||
2369 decl_node->data.container_decl.init_arg_expr != nullptr;
2370
2371 if (src_have_tag && union_type->data.unionation.layout != ContainerLayoutAuto) {
2372 const char *qual_str;
2373 switch (union_type->data.unionation.layout) {
2374 case ContainerLayoutAuto:
2375 zig_unreachable();
2376 case ContainerLayoutPacked:
2377 qual_str = "packed";
2378 break;
2379 case ContainerLayoutExtern:
2380 qual_str = "extern";
2381 break;
2382 }
2383 AstNode *source_node = (decl_node->data.container_decl.init_arg_expr != nullptr) ?
2384 decl_node->data.container_decl.init_arg_expr : decl_node;
2385 add_node_error(g, source_node,
2386 buf_sprintf("%s union does not support enum tag type", qual_str));
2387 union_type->data.unionation.is_invalid = true;
2388 return;
2389 }
2390
2391 if (create_enum_type) {
2392 // Now iterate again and populate the unspecified tag values
2393 uint32_t next_maybe_unoccupied_index = 0;
2394
2395 for (uint32_t field_i = 0; field_i < field_count; field_i += 1) {
2396 AstNode *field_node = decl_node->data.container_decl.fields.at(field_i);
2397 TypeUnionField *union_field = &union_type->data.unionation.fields[field_i];
2398 AstNode *tag_value = field_node->data.struct_field.value;
2399
2400 if (tag_value == nullptr) {
2401 if (occupied_tag_values.size() == 0) {
2402 bigint_init_unsigned(&union_field->enum_field->value, next_maybe_unoccupied_index);
2403 next_maybe_unoccupied_index += 1;
2404 } else {
2405 BigInt proposed_value;
2406 for (;;) {
2407 bigint_init_unsigned(&proposed_value, next_maybe_unoccupied_index);
2408 next_maybe_unoccupied_index += 1;
2409 auto entry = occupied_tag_values.put_unique(proposed_value, field_node);
2410 if (entry != nullptr) {
2411 continue;
2412 }
2413 break;
2414 }
2415 bigint_init_bigint(&union_field->enum_field->value, &proposed_value);
2416 }
2417 }
2418 }
2419 } else if (enum_type_node != nullptr) {
2420 for (uint32_t i = 0; i < tag_type->data.enumeration.src_field_count; i += 1) {
2421 TypeEnumField *enum_field = &tag_type->data.enumeration.fields[i];
2422 if (!covered_enum_fields[i]) {
2423 AstNode *enum_decl_node = tag_type->data.enumeration.decl_node;
2424 AstNode *field_node = enum_decl_node->data.container_decl.fields.at(i);
2425 ErrorMsg *msg = add_node_error(g, decl_node,
2426 buf_sprintf("enum field missing: '%s'", buf_ptr(enum_field->name)));
2427 add_error_note(g, msg, field_node,
2428 buf_sprintf("declared here"));
2429 union_type->data.unionation.is_invalid = true;
2430 }
2431 }
2432 }
2433
2434 if (create_enum_type) {
2435 ImportTableEntry *import = get_scope_import(scope);
2436 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref);
2437 uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref);
2438 // TODO get a more accurate debug scope
2439 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
2440 ZigLLVMFileToScope(import->di_file), buf_ptr(&tag_type->name),
2441 import->di_file, (unsigned)(decl_node->line + 1),
2442 tag_debug_size_in_bits, tag_debug_align_in_bits, di_enumerators, field_count,
2443 tag_type->di_type, "");
2444 tag_type->di_type = tag_di_type;
2445 }
22762446
22772447 union_type->data.unionation.zero_bits_loop_flag = false;
22782448 union_type->data.unionation.gen_field_count = gen_field_index;
2279 union_type->zero_bits = (gen_field_index == 0 && (field_count < 2 || !auto_layout));
2449 union_type->zero_bits = (gen_field_index == 0 && (field_count < 2 || !src_have_tag));
22802450 union_type->data.unionation.zero_bits_known = true;
2281
2282 // also compute abi_alignment
2283 if (!union_type->zero_bits) {
2284 union_type->data.unionation.abi_alignment = biggest_align_bytes;
2285 }
22862451}
22872452
22882453static void get_fully_qualified_decl_name_internal(Buf *buf, Scope *scope, uint8_t sep) {
......@@ -2741,7 +2906,6 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt
27412906 case TypeTableEntryIdUnion:
27422907 case TypeTableEntryIdFn:
27432908 case TypeTableEntryIdBoundFn:
2744 case TypeTableEntryIdEnumTag:
27452909 return type_entry;
27462910 }
27472911 zig_unreachable();
......@@ -3158,13 +3322,37 @@ TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name) {
31583322 assert(type_entry->data.unionation.complete);
31593323 for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) {
31603324 TypeUnionField *field = &type_entry->data.unionation.fields[i];
3161 if (buf_eql_buf(field->name, name)) {
3325 if (buf_eql_buf(field->enum_field->name, name)) {
31623326 return field;
31633327 }
31643328 }
31653329 return nullptr;
31663330}
31673331
3332TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag) {
3333 assert(type_entry->id == TypeTableEntryIdUnion);
3334 assert(type_entry->data.unionation.complete);
3335 assert(type_entry->data.unionation.gen_tag_index != SIZE_MAX);
3336 for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) {
3337 TypeUnionField *field = &type_entry->data.unionation.fields[i];
3338 if (bigint_cmp(&field->enum_field->value, tag) == CmpEQ) {
3339 return field;
3340 }
3341 }
3342 return nullptr;
3343}
3344
3345TypeEnumField *find_enum_field_by_tag(TypeTableEntry *enum_type, const BigInt *tag) {
3346 for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) {
3347 TypeEnumField *field = &enum_type->data.enumeration.fields[i];
3348 if (bigint_cmp(&field->value, tag) == CmpEQ) {
3349 return field;
3350 }
3351 }
3352 return nullptr;
3353}
3354
3355
31683356static bool is_container(TypeTableEntry *type_entry) {
31693357 switch (type_entry->id) {
31703358 case TypeTableEntryIdInvalid:
......@@ -3193,7 +3381,6 @@ static bool is_container(TypeTableEntry *type_entry) {
31933381 case TypeTableEntryIdNamespace:
31943382 case TypeTableEntryIdBlock:
31953383 case TypeTableEntryIdBoundFn:
3196 case TypeTableEntryIdEnumTag:
31973384 case TypeTableEntryIdArgTuple:
31983385 case TypeTableEntryIdOpaque:
31993386 return false;
......@@ -3244,7 +3431,6 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
32443431 case TypeTableEntryIdBoundFn:
32453432 case TypeTableEntryIdInvalid:
32463433 case TypeTableEntryIdVar:
3247 case TypeTableEntryIdEnumTag:
32483434 case TypeTableEntryIdArgTuple:
32493435 case TypeTableEntryIdOpaque:
32503436 zig_unreachable();
......@@ -3698,7 +3884,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
36983884 case TypeTableEntryIdPointer:
36993885 case TypeTableEntryIdPureError:
37003886 case TypeTableEntryIdFn:
3701 case TypeTableEntryIdEnumTag:
3887 case TypeTableEntryIdEnum:
37023888 return false;
37033889 case TypeTableEntryIdArray:
37043890 case TypeTableEntryIdStruct:
......@@ -3706,9 +3892,6 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
37063892 return type_has_bits(type_entry);
37073893 case TypeTableEntryIdErrorUnion:
37083894 return type_has_bits(type_entry->data.error.child_type);
3709 case TypeTableEntryIdEnum:
3710 assert(type_entry->data.enumeration.complete);
3711 return type_entry->data.enumeration.gen_field_count != 0;
37123895 case TypeTableEntryIdMaybe:
37133896 return type_has_bits(type_entry->data.maybe.child_type) &&
37143897 type_entry->data.maybe.child_type->id != TypeTableEntryIdPointer &&
......@@ -3850,7 +4033,6 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
38504033 return (uint32_t)4149439618;
38514034 case TypeTableEntryIdInt:
38524035 case TypeTableEntryIdNumLitInt:
3853 case TypeTableEntryIdEnumTag:
38544036 {
38554037 uint32_t result = 1331471175;
38564038 for (size_t i = 0; i < const_val->data.x_bigint.digit_count; i += 1) {
......@@ -3859,6 +4041,15 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
38594041 }
38604042 return result;
38614043 }
4044 case TypeTableEntryIdEnum:
4045 {
4046 uint32_t result = 31643936;
4047 for (size_t i = 0; i < const_val->data.x_enum_tag.digit_count; i += 1) {
4048 uint64_t digit = bigint_ptr(&const_val->data.x_enum_tag)[i];
4049 result ^= ((uint32_t)(digit >> 32)) ^ (uint32_t)(result);
4050 }
4051 return result;
4052 }
38624053 case TypeTableEntryIdFloat:
38634054 switch (const_val->type->data.floating.bit_count) {
38644055 case 32:
......@@ -3959,9 +4150,6 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
39594150 case TypeTableEntryIdPureError:
39604151 // TODO better hashing algorithm
39614152 return 2630160122;
3962 case TypeTableEntryIdEnum:
3963 // TODO better hashing algorithm
3964 return 31643936;
39654153 case TypeTableEntryIdFn:
39664154 return 4133894920 ^ hash_ptr(const_val->data.x_fn.fn_entry);
39674155 case TypeTableEntryIdNamespace:
......@@ -4094,7 +4282,6 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
40944282 case TypeTableEntryIdInt:
40954283 case TypeTableEntryIdFloat:
40964284 case TypeTableEntryIdPointer:
4097 case TypeTableEntryIdEnumTag:
40984285 case TypeTableEntryIdVoid:
40994286 case TypeTableEntryIdUnreachable:
41004287 return false;
......@@ -4153,6 +4340,19 @@ ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *str) {
41534340 return const_val;
41544341}
41554342
4343void init_const_bigint(ConstExprValue *const_val, TypeTableEntry *type, const BigInt *bigint) {
4344 const_val->special = ConstValSpecialStatic;
4345 const_val->type = type;
4346 bigint_init_bigint(&const_val->data.x_bigint, bigint);
4347}
4348
4349ConstExprValue *create_const_bigint(TypeTableEntry *type, const BigInt *bigint) {
4350 ConstExprValue *const_val = create_const_vals(1);
4351 init_const_bigint(const_val, type, bigint);
4352 return const_val;
4353}
4354
4355
41564356void init_const_unsigned_negative(ConstExprValue *const_val, TypeTableEntry *type, uint64_t x, bool negative) {
41574357 const_val->special = ConstValSpecialStatic;
41584358 const_val->type = type;
......@@ -4216,18 +4416,19 @@ ConstExprValue *create_const_float(TypeTableEntry *type, double value) {
42164416 return const_val;
42174417}
42184418
4219void init_const_enum_tag(ConstExprValue *const_val, TypeTableEntry *type, uint64_t tag) {
4419void init_const_enum(ConstExprValue *const_val, TypeTableEntry *type, const BigInt *tag) {
42204420 const_val->special = ConstValSpecialStatic;
42214421 const_val->type = type;
4222 const_val->data.x_enum.tag = tag;
4422 bigint_init_bigint(&const_val->data.x_enum_tag, tag);
42234423}
42244424
4225ConstExprValue *create_const_enum_tag(TypeTableEntry *type, uint64_t tag) {
4425ConstExprValue *create_const_enum(TypeTableEntry *type, const BigInt *tag) {
42264426 ConstExprValue *const_val = create_const_vals(1);
4227 init_const_enum_tag(const_val, type, tag);
4427 init_const_enum(const_val, type, tag);
42284428 return const_val;
42294429}
42304430
4431
42314432void init_const_bool(CodeGen *g, ConstExprValue *const_val, bool value) {
42324433 const_val->special = ConstValSpecialStatic;
42334434 const_val->type = g->builtin_types.entry_bool;
......@@ -4426,19 +4627,22 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
44264627 case TypeTableEntryIdOpaque:
44274628 zig_unreachable();
44284629 case TypeTableEntryIdEnum:
4429 {
4430 ConstEnumValue *enum1 = &a->data.x_enum;
4431 ConstEnumValue *enum2 = &b->data.x_enum;
4432 if (enum1->tag == enum2->tag) {
4433 TypeEnumField *enum_field = &a->type->data.enumeration.fields[enum1->tag];
4434 if (type_has_bits(enum_field->type_entry)) {
4435 zig_panic("TODO const expr analyze enum special value for equality");
4436 } else {
4437 return true;
4438 }
4630 return bigint_cmp(&a->data.x_enum_tag, &b->data.x_enum_tag) == CmpEQ;
4631 case TypeTableEntryIdUnion: {
4632 ConstUnionValue *union1 = &a->data.x_union;
4633 ConstUnionValue *union2 = &b->data.x_union;
4634
4635 if (bigint_cmp(&union1->tag, &union2->tag) == CmpEQ) {
4636 TypeUnionField *field = find_union_field_by_tag(a->type, &union1->tag);
4637 assert(field != nullptr);
4638 if (type_has_bits(field->type_entry)) {
4639 zig_panic("TODO const expr analyze union field value for equality");
4640 } else {
4641 return true;
44394642 }
4440 return false;
44414643 }
4644 return false;
4645 }
44424646 case TypeTableEntryIdMetaType:
44434647 return a->data.x_type == b->data.x_type;
44444648 case TypeTableEntryIdVoid:
......@@ -4465,7 +4669,6 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
44654669 return bigfloat_cmp(&a->data.x_bigfloat, &b->data.x_bigfloat) == CmpEQ;
44664670 case TypeTableEntryIdInt:
44674671 case TypeTableEntryIdNumLitInt:
4468 case TypeTableEntryIdEnumTag:
44694672 return bigint_cmp(&a->data.x_bigint, &b->data.x_bigint) == CmpEQ;
44704673 case TypeTableEntryIdPointer:
44714674 if (a->data.x_ptr.special != b->data.x_ptr.special)
......@@ -4519,8 +4722,6 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
45194722 return false;
45204723 }
45214724 return true;
4522 case TypeTableEntryIdUnion:
4523 zig_panic("TODO");
45244725 case TypeTableEntryIdUndefLit:
45254726 zig_panic("TODO");
45264727 case TypeTableEntryIdNullLit:
......@@ -4664,7 +4865,7 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
46644865 buf_appendf(buf, "%s", buf_ptr(&const_val->data.x_type->name));
46654866 return;
46664867 case TypeTableEntryIdUnreachable:
4667 buf_appendf(buf, "@unreachable()");
4868 buf_appendf(buf, "unreachable");
46684869 return;
46694870 case TypeTableEntryIdBool:
46704871 {
......@@ -4794,7 +4995,8 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
47944995 }
47954996 case TypeTableEntryIdEnum:
47964997 {
4797 buf_appendf(buf, "(enum %s constant)", buf_ptr(&type_entry->name));
4998 TypeEnumField *field = find_enum_field_by_tag(type_entry, &const_val->data.x_enum_tag);
4999 buf_appendf(buf, "%s.%s", buf_ptr(&type_entry->name), buf_ptr(field->name));
47985000 return;
47995001 }
48005002 case TypeTableEntryIdErrorUnion:
......@@ -4812,14 +5014,6 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
48125014 buf_appendf(buf, "(pure error constant)");
48135015 return;
48145016 }
4815 case TypeTableEntryIdEnumTag:
4816 {
4817 TypeTableEntry *enum_type = type_entry->data.enum_tag.enum_type;
4818 size_t field_index = bigint_as_unsigned(&const_val->data.x_bigint);
4819 TypeEnumField *field = &enum_type->data.enumeration.fields[field_index];
4820 buf_appendf(buf, "%s.%s", buf_ptr(&enum_type->name), buf_ptr(field->name));
4821 return;
4822 }
48235017 case TypeTableEntryIdArgTuple:
48245018 {
48255019 buf_appendf(buf, "(args value)");
......@@ -4830,11 +5024,10 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
48305024}
48315025
48325026TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
4833 assert(size_in_bits > 0);
4834
48355027 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
48365028 entry->is_copyable = true;
4837 entry->type_ref = LLVMIntType(size_in_bits);
5029 entry->type_ref = (size_in_bits == 0) ? LLVMVoidType() : LLVMIntType(size_in_bits);
5030 entry->zero_bits = (size_in_bits == 0);
48385031
48395032 const char u_or_i = is_signed ? 'i' : 'u';
48405033 buf_resize(&entry->name, 0);
......@@ -4855,7 +5048,8 @@ TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits)
48555048 }
48565049 }
48575050
4858 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
5051 uint64_t debug_size_in_bits = (size_in_bits == 0) ?
5052 0 : (8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref));
48595053 entry->di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), debug_size_in_bits, dwarf_tag);
48605054 entry->data.integral.is_signed = is_signed;
48615055 entry->data.integral.bit_count = size_in_bits;
......@@ -4881,7 +5075,6 @@ uint32_t type_id_hash(TypeId x) {
48815075 case TypeTableEntryIdErrorUnion:
48825076 case TypeTableEntryIdPureError:
48835077 case TypeTableEntryIdEnum:
4884 case TypeTableEntryIdEnumTag:
48855078 case TypeTableEntryIdUnion:
48865079 case TypeTableEntryIdFn:
48875080 case TypeTableEntryIdNamespace:
......@@ -4926,7 +5119,6 @@ bool type_id_eql(TypeId a, TypeId b) {
49265119 case TypeTableEntryIdErrorUnion:
49275120 case TypeTableEntryIdPureError:
49285121 case TypeTableEntryIdEnum:
4929 case TypeTableEntryIdEnumTag:
49305122 case TypeTableEntryIdUnion:
49315123 case TypeTableEntryIdFn:
49325124 case TypeTableEntryIdNamespace:
......@@ -5041,7 +5233,6 @@ static const TypeTableEntryId all_type_ids[] = {
50415233 TypeTableEntryIdErrorUnion,
50425234 TypeTableEntryIdPureError,
50435235 TypeTableEntryIdEnum,
5044 TypeTableEntryIdEnumTag,
50455236 TypeTableEntryIdUnion,
50465237 TypeTableEntryIdFn,
50475238 TypeTableEntryIdNamespace,
......@@ -5099,22 +5290,20 @@ size_t type_id_index(TypeTableEntryId id) {
50995290 return 15;
51005291 case TypeTableEntryIdEnum:
51015292 return 16;
5102 case TypeTableEntryIdEnumTag:
5103 return 17;
51045293 case TypeTableEntryIdUnion:
5105 return 18;
5294 return 17;
51065295 case TypeTableEntryIdFn:
5107 return 19;
5296 return 18;
51085297 case TypeTableEntryIdNamespace:
5109 return 20;
5298 return 19;
51105299 case TypeTableEntryIdBlock:
5111 return 21;
5300 return 20;
51125301 case TypeTableEntryIdBoundFn:
5113 return 22;
5302 return 21;
51145303 case TypeTableEntryIdArgTuple:
5115 return 23;
5304 return 22;
51165305 case TypeTableEntryIdOpaque:
5117 return 24;
5306 return 23;
51185307 }
51195308 zig_unreachable();
51205309}
......@@ -5158,8 +5347,6 @@ const char *type_id_name(TypeTableEntryId id) {
51585347 return "Error";
51595348 case TypeTableEntryIdEnum:
51605349 return "Enum";
5161 case TypeTableEntryIdEnumTag:
5162 return "EnumTag";
51635350 case TypeTableEntryIdUnion:
51645351 return "Union";
51655352 case TypeTableEntryIdFn:
......@@ -5226,9 +5413,6 @@ uint32_t get_abi_alignment(CodeGen *g, TypeTableEntry *type_entry) {
52265413 if (type_entry->id == TypeTableEntryIdStruct) {
52275414 assert(type_entry->data.structure.abi_alignment != 0);
52285415 return type_entry->data.structure.abi_alignment;
5229 } else if (type_entry->id == TypeTableEntryIdEnum) {
5230 assert(type_entry->data.enumeration.abi_alignment != 0);
5231 return type_entry->data.enumeration.abi_alignment;
52325416 } else if (type_entry->id == TypeTableEntryIdUnion) {
52335417 assert(type_entry->data.unionation.abi_alignment != 0);
52345418 return type_entry->data.unionation.abi_alignment;
src/analyze.hpp+8-3
......@@ -64,6 +64,9 @@ TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name);
6464ScopeDecls *get_container_scope(TypeTableEntry *type_entry);
6565TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name);
6666TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name);
67TypeEnumField *find_enum_field_by_tag(TypeTableEntry *enum_type, const BigInt *tag);
68TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag);
69
6770bool is_container_ref(TypeTableEntry *type_entry);
6871void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node);
6972void scan_import(CodeGen *g, ImportTableEntry *import);
......@@ -109,6 +112,9 @@ ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str);
109112void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *c_str);
110113ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *c_str);
111114
115void init_const_bigint(ConstExprValue *const_val, TypeTableEntry *type, const BigInt *bigint);
116ConstExprValue *create_const_bigint(TypeTableEntry *type, const BigInt *bigint);
117
112118void init_const_unsigned_negative(ConstExprValue *const_val, TypeTableEntry *type, uint64_t x, bool negative);
113119ConstExprValue *create_const_unsigned_negative(TypeTableEntry *type, uint64_t x, bool negative);
114120
......@@ -121,8 +127,8 @@ ConstExprValue *create_const_usize(CodeGen *g, uint64_t x);
121127void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double value);
122128ConstExprValue *create_const_float(TypeTableEntry *type, double value);
123129
124void init_const_enum_tag(ConstExprValue *const_val, TypeTableEntry *type, uint64_t tag);
125ConstExprValue *create_const_enum_tag(TypeTableEntry *type, uint64_t tag);
130void init_const_enum(ConstExprValue *const_val, TypeTableEntry *type, const BigInt *tag);
131ConstExprValue *create_const_enum(TypeTableEntry *type, const BigInt *tag);
126132
127133void init_const_bool(CodeGen *g, ConstExprValue *const_val, bool value);
128134ConstExprValue *create_const_bool(CodeGen *g, bool value);
......@@ -158,7 +164,6 @@ ConstExprValue *create_const_vals(size_t count);
158164
159165TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
160166ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value);
161TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type);
162167void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
163168void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value);
164169
src/ast_render.cpp+18-1
......@@ -660,7 +660,20 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
660660 {
661661 const char *layout_str = layout_string(node->data.container_decl.layout);
662662 const char *container_str = container_string(node->data.container_decl.kind);
663 fprintf(ar->f, "%s%s {\n", layout_str, container_str);
663 fprintf(ar->f, "%s%s", layout_str, container_str);
664 if (node->data.container_decl.auto_enum) {
665 fprintf(ar->f, "(enum");
666 }
667 if (node->data.container_decl.init_arg_expr != nullptr) {
668 fprintf(ar->f, "(");
669 render_node_grouped(ar, node->data.container_decl.init_arg_expr);
670 fprintf(ar->f, ")");
671 }
672 if (node->data.container_decl.auto_enum) {
673 fprintf(ar->f, ")");
674 }
675
676 fprintf(ar->f, " {\n");
664677 ar->indent += ar->indent_size;
665678 for (size_t field_i = 0; field_i < node->data.container_decl.fields.length; field_i += 1) {
666679 AstNode *field_node = node->data.container_decl.fields.at(field_i);
......@@ -671,6 +684,10 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
671684 fprintf(ar->f, ": ");
672685 render_node_grouped(ar, field_node->data.struct_field.type);
673686 }
687 if (field_node->data.struct_field.value != nullptr) {
688 fprintf(ar->f, "= ");
689 render_node_grouped(ar, field_node->data.struct_field.value);
690 }
674691 fprintf(ar->f, ",\n");
675692 }
676693
src/bigint.cpp+32
......@@ -1224,3 +1224,35 @@ Cmp bigint_cmp_zero(const BigInt *op) {
12241224 }
12251225 return op->is_negative ? CmpLT : CmpGT;
12261226}
1227
1228uint32_t bigint_hash(BigInt x) {
1229 if (x.digit_count == 0) {
1230 return 0;
1231 } else {
1232 return bigint_ptr(&x)[0];
1233 }
1234}
1235
1236bool bigint_eql(BigInt a, BigInt b) {
1237 return bigint_cmp(&a, &b) == CmpEQ;
1238}
1239
1240void bigint_incr(BigInt *x) {
1241 if (x->digit_count == 0) {
1242 bigint_init_unsigned(x, 1);
1243 return;
1244 }
1245
1246 if (x->digit_count == 1 && x->data.digit != UINT64_MAX) {
1247 x->data.digit += 1;
1248 return;
1249 }
1250
1251 BigInt copy;
1252 bigint_init_bigint(&copy, x);
1253
1254 BigInt one;
1255 bigint_init_unsigned(&one, 1);
1256
1257 bigint_add(x, &copy, &one);
1258}
src/bigint.hpp+5
......@@ -88,6 +88,11 @@ size_t bigint_bits_needed(const BigInt *op);
8888// convenience functions
8989Cmp bigint_cmp_zero(const BigInt *op);
9090
91void bigint_incr(BigInt *value);
92
9193bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result);
9294
95uint32_t bigint_hash(BigInt x);
96bool bigint_eql(BigInt a, BigInt b);
97
9398#endif
src/codegen.cpp+105-180
......@@ -1362,8 +1362,12 @@ static LLVMValueRef bigint_to_llvm_const(LLVMTypeRef type_ref, BigInt *bigint) {
13621362 if (bigint->digit_count == 0) {
13631363 return LLVMConstNull(type_ref);
13641364 }
1365 LLVMValueRef unsigned_val = LLVMConstIntOfArbitraryPrecision(type_ref,
1366 bigint->digit_count, bigint_ptr(bigint));
1365 LLVMValueRef unsigned_val;
1366 if (bigint->digit_count == 1) {
1367 unsigned_val = LLVMConstInt(type_ref, bigint_ptr(bigint)[0], false);
1368 } else {
1369 unsigned_val = LLVMConstIntOfArbitraryPrecision(type_ref, bigint->digit_count, bigint_ptr(bigint));
1370 }
13671371 if (bigint->is_negative) {
13681372 return LLVMConstNeg(unsigned_val);
13691373 } else {
......@@ -1627,12 +1631,8 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
16271631 LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, type_entry->data.integral.is_signed);
16281632 return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, "");
16291633 } else if (type_entry->id == TypeTableEntryIdEnum) {
1630 if (type_entry->data.enumeration.gen_field_count == 0) {
1631 LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false);
1632 return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, "");
1633 } else {
1634 zig_unreachable();
1635 }
1634 LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false);
1635 return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, "");
16361636 } else if (type_entry->id == TypeTableEntryIdPureError ||
16371637 type_entry->id == TypeTableEntryIdPointer ||
16381638 type_entry->id == TypeTableEntryIdBool)
......@@ -1916,9 +1916,7 @@ static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executa
19161916 // enum_tag to the underlying int type
19171917 TypeTableEntry *int_type;
19181918 if (actual_type->id == TypeTableEntryIdEnum) {
1919 TypeTableEntry *tag_type = actual_type->data.enumeration.tag_type;
1920 assert(tag_type->id == TypeTableEntryIdEnumTag);
1921 int_type = tag_type->data.enum_tag.int_type;
1919 int_type = actual_type->data.enumeration.tag_int_type;
19221920 } else {
19231921 int_type = actual_type;
19241922 }
......@@ -1942,19 +1940,11 @@ static LLVMValueRef ir_render_ptr_to_int(CodeGen *g, IrExecutable *executable, I
19421940static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable, IrInstructionIntToEnum *instruction) {
19431941 TypeTableEntry *wanted_type = instruction->base.value.type;
19441942 assert(wanted_type->id == TypeTableEntryIdEnum);
1945 TypeTableEntry *tag_type = wanted_type->data.enumeration.tag_type;
1946 TypeTableEntry *wanted_int_type;
1947 if (tag_type->id == TypeTableEntryIdEnumTag) {
1948 wanted_int_type = tag_type->data.enum_tag.int_type;
1949 } else if (tag_type->id == TypeTableEntryIdInt) {
1950 wanted_int_type = tag_type;
1951 } else {
1952 zig_unreachable();
1953 }
1943 TypeTableEntry *tag_int_type = wanted_type->data.enumeration.tag_int_type;
19541944
19551945 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
19561946 return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),
1957 instruction->target->value.type, wanted_int_type, target_val);
1947 instruction->target->value.type, tag_int_type, target_val);
19581948}
19591949
19601950static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, IrInstructionIntToErr *instruction) {
......@@ -2374,27 +2364,6 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
23742364 return LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, "");
23752365}
23762366
2377static LLVMValueRef ir_render_enum_field_ptr(CodeGen *g, IrExecutable *executable,
2378 IrInstructionEnumFieldPtr *instruction)
2379{
2380 TypeTableEntry *enum_ptr_type = instruction->enum_ptr->value.type;
2381 assert(enum_ptr_type->id == TypeTableEntryIdPointer);
2382 TypeTableEntry *enum_type = enum_ptr_type->data.pointer.child_type;
2383 assert(enum_type->id == TypeTableEntryIdEnum);
2384
2385 TypeEnumField *field = instruction->field;
2386
2387 if (!type_has_bits(field->type_entry))
2388 return nullptr;
2389
2390 LLVMValueRef enum_ptr = ir_llvm_value(g, instruction->enum_ptr);
2391 LLVMTypeRef field_type_ref = LLVMPointerType(field->type_entry->type_ref, 0);
2392 LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, enum_ptr, enum_type->data.enumeration.gen_union_index, "");
2393 LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, "");
2394
2395 return bitcasted_union_field_ptr;
2396}
2397
23982367static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executable,
23992368 IrInstructionUnionFieldPtr *instruction)
24002369{
......@@ -2420,9 +2389,10 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
24202389 if (ir_want_debug_safety(g, &instruction->base)) {
24212390 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
24222391 LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, "");
2423 LLVMValueRef expected_tag_value = LLVMConstInt(union_type->data.unionation.tag_type->type_ref,
2424 field->value, false);
24252392
2393
2394 LLVMValueRef expected_tag_value = bigint_to_llvm_const(union_type->data.unionation.tag_type->type_ref,
2395 &field->enum_field->value);
24262396 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnionCheckOk");
24272397 LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnionCheckFail");
24282398 LLVMValueRef ok_val = LLVMBuildICmp(g->builder, LLVMIntEQ, tag_value, expected_tag_value, "");
......@@ -2747,21 +2717,21 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI
27472717}
27482718
27492719static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable,
2750 IrInstructionEnumTagName *instruction)
2720 IrInstructionTagName *instruction)
27512721{
2752 TypeTableEntry *enum_tag_type = instruction->target->value.type;
2753 assert(enum_tag_type->data.enum_tag.generate_name_table);
2722 TypeTableEntry *enum_type = instruction->target->value.type;
2723 assert(enum_type->id == TypeTableEntryIdEnum);
2724 assert(enum_type->data.enumeration.generate_name_table);
27542725
2726 TypeTableEntry *tag_int_type = enum_type->data.enumeration.tag_int_type;
27552727 LLVMValueRef enum_tag_value = ir_llvm_value(g, instruction->target);
27562728 if (ir_want_debug_safety(g, &instruction->base)) {
2757 TypeTableEntry *enum_type = enum_tag_type->data.enum_tag.enum_type;
27582729 size_t field_count = enum_type->data.enumeration.src_field_count;
27592730
2760 // if the field_count can't fit in the bits of the enum_tag_type, then it can't possibly
2731 // if the field_count can't fit in the bits of the enum_type, then it can't possibly
27612732 // be the wrong value
27622733 BigInt field_bi;
27632734 bigint_init_unsigned(&field_bi, field_count);
2764 TypeTableEntry *tag_int_type = enum_tag_type->data.enum_tag.int_type;
27652735 if (bigint_fits_in_bits(&field_bi, tag_int_type->data.integral.bit_count, false)) {
27662736 LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(enum_tag_value), field_count, false);
27672737 add_bounds_check(g, enum_tag_value, LLVMIntEQ, nullptr, LLVMIntULT, end_val);
......@@ -2770,10 +2740,10 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable
27702740
27712741 LLVMValueRef indices[] = {
27722742 LLVMConstNull(g->builtin_types.entry_usize->type_ref),
2773 gen_widen_or_shorten(g, false, enum_tag_type->data.enum_tag.int_type,
2743 gen_widen_or_shorten(g, false, tag_int_type,
27742744 g->builtin_types.entry_usize, enum_tag_value),
27752745 };
2776 return LLVMBuildInBoundsGEP(g->builder, enum_tag_type->data.enum_tag.name_table, indices, 2, "");
2746 return LLVMBuildInBoundsGEP(g->builder, enum_type->data.enumeration.name_table, indices, 2, "");
27772747}
27782748
27792749static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, IrExecutable *executable,
......@@ -3347,48 +3317,24 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
33473317 return instruction->tmp_ptr;
33483318}
33493319
3350static LLVMValueRef ir_render_enum_tag(CodeGen *g, IrExecutable *executable, IrInstructionEnumTag *instruction) {
3351 TypeTableEntry *enum_type = instruction->value->value.type;
3352 TypeTableEntry *tag_type = enum_type->data.enumeration.tag_type;
3320static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, IrInstructionUnionTag *instruction) {
3321 TypeTableEntry *union_type = instruction->value->value.type;
3322 assert(union_type->data.unionation.gen_tag_index != SIZE_MAX);
3323
3324 TypeTableEntry *tag_type = union_type->data.unionation.tag_type;
33533325 if (!type_has_bits(tag_type))
33543326 return nullptr;
33553327
3356 LLVMValueRef enum_val = ir_llvm_value(g, instruction->value);
3357 if (enum_type->data.enumeration.gen_field_count == 0)
3358 return enum_val;
3328 LLVMValueRef union_val = ir_llvm_value(g, instruction->value);
3329 if (union_type->data.unionation.gen_field_count == 0)
3330 return union_val;
33593331
3360 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, enum_val, enum_type->data.enumeration.gen_tag_index, "");
3332 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_val,
3333 union_type->data.unionation.gen_tag_index, "");
33613334 TypeTableEntry *ptr_type = get_pointer_to_type(g, tag_type, false);
33623335 return get_handle_value(g, tag_field_ptr, tag_type, ptr_type);
33633336}
33643337
3365static LLVMValueRef ir_render_init_enum(CodeGen *g, IrExecutable *executable, IrInstructionInitEnum *instruction) {
3366 TypeTableEntry *enum_type = instruction->enum_type;
3367 uint32_t value = instruction->field->value;
3368 LLVMTypeRef tag_type_ref = enum_type->data.enumeration.tag_type->type_ref;
3369 LLVMValueRef tag_value = LLVMConstInt(tag_type_ref, value, false);
3370
3371 if (enum_type->data.enumeration.gen_field_count == 0)
3372 return tag_value;
3373
3374 LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;
3375
3376 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_type->data.enumeration.gen_tag_index, "");
3377 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
3378
3379 TypeTableEntry *union_val_type = instruction->field->type_entry;
3380 if (type_has_bits(union_val_type)) {
3381 LLVMValueRef new_union_val = ir_llvm_value(g, instruction->init_value);
3382 LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_type->data.enumeration.gen_union_index, "");
3383 LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr,
3384 LLVMPointerType(union_val_type->type_ref, 0), "");
3385
3386 gen_assign_raw(g, bitcasted_union_field_ptr, get_pointer_to_type(g, union_val_type, false), new_union_val);
3387 }
3388
3389 return tmp_struct_ptr;
3390}
3391
33923338static LLVMValueRef ir_render_struct_init(CodeGen *g, IrExecutable *executable, IrInstructionStructInit *instruction) {
33933339 for (size_t i = 0; i < instruction->field_count; i += 1) {
33943340 IrInstructionStructInitField *field = &instruction->fields[i];
......@@ -3429,8 +3375,9 @@ static LLVMValueRef ir_render_union_init(CodeGen *g, IrExecutable *executable, I
34293375 if (union_type->data.unionation.gen_tag_index != SIZE_MAX) {
34303376 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,
34313377 union_type->data.unionation.gen_tag_index, "");
3432 LLVMValueRef tag_value = LLVMConstInt(union_type->data.unionation.tag_type->type_ref,
3433 type_union_field->value, false);
3378
3379 LLVMValueRef tag_value = bigint_to_llvm_const(union_type->data.unionation.tag_type->type_ref,
3380 &type_union_field->enum_field->value);
34343381 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
34353382
34363383 uncasted_union_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,
......@@ -3537,6 +3484,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
35373484 case IrInstructionIdOpaqueType:
35383485 case IrInstructionIdSetAlignStack:
35393486 case IrInstructionIdArgType:
3487 case IrInstructionIdTagType:
35403488 zig_unreachable();
35413489 case IrInstructionIdReturn:
35423490 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
......@@ -3566,8 +3514,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
35663514 return ir_render_call(g, executable, (IrInstructionCall *)instruction);
35673515 case IrInstructionIdStructFieldPtr:
35683516 return ir_render_struct_field_ptr(g, executable, (IrInstructionStructFieldPtr *)instruction);
3569 case IrInstructionIdEnumFieldPtr:
3570 return ir_render_enum_field_ptr(g, executable, (IrInstructionEnumFieldPtr *)instruction);
35713517 case IrInstructionIdUnionFieldPtr:
35723518 return ir_render_union_field_ptr(g, executable, (IrInstructionUnionFieldPtr *)instruction);
35733519 case IrInstructionIdAsm:
......@@ -3622,10 +3568,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
36223568 return ir_render_err_wrap_code(g, executable, (IrInstructionErrWrapCode *)instruction);
36233569 case IrInstructionIdErrWrapPayload:
36243570 return ir_render_err_wrap_payload(g, executable, (IrInstructionErrWrapPayload *)instruction);
3625 case IrInstructionIdEnumTag:
3626 return ir_render_enum_tag(g, executable, (IrInstructionEnumTag *)instruction);
3627 case IrInstructionIdInitEnum:
3628 return ir_render_init_enum(g, executable, (IrInstructionInitEnum *)instruction);
3571 case IrInstructionIdUnionTag:
3572 return ir_render_union_tag(g, executable, (IrInstructionUnionTag *)instruction);
36293573 case IrInstructionIdStructInit:
36303574 return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction);
36313575 case IrInstructionIdUnionInit:
......@@ -3650,8 +3594,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
36503594 return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction);
36513595 case IrInstructionIdPanic:
36523596 return ir_render_panic(g, executable, (IrInstructionPanic *)instruction);
3653 case IrInstructionIdEnumTagName:
3654 return ir_render_enum_tag_name(g, executable, (IrInstructionEnumTagName *)instruction);
3597 case IrInstructionIdTagName:
3598 return ir_render_enum_tag_name(g, executable, (IrInstructionTagName *)instruction);
36553599 case IrInstructionIdFieldParentPtr:
36563600 return ir_render_field_parent_ptr(g, executable, (IrInstructionFieldParentPtr *)instruction);
36573601 case IrInstructionIdAlignCast:
......@@ -3761,8 +3705,6 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
37613705 case TypeTableEntryIdNullLit:
37623706 case TypeTableEntryIdErrorUnion:
37633707 case TypeTableEntryIdPureError:
3764 case TypeTableEntryIdEnum:
3765 case TypeTableEntryIdEnumTag:
37663708 case TypeTableEntryIdNamespace:
37673709 case TypeTableEntryIdBlock:
37683710 case TypeTableEntryIdBoundFn:
......@@ -3772,6 +3714,12 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
37723714 zig_unreachable();
37733715 case TypeTableEntryIdBool:
37743716 return LLVMConstInt(big_int_type_ref, const_val->data.x_bool ? 1 : 0, false);
3717 case TypeTableEntryIdEnum:
3718 {
3719 assert(type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr);
3720 LLVMValueRef int_val = gen_const_val(g, const_val);
3721 return LLVMConstZExt(int_val, big_int_type_ref);
3722 }
37753723 case TypeTableEntryIdInt:
37763724 {
37773725 LLVMValueRef int_val = gen_const_val(g, const_val);
......@@ -3813,6 +3761,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
38133761 }
38143762 return val;
38153763 }
3764
38163765 }
38173766 zig_unreachable();
38183767}
......@@ -3838,7 +3787,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
38383787
38393788 switch (type_entry->id) {
38403789 case TypeTableEntryIdInt:
3841 case TypeTableEntryIdEnumTag:
38423790 return bigint_to_llvm_const(type_entry->type_ref, &const_val->data.x_bigint);
38433791 case TypeTableEntryIdPureError:
38443792 assert(const_val->data.x_pure_err);
......@@ -4001,37 +3949,52 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
40013949 ConstExprValue *payload_value = const_val->data.x_union.payload;
40023950 assert(payload_value != nullptr);
40033951
4004 if (!type_has_bits(payload_value->type)) {
4005 return LLVMGetUndef(union_type_ref);
3952 if (type_entry->data.unionation.gen_field_count == 0) {
3953 if (type_entry->data.unionation.gen_tag_index == SIZE_MAX) {
3954 return nullptr;
3955 } else {
3956 return bigint_to_llvm_const(type_entry->data.unionation.tag_type->type_ref,
3957 &const_val->data.x_union.tag);
3958 }
40063959 }
40073960
4008 uint64_t field_type_bytes = LLVMStoreSizeOfType(g->target_data_ref, payload_value->type->type_ref);
4009 uint64_t pad_bytes = type_entry->data.unionation.union_size_bytes - field_type_bytes;
4010 LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value);
4011 bool make_unnamed_struct = is_llvm_value_unnamed_type(payload_value->type, correctly_typed_value) ||
4012 payload_value->type != type_entry->data.unionation.most_aligned_union_member;
4013
40143961 LLVMValueRef union_value_ref;
4015 {
4016 if (pad_bytes == 0) {
4017 union_value_ref = correctly_typed_value;
4018 } else {
4019 LLVMValueRef fields[2];
4020 fields[0] = correctly_typed_value;
4021 fields[1] = LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), (unsigned)pad_bytes));
4022 if (make_unnamed_struct || type_entry->data.unionation.gen_tag_index != SIZE_MAX) {
4023 union_value_ref = LLVMConstStruct(fields, 2, false);
3962 bool make_unnamed_struct;
3963 if (!type_has_bits(payload_value->type)) {
3964 if (type_entry->data.unionation.gen_tag_index == SIZE_MAX)
3965 return LLVMGetUndef(type_entry->type_ref);
3966
3967 union_value_ref = LLVMGetUndef(type_entry->data.unionation.most_aligned_union_member->type_ref);
3968 make_unnamed_struct = false;
3969 } else {
3970 uint64_t field_type_bytes = LLVMStoreSizeOfType(g->target_data_ref, payload_value->type->type_ref);
3971 uint64_t pad_bytes = type_entry->data.unionation.union_size_bytes - field_type_bytes;
3972 LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value);
3973 make_unnamed_struct = is_llvm_value_unnamed_type(payload_value->type, correctly_typed_value) ||
3974 payload_value->type != type_entry->data.unionation.most_aligned_union_member;
3975
3976 {
3977 if (pad_bytes == 0) {
3978 union_value_ref = correctly_typed_value;
40243979 } else {
4025 union_value_ref = LLVMConstNamedStruct(union_type_ref, fields, 2);
3980 LLVMValueRef fields[2];
3981 fields[0] = correctly_typed_value;
3982 fields[1] = LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), (unsigned)pad_bytes));
3983 if (make_unnamed_struct || type_entry->data.unionation.gen_tag_index != SIZE_MAX) {
3984 union_value_ref = LLVMConstStruct(fields, 2, false);
3985 } else {
3986 union_value_ref = LLVMConstNamedStruct(union_type_ref, fields, 2);
3987 }
40263988 }
40273989 }
4028 }
40293990
4030 if (type_entry->data.unionation.gen_tag_index == SIZE_MAX) {
4031 return union_value_ref;
3991 if (type_entry->data.unionation.gen_tag_index == SIZE_MAX) {
3992 return union_value_ref;
3993 }
40323994 }
40333995
4034 LLVMValueRef tag_value = LLVMConstInt(type_entry->data.unionation.tag_type->type_ref, const_val->data.x_union.tag, false);
3996 LLVMValueRef tag_value = bigint_to_llvm_const(type_entry->data.unionation.tag_type->type_ref,
3997 &const_val->data.x_union.tag);
40353998
40363999 LLVMValueRef fields[2];
40374000 fields[type_entry->data.unionation.gen_union_index] = union_value_ref;
......@@ -4044,55 +4007,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
40444007 }
40454008
40464009 }
4047 case TypeTableEntryIdEnum:
4048 {
4049 LLVMTypeRef tag_type_ref = type_entry->data.enumeration.tag_type->type_ref;
4050 LLVMValueRef tag_value = LLVMConstInt(tag_type_ref, const_val->data.x_enum.tag, false);
4051 if (type_entry->data.enumeration.gen_field_count == 0) {
4052 return tag_value;
4053 } else {
4054 LLVMTypeRef union_type_ref = type_entry->data.enumeration.union_type_ref;
4055 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag];
4056 assert(enum_field->value == const_val->data.x_enum.tag);
4057 LLVMValueRef union_value;
40584010
4059 bool make_unnamed_struct;
4060
4061 if (type_has_bits(enum_field->type_entry)) {
4062 uint64_t field_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,
4063 enum_field->type_entry->type_ref);
4064 uint64_t pad_bytes = type_entry->data.enumeration.union_size_bytes - field_type_bytes;
4065
4066 ConstExprValue *payload_value = const_val->data.x_enum.payload;
4067 LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value);
4068
4069 make_unnamed_struct = is_llvm_value_unnamed_type(payload_value->type, correctly_typed_value) ||
4070 payload_value->type != type_entry->data.enumeration.most_aligned_union_member;
4071
4072 if (pad_bytes == 0) {
4073 union_value = correctly_typed_value;
4074 } else {
4075 LLVMValueRef fields[] = {
4076 correctly_typed_value,
4077 LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), (unsigned)pad_bytes)),
4078 };
4079 union_value = LLVMConstStruct(fields, 2, false);
4080 }
4081 } else {
4082 make_unnamed_struct = false;
4083 union_value = LLVMGetUndef(union_type_ref);
4084 }
4085 LLVMValueRef fields[2];
4086 fields[type_entry->data.enumeration.gen_tag_index] = tag_value;
4087 fields[type_entry->data.enumeration.gen_union_index] = union_value;
4088
4089 if (make_unnamed_struct) {
4090 return LLVMConstStruct(fields, 2, false);
4091 } else {
4092 return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
4093 }
4094 }
4095 }
4011 case TypeTableEntryIdEnum:
4012 return bigint_to_llvm_const(type_entry->type_ref, &const_val->data.x_enum_tag);
40964013 case TypeTableEntryIdFn:
40974014 return fn_llvm_value(g, const_val->data.x_fn.fn_entry);
40984015 case TypeTableEntryIdPointer:
......@@ -4303,9 +4220,8 @@ static void generate_enum_name_tables(CodeGen *g) {
43034220
43044221
43054222 for (size_t enum_i = 0; enum_i < g->name_table_enums.length; enum_i += 1) {
4306 TypeTableEntry *enum_tag_type = g->name_table_enums.at(enum_i);
4307 assert(enum_tag_type->id == TypeTableEntryIdEnumTag);
4308 TypeTableEntry *enum_type = enum_tag_type->data.enum_tag.enum_type;
4223 TypeTableEntry *enum_type = g->name_table_enums.at(enum_i);
4224 assert(enum_type->id == TypeTableEntryIdEnum);
43094225
43104226 size_t field_count = enum_type->data.enumeration.src_field_count;
43114227 LLVMValueRef *values = allocate<LLVMValueRef>(field_count);
......@@ -4336,7 +4252,7 @@ static void generate_enum_name_tables(CodeGen *g) {
43364252 LLVMSetGlobalConstant(name_table, true);
43374253 LLVMSetUnnamedAddr(name_table, true);
43384254 LLVMSetAlignment(name_table, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(name_table_init)));
4339 enum_tag_type->data.enum_tag.name_table = name_table;
4255 enum_type->data.enumeration.name_table = name_table;
43404256 }
43414257}
43424258
......@@ -4540,9 +4456,6 @@ static void do_code_gen(CodeGen *g) {
45404456 } else if (instruction->id == IrInstructionIdErrWrapCode) {
45414457 IrInstructionErrWrapCode *err_wrap_code_instruction = (IrInstructionErrWrapCode *)instruction;
45424458 slot = &err_wrap_code_instruction->tmp_ptr;
4543 } else if (instruction->id == IrInstructionIdInitEnum) {
4544 IrInstructionInitEnum *init_enum_instruction = (IrInstructionInitEnum *)instruction;
4545 slot = &init_enum_instruction->tmp_ptr;
45464459 } else {
45474460 zig_unreachable();
45484461 }
......@@ -5039,7 +4952,7 @@ static void define_builtin_fns(CodeGen *g) {
50394952 create_builtin_fn(g, BuiltinFnIdTruncate, "truncate", 2);
50404953 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);
50414954 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
5042 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2);
4955 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
50434956 create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);
50444957 create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2);
50454958 create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
......@@ -5049,7 +4962,8 @@ static void define_builtin_fns(CodeGen *g) {
50494962 create_builtin_fn(g, BuiltinFnIdBitCast, "bitCast", 2);
50504963 create_builtin_fn(g, BuiltinFnIdIntToPtr, "intToPtr", 2);
50514964 create_builtin_fn(g, BuiltinFnIdPtrToInt, "ptrToInt", 1);
5052 create_builtin_fn(g, BuiltinFnIdEnumTagName, "enumTagName", 1);
4965 create_builtin_fn(g, BuiltinFnIdTagName, "tagName", 1);
4966 create_builtin_fn(g, BuiltinFnIdTagType, "TagType", 1);
50534967 create_builtin_fn(g, BuiltinFnIdFieldParentPtr, "fieldParentPtr", 3);
50544968 create_builtin_fn(g, BuiltinFnIdOffsetOf, "offsetOf", 2);
50554969 create_builtin_fn(g, BuiltinFnIdDivExact, "divExact", 2);
......@@ -5215,7 +5129,19 @@ static void define_builtin_compile_vars(CodeGen *g) {
52155129 assert(FloatModeOptimized == 0);
52165130 assert(FloatModeStrict == 1);
52175131 }
5218 buf_appendf(contents, "pub const is_big_endian = %s;\n", bool_to_str(g->is_big_endian));
5132 {
5133 buf_appendf(contents,
5134 "pub const Endian = enum {\n"
5135 " Big,\n"
5136 " Little,\n"
5137 "};\n\n");
5138 assert(FloatModeOptimized == 0);
5139 assert(FloatModeStrict == 1);
5140 }
5141 {
5142 const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little";
5143 buf_appendf(contents, "pub const endian = %s;\n", endian_str);
5144 }
52195145 buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build));
52205146 buf_appendf(contents, "pub const os = Os.%s;\n", cur_os);
52215147 buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch);
......@@ -5665,7 +5591,6 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
56655591 case TypeTableEntryIdEnum:
56665592 case TypeTableEntryIdUnion:
56675593 case TypeTableEntryIdFn:
5668 case TypeTableEntryIdEnumTag:
56695594 zig_panic("TODO implement get_c_type for more types");
56705595 case TypeTableEntryIdInvalid:
56715596 case TypeTableEntryIdMetaType:
src/errmsg.cpp+4-4
......@@ -24,20 +24,20 @@ static void print_err_msg_type(ErrorMsg *err, ErrColor color, ErrType err_type)
2424 bool is_tty = os_stderr_tty();
2525 if (color == ErrColorOn || (color == ErrColorAuto && is_tty)) {
2626 if (err_type == ErrTypeError) {
27 os_stderr_set_color(TermColorWhite);
27 os_stderr_set_color(TermColorBold);
2828 fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": ", path, line, col);
2929 os_stderr_set_color(TermColorRed);
3030 fprintf(stderr, "error:");
31 os_stderr_set_color(TermColorWhite);
31 os_stderr_set_color(TermColorBold);
3232 fprintf(stderr, " %s", text);
3333 os_stderr_set_color(TermColorReset);
3434 fprintf(stderr, "\n");
3535 } else if (err_type == ErrTypeNote) {
36 os_stderr_set_color(TermColorWhite);
36 os_stderr_set_color(TermColorBold);
3737 fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": ", path, line, col);
3838 os_stderr_set_color(TermColorCyan);
3939 fprintf(stderr, "note:");
40 os_stderr_set_color(TermColorWhite);
40 os_stderr_set_color(TermColorBold);
4141 fprintf(stderr, " %s", text);
4242 os_stderr_set_color(TermColorReset);
4343 fprintf(stderr, "\n");
src/error.cpp+1
......@@ -26,6 +26,7 @@ const char *err_str(int err) {
2626 case ErrorExactDivRemainder: return "exact division had a remainder";
2727 case ErrorNegativeDenominator: return "negative denominator";
2828 case ErrorShiftedOutOneBits: return "exact shift shifted out one bits";
29 case ErrorCCompileErrors: return "C compile errors";
2930 }
3031 return "(invalid error)";
3132}
src/error.hpp+1
......@@ -26,6 +26,7 @@ enum Error {
2626 ErrorExactDivRemainder,
2727 ErrorNegativeDenominator,
2828 ErrorShiftedOutOneBits,
29 ErrorCCompileErrors,
2930};
3031
3132const char *err_str(int err);
src/ir.cpp+346-295
......@@ -223,10 +223,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr *
223223 return IrInstructionIdStructFieldPtr;
224224}
225225
226static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumFieldPtr *) {
227 return IrInstructionIdEnumFieldPtr;
228}
229
230226static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionFieldPtr *) {
231227 return IrInstructionIdUnionFieldPtr;
232228}
......@@ -319,8 +315,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCtz *) {
319315 return IrInstructionIdCtz;
320316}
321317
322static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumTag *) {
323 return IrInstructionIdEnumTag;
318static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) {
319 return IrInstructionIdUnionTag;
324320}
325321
326322static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) {
......@@ -479,10 +475,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTestComptime *)
479475 return IrInstructionIdTestComptime;
480476}
481477
482static constexpr IrInstructionId ir_instruction_id(IrInstructionInitEnum *) {
483 return IrInstructionIdInitEnum;
484}
485
486478static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCast *) {
487479 return IrInstructionIdPtrCast;
488480}
......@@ -547,8 +539,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPanic *) {
547539 return IrInstructionIdPanic;
548540}
549541
550static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumTagName *) {
551 return IrInstructionIdEnumTagName;
542static constexpr IrInstructionId ir_instruction_id(IrInstructionTagName *) {
543 return IrInstructionIdTagName;
544}
545
546static constexpr IrInstructionId ir_instruction_id(IrInstructionTagType *) {
547 return IrInstructionIdTagType;
552548}
553549
554550static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldParentPtr *) {
......@@ -909,27 +905,6 @@ static IrInstruction *ir_build_struct_field_ptr_from(IrBuilder *irb, IrInstructi
909905 return new_instruction;
910906}
911907
912static IrInstruction *ir_build_enum_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
913 IrInstruction *enum_ptr, TypeEnumField *field)
914{
915 IrInstructionEnumFieldPtr *instruction = ir_build_instruction<IrInstructionEnumFieldPtr>(irb, scope, source_node);
916 instruction->enum_ptr = enum_ptr;
917 instruction->field = field;
918
919 ir_ref_instruction(enum_ptr, irb->current_basic_block);
920
921 return &instruction->base;
922}
923
924static IrInstruction *ir_build_enum_field_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,
925 IrInstruction *enum_ptr, TypeEnumField *type_enum_field)
926{
927 IrInstruction *new_instruction = ir_build_enum_field_ptr(irb, old_instruction->scope,
928 old_instruction->source_node, enum_ptr, type_enum_field);
929 ir_link_new_instruction(new_instruction, old_instruction);
930 return new_instruction;
931}
932
933908static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
934909 IrInstruction *union_ptr, TypeUnionField *field)
935910{
......@@ -1524,8 +1499,8 @@ static IrInstruction *ir_build_switch_var(IrBuilder *irb, Scope *scope, AstNode
15241499 return &instruction->base;
15251500}
15261501
1527static IrInstruction *ir_build_enum_tag(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1528 IrInstructionEnumTag *instruction = ir_build_instruction<IrInstructionEnumTag>(irb, scope, source_node);
1502static IrInstruction *ir_build_union_tag(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1503 IrInstructionUnionTag *instruction = ir_build_instruction<IrInstructionUnionTag>(irb, scope, source_node);
15291504 instruction->value = value;
15301505
15311506 ir_ref_instruction(value, irb->current_basic_block);
......@@ -1533,13 +1508,6 @@ static IrInstruction *ir_build_enum_tag(IrBuilder *irb, Scope *scope, AstNode *s
15331508 return &instruction->base;
15341509}
15351510
1536static IrInstruction *ir_build_enum_tag_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) {
1537 IrInstruction *new_instruction = ir_build_enum_tag(irb, old_instruction->scope,
1538 old_instruction->source_node, value);
1539 ir_link_new_instruction(new_instruction, old_instruction);
1540 return new_instruction;
1541}
1542
15431511static IrInstruction *ir_build_import(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) {
15441512 IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, scope, source_node);
15451513 instruction->name = name;
......@@ -2029,28 +1997,6 @@ static IrInstruction *ir_build_test_comptime(IrBuilder *irb, Scope *scope, AstNo
20291997 return &instruction->base;
20301998}
20311999
2032static IrInstruction *ir_build_init_enum(IrBuilder *irb, Scope *scope, AstNode *source_node,
2033 TypeTableEntry *enum_type, TypeEnumField *field, IrInstruction *init_value)
2034{
2035 IrInstructionInitEnum *instruction = ir_build_instruction<IrInstructionInitEnum>(irb, scope, source_node);
2036 instruction->enum_type = enum_type;
2037 instruction->field = field;
2038 instruction->init_value = init_value;
2039
2040 ir_ref_instruction(init_value, irb->current_basic_block);
2041
2042 return &instruction->base;
2043}
2044
2045static IrInstruction *ir_build_init_enum_from(IrBuilder *irb, IrInstruction *old_instruction,
2046 TypeTableEntry *enum_type, TypeEnumField *field, IrInstruction *init_value)
2047{
2048 IrInstruction *new_instruction = ir_build_init_enum(irb, old_instruction->scope, old_instruction->source_node,
2049 enum_type, field, init_value);
2050 ir_link_new_instruction(new_instruction, old_instruction);
2051 return new_instruction;
2052}
2053
20542000static IrInstruction *ir_build_ptr_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
20552001 IrInstruction *dest_type, IrInstruction *ptr)
20562002{
......@@ -2259,10 +2205,21 @@ static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *sour
22592205 return &instruction->base;
22602206}
22612207
2262static IrInstruction *ir_build_enum_tag_name(IrBuilder *irb, Scope *scope, AstNode *source_node,
2208static IrInstruction *ir_build_tag_name(IrBuilder *irb, Scope *scope, AstNode *source_node,
22632209 IrInstruction *target)
22642210{
2265 IrInstructionEnumTagName *instruction = ir_build_instruction<IrInstructionEnumTagName>(irb, scope, source_node);
2211 IrInstructionTagName *instruction = ir_build_instruction<IrInstructionTagName>(irb, scope, source_node);
2212 instruction->target = target;
2213
2214 ir_ref_instruction(target, irb->current_basic_block);
2215
2216 return &instruction->base;
2217}
2218
2219static IrInstruction *ir_build_tag_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
2220 IrInstruction *target)
2221{
2222 IrInstructionTagType *instruction = ir_build_instruction<IrInstructionTagType>(irb, scope, source_node);
22662223 instruction->target = target;
22672224
22682225 ir_ref_instruction(target, irb->current_basic_block);
......@@ -2466,13 +2423,6 @@ static IrInstruction *ir_instruction_structfieldptr_get_dep(IrInstructionStructF
24662423 }
24672424}
24682425
2469static IrInstruction *ir_instruction_enumfieldptr_get_dep(IrInstructionEnumFieldPtr *instruction, size_t index) {
2470 switch (index) {
2471 case 0: return instruction->enum_ptr;
2472 default: return nullptr;
2473 }
2474}
2475
24762426static IrInstruction *ir_instruction_unionfieldptr_get_dep(IrInstructionUnionFieldPtr *instruction, size_t index) {
24772427 switch (index) {
24782428 case 0: return instruction->union_ptr;
......@@ -2642,7 +2592,7 @@ static IrInstruction *ir_instruction_maybewrap_get_dep(IrInstructionMaybeWrap *i
26422592 }
26432593}
26442594
2645static IrInstruction *ir_instruction_enumtag_get_dep(IrInstructionEnumTag *instruction, size_t index) {
2595static IrInstruction *ir_instruction_uniontag_get_dep(IrInstructionUnionTag *instruction, size_t index) {
26462596 switch (index) {
26472597 case 0: return instruction->value;
26482598 default: return nullptr;
......@@ -2928,13 +2878,6 @@ static IrInstruction *ir_instruction_testcomptime_get_dep(IrInstructionTestCompt
29282878 }
29292879}
29302880
2931static IrInstruction *ir_instruction_initenum_get_dep(IrInstructionInitEnum *instruction, size_t index) {
2932 switch (index) {
2933 case 0: return instruction->init_value;
2934 default: return nullptr;
2935 }
2936}
2937
29382881static IrInstruction *ir_instruction_ptrcast_get_dep(IrInstructionPtrCast *instruction,
29392882 size_t index)
29402883{
......@@ -3059,7 +3002,14 @@ static IrInstruction *ir_instruction_panic_get_dep(IrInstructionPanic *instructi
30593002 }
30603003}
30613004
3062static IrInstruction *ir_instruction_enumtagname_get_dep(IrInstructionEnumTagName *instruction, size_t index) {
3005static IrInstruction *ir_instruction_enumtagname_get_dep(IrInstructionTagName *instruction, size_t index) {
3006 switch (index) {
3007 case 0: return instruction->target;
3008 default: return nullptr;
3009 }
3010}
3011
3012static IrInstruction *ir_instruction_enumtagtype_get_dep(IrInstructionTagType *instruction, size_t index) {
30633013 switch (index) {
30643014 case 0: return instruction->target;
30653015 default: return nullptr;
......@@ -3162,8 +3112,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
31623112 return ir_instruction_fieldptr_get_dep((IrInstructionFieldPtr *) instruction, index);
31633113 case IrInstructionIdStructFieldPtr:
31643114 return ir_instruction_structfieldptr_get_dep((IrInstructionStructFieldPtr *) instruction, index);
3165 case IrInstructionIdEnumFieldPtr:
3166 return ir_instruction_enumfieldptr_get_dep((IrInstructionEnumFieldPtr *) instruction, index);
31673115 case IrInstructionIdUnionFieldPtr:
31683116 return ir_instruction_unionfieldptr_get_dep((IrInstructionUnionFieldPtr *) instruction, index);
31693117 case IrInstructionIdElemPtr:
......@@ -3212,8 +3160,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
32123160 return ir_instruction_unwrapmaybe_get_dep((IrInstructionUnwrapMaybe *) instruction, index);
32133161 case IrInstructionIdMaybeWrap:
32143162 return ir_instruction_maybewrap_get_dep((IrInstructionMaybeWrap *) instruction, index);
3215 case IrInstructionIdEnumTag:
3216 return ir_instruction_enumtag_get_dep((IrInstructionEnumTag *) instruction, index);
3163 case IrInstructionIdUnionTag:
3164 return ir_instruction_uniontag_get_dep((IrInstructionUnionTag *) instruction, index);
32173165 case IrInstructionIdClz:
32183166 return ir_instruction_clz_get_dep((IrInstructionClz *) instruction, index);
32193167 case IrInstructionIdCtz:
......@@ -3290,8 +3238,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
32903238 return ir_instruction_fnproto_get_dep((IrInstructionFnProto *) instruction, index);
32913239 case IrInstructionIdTestComptime:
32923240 return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index);
3293 case IrInstructionIdInitEnum:
3294 return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index);
32953241 case IrInstructionIdPtrCast:
32963242 return ir_instruction_ptrcast_get_dep((IrInstructionPtrCast *) instruction, index);
32973243 case IrInstructionIdBitCast:
......@@ -3324,8 +3270,10 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
33243270 return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index);
33253271 case IrInstructionIdPanic:
33263272 return ir_instruction_panic_get_dep((IrInstructionPanic *) instruction, index);
3327 case IrInstructionIdEnumTagName:
3328 return ir_instruction_enumtagname_get_dep((IrInstructionEnumTagName *) instruction, index);
3273 case IrInstructionIdTagName:
3274 return ir_instruction_enumtagname_get_dep((IrInstructionTagName *) instruction, index);
3275 case IrInstructionIdTagType:
3276 return ir_instruction_enumtagtype_get_dep((IrInstructionTagType *) instruction, index);
33293277 case IrInstructionIdFieldParentPtr:
33303278 return ir_instruction_fieldparentptr_get_dep((IrInstructionFieldParentPtr *) instruction, index);
33313279 case IrInstructionIdOffsetOf:
......@@ -4671,15 +4619,24 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
46714619
46724620 return ir_build_ptr_to_int(irb, scope, node, arg0_value);
46734621 }
4674 case BuiltinFnIdEnumTagName:
4622 case BuiltinFnIdTagName:
4623 {
4624 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4625 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4626 if (arg0_value == irb->codegen->invalid_instruction)
4627 return arg0_value;
4628
4629 IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value);
4630 return ir_build_tag_name(irb, scope, node, actual_tag);
4631 }
4632 case BuiltinFnIdTagType:
46754633 {
46764634 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
46774635 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
46784636 if (arg0_value == irb->codegen->invalid_instruction)
46794637 return arg0_value;
46804638
4681 IrInstruction *actual_tag = ir_build_enum_tag(irb, scope, node, arg0_value);
4682 return ir_build_enum_tag_name(irb, scope, node, actual_tag);
4639 return ir_build_tag_type(irb, scope, node, arg0_value);
46834640 }
46844641 case BuiltinFnIdFieldParentPtr:
46854642 {
......@@ -8348,13 +8305,28 @@ static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *sour
83488305{
83498306 assert(wanted_type->id == TypeTableEntryIdInt);
83508307
8308 TypeTableEntry *actual_type = target->value.type;
8309 ensure_complete_type(ira->codegen, actual_type);
8310 if (type_is_invalid(actual_type))
8311 return ira->codegen->invalid_instruction;
8312
8313 if (wanted_type != actual_type->data.enumeration.tag_int_type) {
8314 ir_add_error(ira, source_instr,
8315 buf_sprintf("enum to integer cast to '%s' instead of its tag type, '%s'",
8316 buf_ptr(&wanted_type->name),
8317 buf_ptr(&actual_type->data.enumeration.tag_int_type->name)));
8318 return ira->codegen->invalid_instruction;
8319 }
8320
8321 assert(actual_type->id == TypeTableEntryIdEnum);
8322
83518323 if (instr_is_comptime(target)) {
83528324 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
83538325 if (!val)
83548326 return ira->codegen->invalid_instruction;
83558327 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
83568328 source_instr->source_node, wanted_type);
8357 init_const_unsigned_negative(&result->value, wanted_type, val->data.x_enum.tag, false);
8329 init_const_bigint(&result->value, wanted_type, &val->data.x_enum_tag);
83588330 return result;
83598331 }
83608332
......@@ -8364,6 +8336,31 @@ static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *sour
83648336 return result;
83658337}
83668338
8339static IrInstruction *ir_analyze_union_to_tag(IrAnalyze *ira, IrInstruction *source_instr,
8340 IrInstruction *target, TypeTableEntry *wanted_type)
8341{
8342 assert(target->value.type->id == TypeTableEntryIdUnion);
8343 assert(wanted_type->id == TypeTableEntryIdEnum);
8344 assert(wanted_type == target->value.type->data.unionation.tag_type);
8345
8346 if (instr_is_comptime(target)) {
8347 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
8348 if (!val)
8349 return ira->codegen->invalid_instruction;
8350 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
8351 source_instr->source_node, wanted_type);
8352 result->value.special = ConstValSpecialStatic;
8353 result->value.type = wanted_type;
8354 bigint_init_bigint(&result->value.data.x_enum_tag, &val->data.x_union.tag);
8355 return result;
8356 }
8357
8358 IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope,
8359 source_instr->source_node, target);
8360 result->value.type = wanted_type;
8361 return result;
8362}
8363
83678364static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruction *source_instr,
83688365 IrInstruction *target, TypeTableEntry *wanted_type)
83698366{
......@@ -8419,6 +8416,22 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour
84198416{
84208417 assert(wanted_type->id == TypeTableEntryIdEnum);
84218418
8419 TypeTableEntry *actual_type = target->value.type;
8420
8421 ensure_complete_type(ira->codegen, wanted_type);
8422 if (type_is_invalid(wanted_type))
8423 return ira->codegen->invalid_instruction;
8424
8425 if (actual_type != wanted_type->data.enumeration.tag_int_type) {
8426 ir_add_error(ira, source_instr,
8427 buf_sprintf("integer to enum cast from '%s' instead of its tag type, '%s'",
8428 buf_ptr(&actual_type->name),
8429 buf_ptr(&wanted_type->data.enumeration.tag_int_type->name)));
8430 return ira->codegen->invalid_instruction;
8431 }
8432
8433 assert(actual_type->id == TypeTableEntryIdInt);
8434
84228435 if (instr_is_comptime(target)) {
84238436 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
84248437 if (!val)
......@@ -8436,7 +8449,7 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour
84368449
84378450 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
84388451 source_instr->source_node, wanted_type);
8439 result->value.data.x_enum.tag = bigint_as_unsigned(&val->data.x_bigint);
8452 bigint_init_bigint(&result->value.data.x_enum_tag, &val->data.x_bigint);
84408453 return result;
84418454 }
84428455
......@@ -8874,21 +8887,26 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
88748887 }
88758888
88768889 // explicit cast from integer to enum type with no payload
8877 if (actual_type->id == TypeTableEntryIdInt &&
8878 wanted_type->id == TypeTableEntryIdEnum &&
8879 wanted_type->data.enumeration.gen_field_count == 0)
8880 {
8890 if (actual_type->id == TypeTableEntryIdInt && wanted_type->id == TypeTableEntryIdEnum) {
88818891 return ir_analyze_int_to_enum(ira, source_instr, value, wanted_type);
88828892 }
88838893
88848894 // explicit cast from enum type with no payload to integer
8885 if (wanted_type->id == TypeTableEntryIdInt &&
8886 actual_type->id == TypeTableEntryIdEnum &&
8887 actual_type->data.enumeration.gen_field_count == 0)
8888 {
8895 if (wanted_type->id == TypeTableEntryIdInt && actual_type->id == TypeTableEntryIdEnum) {
88898896 return ir_analyze_enum_to_int(ira, source_instr, value, wanted_type);
88908897 }
88918898
8899 // explicit cast from union to the enum type of the union
8900 if (actual_type->id == TypeTableEntryIdUnion && wanted_type->id == TypeTableEntryIdEnum) {
8901 type_ensure_zero_bits_known(ira->codegen, actual_type);
8902 if (type_is_invalid(actual_type))
8903 return ira->codegen->invalid_instruction;
8904
8905 if (actual_type->data.unionation.tag_type == wanted_type) {
8906 return ir_analyze_union_to_tag(ira, source_instr, value, wanted_type);
8907 }
8908 }
8909
88928910 // explicit cast from undefined to anything
88938911 if (actual_type->id == TypeTableEntryIdUndefLit) {
88948912 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);
......@@ -9095,7 +9113,7 @@ static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, Atomic
90959113 if (!const_val)
90969114 return false;
90979115
9098 *out = (AtomicOrder)const_val->data.x_enum.tag;
9116 *out = (AtomicOrder)bigint_as_unsigned(&const_val->data.x_enum_tag);
90999117 return true;
91009118}
91019119
......@@ -9115,7 +9133,27 @@ static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstruction *value, Glob
91159133 if (!const_val)
91169134 return false;
91179135
9118 *out = (GlobalLinkageId)const_val->data.x_enum.tag;
9136 *out = (GlobalLinkageId)bigint_as_unsigned(&const_val->data.x_enum_tag);
9137 return true;
9138}
9139
9140static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstruction *value, FloatMode *out) {
9141 if (type_is_invalid(value->value.type))
9142 return false;
9143
9144 ConstExprValue *float_mode_val = get_builtin_value(ira->codegen, "FloatMode");
9145 assert(float_mode_val->type->id == TypeTableEntryIdMetaType);
9146 TypeTableEntry *float_mode_type = float_mode_val->data.x_type;
9147
9148 IrInstruction *casted_value = ir_implicit_cast(ira, value, float_mode_type);
9149 if (type_is_invalid(casted_value->value.type))
9150 return false;
9151
9152 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad);
9153 if (!const_val)
9154 return false;
9155
9156 *out = (FloatMode)bigint_as_unsigned(&const_val->data.x_enum_tag);
91199157 return true;
91209158}
91219159
......@@ -9327,7 +9365,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
93279365 break;
93289366
93299367 case TypeTableEntryIdEnum:
9330 if (!is_equality_cmp || resolved_type->data.enumeration.gen_field_count != 0) {
9368 if (!is_equality_cmp) {
93319369 ir_add_error_node(ira, source_node,
93329370 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));
93339371 return ira->codegen->builtin_types.entry_invalid;
......@@ -9346,9 +9384,6 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
93469384 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));
93479385 return ira->codegen->builtin_types.entry_invalid;
93489386
9349 case TypeTableEntryIdEnumTag:
9350 zig_panic("TODO implement comparison for enum tag type");
9351
93529387 case TypeTableEntryIdVar:
93539388 zig_unreachable();
93549389 }
......@@ -10097,7 +10132,6 @@ static VarClassRequired get_var_class_required(TypeTableEntry *type_entry) {
1009710132 case TypeTableEntryIdVoid:
1009810133 case TypeTableEntryIdPureError:
1009910134 case TypeTableEntryIdFn:
10100 case TypeTableEntryIdEnumTag:
1010110135 return VarClassRequiredAny;
1010210136 case TypeTableEntryIdNumLitFloat:
1010310137 case TypeTableEntryIdNumLitInt:
......@@ -10840,7 +10874,6 @@ static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstruct
1084010874 case TypeTableEntryIdUnion:
1084110875 case TypeTableEntryIdFn:
1084210876 case TypeTableEntryIdBoundFn:
10843 case TypeTableEntryIdEnumTag:
1084410877 {
1084510878 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);
1084610879 TypeTableEntry *result_type = get_error_type(ira->codegen, meta_type);
......@@ -10928,7 +10961,6 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op
1092810961 case TypeTableEntryIdNamespace:
1092910962 case TypeTableEntryIdBlock:
1093010963 case TypeTableEntryIdBoundFn:
10931 case TypeTableEntryIdEnumTag:
1093210964 case TypeTableEntryIdArgTuple:
1093310965 {
1093410966 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);
......@@ -11154,8 +11186,8 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
1115411186 }
1115511187
1115611188 if (new_incoming_blocks.length == 0) {
11157 ir_build_const_from(ira, &phi_instruction->base);
11158 return ira->codegen->builtin_types.entry_void;
11189 ir_build_unreachable_from(&ira->new_irb, &phi_instruction->base);
11190 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
1115911191 }
1116011192
1116111193 if (new_incoming_blocks.length == 1) {
......@@ -11589,15 +11621,8 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
1158911621 field_ptr_instruction, container_ptr, container_type);
1159011622 }
1159111623 } else if (bare_type->id == TypeTableEntryIdEnum) {
11592 TypeEnumField *field = find_enum_type_field(bare_type, field_name);
11593 if (field) {
11594 ir_build_enum_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
11595 return get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
11596 get_abi_alignment(ira->codegen, field->type_entry), 0, 0);
11597 } else {
11598 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
11599 field_ptr_instruction, container_ptr, container_type);
11600 }
11624 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
11625 field_ptr_instruction, container_ptr, container_type);
1160111626 } else if (bare_type->id == TypeTableEntryIdUnion) {
1160211627 TypeUnionField *field = find_union_type_field(bare_type, field_name);
1160311628 if (field) {
......@@ -11768,20 +11793,27 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
1176811793
1176911794 TypeEnumField *field = find_enum_type_field(child_type, field_name);
1177011795 if (field) {
11771 if (field->type_entry->id == TypeTableEntryIdVoid) {
11772 bool ptr_is_const = true;
11773 bool ptr_is_volatile = false;
11774 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base,
11775 create_const_enum_tag(child_type, field->value), child_type,
11776 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile);
11777 } else {
11778 bool ptr_is_const = true;
11779 bool ptr_is_volatile = false;
11780 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base,
11781 create_const_unsigned_negative(child_type->data.enumeration.tag_type, field->value, false),
11782 child_type->data.enumeration.tag_type,
11796 bool ptr_is_const = true;
11797 bool ptr_is_volatile = false;
11798 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base,
11799 create_const_enum(child_type, &field->value), child_type,
11800 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile);
11801 }
11802 } else if (child_type->id == TypeTableEntryIdUnion &&
11803 (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr ||
11804 child_type->data.unionation.decl_node->data.container_decl.auto_enum))
11805 {
11806 ensure_complete_type(ira->codegen, child_type);
11807 if (type_is_invalid(child_type))
11808 return ira->codegen->builtin_types.entry_invalid;
11809 TypeUnionField *field = find_union_type_field(child_type, field_name);
11810 if (field) {
11811 TypeTableEntry *enum_type = child_type->data.unionation.tag_type;
11812 bool ptr_is_const = true;
11813 bool ptr_is_volatile = false;
11814 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base,
11815 create_const_enum(enum_type, &field->enum_field->value), enum_type,
1178311816 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile);
11784 }
1178511817 }
1178611818 }
1178711819 ScopeDecls *container_scope = get_container_scope(child_type);
......@@ -12090,7 +12122,6 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi
1209012122 case TypeTableEntryIdEnum:
1209112123 case TypeTableEntryIdUnion:
1209212124 case TypeTableEntryIdFn:
12093 case TypeTableEntryIdEnumTag:
1209412125 case TypeTableEntryIdArgTuple:
1209512126 case TypeTableEntryIdOpaque:
1209612127 {
......@@ -12367,21 +12398,11 @@ static TypeTableEntry *ir_analyze_instruction_set_float_mode(IrAnalyze *ira,
1236712398 return ira->codegen->builtin_types.entry_invalid;
1236812399 }
1236912400
12370 ConstExprValue *float_mode_val = get_builtin_value(ira->codegen, "FloatMode");
12371 assert(float_mode_val->type->id == TypeTableEntryIdMetaType);
12372 TypeTableEntry *float_mode_enum_type = float_mode_val->data.x_type;
12373
1237412401 IrInstruction *float_mode_value = instruction->mode_value->other;
12375 if (type_is_invalid(float_mode_value->value.type))
12376 return ira->codegen->builtin_types.entry_invalid;
12377 IrInstruction *casted_value = ir_implicit_cast(ira, float_mode_value, float_mode_enum_type);
12378 if (type_is_invalid(casted_value->value.type))
12379 return ira->codegen->builtin_types.entry_invalid;
12380 ConstExprValue *mode_val = ir_resolve_const(ira, casted_value, UndefBad);
12381 if (!mode_val)
12382 return ira->codegen->builtin_types.entry_invalid;
1238312402
12384 bool want_fast_math = (mode_val->data.x_enum.tag == FloatModeOptimized);
12403 FloatMode float_mode_scalar;
12404 if (!ir_resolve_float_mode(ira, float_mode_value, &float_mode_scalar))
12405 return ira->codegen->builtin_types.entry_invalid;
1238512406
1238612407 AstNode *source_node = instruction->base.source_node;
1238712408 if (*fast_math_set_node_ptr) {
......@@ -12391,7 +12412,7 @@ static TypeTableEntry *ir_analyze_instruction_set_float_mode(IrAnalyze *ira,
1239112412 return ira->codegen->builtin_types.entry_invalid;
1239212413 }
1239312414 *fast_math_set_node_ptr = source_node;
12394 *fast_math_off_ptr = !want_fast_math;
12415 *fast_math_off_ptr = (float_mode_scalar == FloatModeStrict);
1239512416
1239612417 ir_build_const_from(ira, &instruction->base);
1239712418 return ira->codegen->builtin_types.entry_void;
......@@ -12448,7 +12469,6 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
1244812469 case TypeTableEntryIdFn:
1244912470 case TypeTableEntryIdNamespace:
1245012471 case TypeTableEntryIdBoundFn:
12451 case TypeTableEntryIdEnumTag:
1245212472 {
1245312473 type_ensure_zero_bits_known(ira->codegen, child_type);
1245412474 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type,
......@@ -12557,7 +12577,6 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,
1255712577 case TypeTableEntryIdFn:
1255812578 case TypeTableEntryIdNamespace:
1255912579 case TypeTableEntryIdBoundFn:
12560 case TypeTableEntryIdEnumTag:
1256112580 {
1256212581 TypeTableEntry *result_type = get_array_type(ira->codegen, child_type, size);
1256312582 ConstExprValue *out_val = ir_build_const_from(ira, &array_type_instruction->base);
......@@ -12608,7 +12627,6 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,
1260812627 case TypeTableEntryIdPureError:
1260912628 case TypeTableEntryIdEnum:
1261012629 case TypeTableEntryIdUnion:
12611 case TypeTableEntryIdEnumTag:
1261212630 case TypeTableEntryIdFn:
1261312631 {
1261412632 uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
......@@ -12761,17 +12779,22 @@ static TypeTableEntry *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionC
1276112779 }
1276212780}
1276312781
12764static IrInstruction *ir_analyze_enum_tag(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value) {
12782static IrInstruction *ir_analyze_union_tag(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value) {
1276512783 if (type_is_invalid(value->value.type))
1276612784 return ira->codegen->invalid_instruction;
1276712785
12768 if (value->value.type->id != TypeTableEntryIdEnum) {
12786 if (value->value.type->id == TypeTableEntryIdEnum) {
12787 return value;
12788 }
12789
12790 if (value->value.type->id != TypeTableEntryIdUnion) {
1276912791 ir_add_error(ira, source_instr,
12770 buf_sprintf("expected enum type, found '%s'", buf_ptr(&value->value.type->name)));
12792 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value.type->name)));
1277112793 return ira->codegen->invalid_instruction;
1277212794 }
1277312795
12774 TypeTableEntry *tag_type = value->value.type->data.enumeration.tag_type;
12796 TypeTableEntry *tag_type = value->value.type->data.unionation.tag_type;
12797 assert(tag_type->id == TypeTableEntryIdEnum);
1277512798
1277612799 if (instr_is_comptime(value)) {
1277712800 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
......@@ -12782,11 +12805,11 @@ static IrInstruction *ir_analyze_enum_tag(IrAnalyze *ira, IrInstruction *source_
1278212805 source_instr->scope, source_instr->source_node);
1278312806 const_instruction->base.value.type = tag_type;
1278412807 const_instruction->base.value.special = ConstValSpecialStatic;
12785 bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, val->data.x_enum.tag);
12808 bigint_init_bigint(&const_instruction->base.value.data.x_enum_tag, &val->data.x_union.tag);
1278612809 return &const_instruction->base;
1278712810 }
1278812811
12789 IrInstruction *result = ir_build_enum_tag(&ira->new_irb, source_instr->scope, source_instr->source_node, value);
12812 IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope, source_instr->source_node, value);
1279012813 result->value.type = tag_type;
1279112814 return result;
1279212815}
......@@ -12817,7 +12840,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,
1281712840 return ir_unreach_error(ira);
1281812841
1281912842 if (case_value->value.type->id == TypeTableEntryIdEnum) {
12820 case_value = ir_analyze_enum_tag(ira, &switch_br_instruction->base, case_value);
12843 case_value = ir_analyze_union_tag(ira, &switch_br_instruction->base, case_value);
1282112844 if (type_is_invalid(case_value->value.type))
1282212845 return ir_unreach_error(ira);
1282312846 }
......@@ -12864,7 +12887,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,
1286412887 continue;
1286512888
1286612889 if (new_value->value.type->id == TypeTableEntryIdEnum) {
12867 new_value = ir_analyze_enum_tag(ira, &switch_br_instruction->base, new_value);
12890 new_value = ir_analyze_union_tag(ira, &switch_br_instruction->base, new_value);
1286812891 if (type_is_invalid(new_value->value.type))
1286912892 continue;
1287012893 }
......@@ -12946,34 +12969,57 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
1294612969
1294712970 ir_build_load_ptr_from(&ira->new_irb, &switch_target_instruction->base, target_value_ptr);
1294812971 return target_type;
12949 case TypeTableEntryIdEnum:
12972 case TypeTableEntryIdUnion: {
12973 AstNode *decl_node = target_type->data.unionation.decl_node;
12974 if (!decl_node->data.container_decl.auto_enum &&
12975 decl_node->data.container_decl.init_arg_expr == nullptr)
1295012976 {
12951 TypeTableEntry *tag_type = target_type->data.enumeration.tag_type;
12952 assert(tag_type != nullptr);
12953 if (pointee_val) {
12954 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);
12955 bigint_init_unsigned(&out_val->data.x_bigint, pointee_val->data.x_enum.tag);
12956 return tag_type;
12957 }
12958
12959 IrInstruction *enum_value = ir_build_load_ptr(&ira->new_irb, switch_target_instruction->base.scope,
12960 switch_target_instruction->base.source_node, target_value_ptr);
12961 enum_value->value.type = target_type;
12962 ir_build_enum_tag_from(&ira->new_irb, &switch_target_instruction->base, enum_value);
12977 ErrorMsg *msg = ir_add_error(ira, target_value_ptr,
12978 buf_sprintf("switch on union which has no attached enum"));
12979 add_error_note(ira->codegen, msg, decl_node,
12980 buf_sprintf("consider 'union(enum)' here"));
12981 return ira->codegen->builtin_types.entry_invalid;
12982 }
12983 TypeTableEntry *tag_type = target_type->data.unionation.tag_type;
12984 assert(tag_type != nullptr);
12985 if (pointee_val) {
12986 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);
12987 bigint_init_bigint(&out_val->data.x_enum_tag, &pointee_val->data.x_union.tag);
1296312988 return tag_type;
1296412989 }
12990
12991 IrInstruction *union_value = ir_build_load_ptr(&ira->new_irb, switch_target_instruction->base.scope,
12992 switch_target_instruction->base.source_node, target_value_ptr);
12993 union_value->value.type = target_type;
12994
12995 IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope,
12996 switch_target_instruction->base.source_node, union_value);
12997 union_tag_inst->value.type = tag_type;
12998 ir_link_new_instruction(union_tag_inst, &switch_target_instruction->base);
12999 return tag_type;
13000 }
13001 case TypeTableEntryIdEnum: {
13002 if (pointee_val) {
13003 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);
13004 bigint_init_bigint(&out_val->data.x_enum_tag, &pointee_val->data.x_enum_tag);
13005 return target_type;
13006 }
13007
13008 IrInstruction *enum_value = ir_build_load_ptr(&ira->new_irb, switch_target_instruction->base.scope,
13009 switch_target_instruction->base.source_node, target_value_ptr);
13010 enum_value->value.type = target_type;
13011 ir_link_new_instruction(enum_value, &switch_target_instruction->base);
13012 return target_type;
13013 }
1296513014 case TypeTableEntryIdErrorUnion:
12966 // see https://github.com/andrewrk/zig/issues/83
13015 // see https://github.com/andrewrk/zig/issues/632
1296713016 zig_panic("TODO switch on error union");
12968 case TypeTableEntryIdEnumTag:
12969 zig_panic("TODO switch on enum tag type");
1297013017 case TypeTableEntryIdUnreachable:
1297113018 case TypeTableEntryIdArray:
1297213019 case TypeTableEntryIdStruct:
1297313020 case TypeTableEntryIdUndefLit:
1297413021 case TypeTableEntryIdNullLit:
1297513022 case TypeTableEntryIdMaybe:
12976 case TypeTableEntryIdUnion:
1297713023 case TypeTableEntryIdBlock:
1297813024 case TypeTableEntryIdBoundFn:
1297913025 case TypeTableEntryIdArgTuple:
......@@ -12996,19 +13042,13 @@ static TypeTableEntry *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstr
1299613042
1299713043 assert(target_value_ptr->value.type->id == TypeTableEntryIdPointer);
1299813044 TypeTableEntry *target_type = target_value_ptr->value.type->data.pointer.child_type;
12999 if (target_type->id == TypeTableEntryIdEnum) {
13045 if (target_type->id == TypeTableEntryIdUnion) {
1300013046 ConstExprValue *prong_val = ir_resolve_const(ira, prong_value, UndefBad);
1300113047 if (!prong_val)
1300213048 return ira->codegen->builtin_types.entry_invalid;
1300313049
13004 TypeEnumField *field;
13005 if (prong_value->value.type->id == TypeTableEntryIdEnumTag) {
13006 field = &target_type->data.enumeration.fields[bigint_as_unsigned(&prong_val->data.x_bigint)];
13007 } else if (prong_value->value.type->id == TypeTableEntryIdEnum) {
13008 field = &target_type->data.enumeration.fields[prong_val->data.x_enum.tag];
13009 } else {
13010 zig_unreachable();
13011 }
13050 assert(prong_value->value.type->id == TypeTableEntryIdEnum);
13051 TypeUnionField *field = find_union_field_by_tag(target_type, &prong_val->data.x_enum_tag);
1301213052
1301313053 if (instr_is_comptime(target_value_ptr)) {
1301413054 ConstExprValue *target_val_ptr = ir_resolve_const(ira, target_value_ptr, UndefBad);
......@@ -13019,11 +13059,11 @@ static TypeTableEntry *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstr
1301913059 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
1302013060 out_val->data.x_ptr.special = ConstPtrSpecialRef;
1302113061 out_val->data.x_ptr.mut = target_val_ptr->data.x_ptr.mut;
13022 out_val->data.x_ptr.data.ref.pointee = pointee_val->data.x_enum.payload;
13062 out_val->data.x_ptr.data.ref.pointee = pointee_val->data.x_union.payload;
1302313063 return get_pointer_to_type(ira->codegen, field->type_entry, target_val_ptr->type->data.pointer.is_const);
1302413064 }
1302513065
13026 ir_build_enum_field_ptr_from(&ira->new_irb, &instruction->base, target_value_ptr, field);
13066 ir_build_union_field_ptr_from(&ira->new_irb, &instruction->base, target_value_ptr, field);
1302713067 return get_pointer_to_type(ira->codegen, field->type_entry,
1302813068 target_value_ptr->value.type->data.pointer.is_const);
1302913069 } else {
......@@ -13033,10 +13073,10 @@ static TypeTableEntry *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstr
1303313073 }
1303413074}
1303513075
13036static TypeTableEntry *ir_analyze_instruction_enum_tag(IrAnalyze *ira, IrInstructionEnumTag *enum_tag_instruction) {
13037 IrInstruction *value = enum_tag_instruction->value->other;
13038 IrInstruction *new_instruction = ir_analyze_enum_tag(ira, &enum_tag_instruction->base, value);
13039 ir_link_new_instruction(new_instruction, &enum_tag_instruction->base);
13076static TypeTableEntry *ir_analyze_instruction_union_tag(IrAnalyze *ira, IrInstructionUnionTag *instruction) {
13077 IrInstruction *value = instruction->value->other;
13078 IrInstruction *new_instruction = ir_analyze_union_tag(ira, &instruction->base, value);
13079 ir_link_new_instruction(new_instruction, &instruction->base);
1304013080 return new_instruction->value.type;
1304113081}
1304213082
......@@ -13192,7 +13232,7 @@ static TypeTableEntry *ir_analyze_container_init_fields_union(IrAnalyze *ira, Ir
1319213232
1319313233 ConstExprValue *out_val = ir_build_const_from(ira, instruction);
1319413234 out_val->data.x_union.payload = field_val;
13195 out_val->data.x_union.tag = type_field->value;
13235 out_val->data.x_union.tag = type_field->enum_field->value;
1319613236
1319713237 ConstParent *parent = get_const_val_parent(ira->codegen, field_val);
1319813238 if (parent != nullptr) {
......@@ -13439,46 +13479,9 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
1343913479 buf_ptr(&container_type->name)));
1344013480 return ira->codegen->builtin_types.entry_invalid;
1344113481 }
13442 } else if (container_type_value->value.type->id == TypeTableEntryIdEnumTag) {
13443 if (elem_count != 1) {
13444 ir_add_error(ira, &instruction->base, buf_sprintf("enum initialization requires exactly one element"));
13445 return ira->codegen->builtin_types.entry_invalid;
13446 }
13447 ConstExprValue *tag_value = ir_resolve_const(ira, container_type_value, UndefBad);
13448 if (!tag_value)
13449 return ira->codegen->builtin_types.entry_invalid;
13450
13451 TypeTableEntry *enum_type = container_type_value->value.type->data.enum_tag.enum_type;
13452
13453 uint64_t tag_uint = bigint_as_unsigned(&tag_value->data.x_bigint);
13454 TypeEnumField *field = &enum_type->data.enumeration.fields[tag_uint];
13455 TypeTableEntry *this_field_type = field->type_entry;
13456
13457 IrInstruction *init_value = instruction->items[0]->other;
13458 if (type_is_invalid(init_value->value.type))
13459 return ira->codegen->builtin_types.entry_invalid;
13460
13461 IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, this_field_type);
13462 if (casted_init_value == ira->codegen->invalid_instruction)
13463 return ira->codegen->builtin_types.entry_invalid;
13464
13465 if (instr_is_comptime(casted_init_value)) {
13466 ConstExprValue *init_val = ir_resolve_const(ira, casted_init_value, UndefOk);
13467 if (!init_val)
13468 return ira->codegen->builtin_types.entry_invalid;
13469 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
13470 out_val->data.x_enum.tag = tag_uint;
13471 out_val->data.x_enum.payload = init_val;
13472 return enum_type;
13473 }
13474
13475 IrInstruction *new_instruction = ir_build_init_enum_from(&ira->new_irb, &instruction->base,
13476 enum_type, field, casted_init_value);
13477 ir_add_alloca(ira, new_instruction, enum_type);
13478 return enum_type;
1347913482 } else {
1348013483 ir_add_error(ira, container_type_value,
13481 buf_sprintf("expected type, found '%s'", buf_ptr(&container_type_value->value.type->name)));
13484 buf_sprintf("expected type, found '%s' value", buf_ptr(&container_type_value->value.type->name)));
1348213485 return ira->codegen->builtin_types.entry_invalid;
1348313486 }
1348413487}
......@@ -13521,8 +13524,8 @@ static TypeTableEntry *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_
1352113524 eval_min_max_value(ira->codegen, target_type, out_val, is_max);
1352213525 return target_type;
1352313526 }
13524 case TypeTableEntryIdEnumTag:
13525 zig_panic("TODO min/max value for enum tag type");
13527 case TypeTableEntryIdEnum:
13528 zig_panic("TODO min/max value for enum type");
1352613529 case TypeTableEntryIdVar:
1352713530 case TypeTableEntryIdMetaType:
1352813531 case TypeTableEntryIdUnreachable:
......@@ -13536,7 +13539,6 @@ static TypeTableEntry *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_
1353613539 case TypeTableEntryIdMaybe:
1353713540 case TypeTableEntryIdErrorUnion:
1353813541 case TypeTableEntryIdPureError:
13539 case TypeTableEntryIdEnum:
1354013542 case TypeTableEntryIdUnion:
1354113543 case TypeTableEntryIdFn:
1354213544 case TypeTableEntryIdNamespace:
......@@ -13639,29 +13641,27 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc
1363913641 return str_type;
1364013642}
1364113643
13642static TypeTableEntry *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructionEnumTagName *instruction) {
13644static TypeTableEntry *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructionTagName *instruction) {
1364313645 IrInstruction *target = instruction->target->other;
1364413646 if (type_is_invalid(target->value.type))
1364513647 return ira->codegen->builtin_types.entry_invalid;
1364613648
13647 assert(target->value.type->id == TypeTableEntryIdEnumTag);
13649 assert(target->value.type->id == TypeTableEntryIdEnum);
1364813650
1364913651 if (instr_is_comptime(target)) {
13650 TypeTableEntry *enum_type = target->value.type->data.enum_tag.enum_type;
13651 uint64_t tag_value = bigint_as_unsigned(&target->value.data.x_bigint);
13652 TypeEnumField *field = &enum_type->data.enumeration.fields[tag_value];
13652 TypeEnumField *field = find_enum_field_by_tag(target->value.type, &target->value.data.x_bigint);
1365313653 ConstExprValue *array_val = create_const_str_lit(ira->codegen, field->name);
1365413654 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
1365513655 init_const_slice(ira->codegen, out_val, array_val, 0, buf_len(field->name), true);
1365613656 return out_val->type;
1365713657 }
1365813658
13659 if (!target->value.type->data.enum_tag.generate_name_table) {
13660 target->value.type->data.enum_tag.generate_name_table = true;
13659 if (!target->value.type->data.enumeration.generate_name_table) {
13660 target->value.type->data.enumeration.generate_name_table = true;
1366113661 ira->codegen->name_table_enums.append(target->value.type);
1366213662 }
1366313663
13664 IrInstruction *result = ir_build_enum_tag_name(&ira->new_irb, instruction->base.scope,
13664 IrInstruction *result = ir_build_tag_name(&ira->new_irb, instruction->base.scope,
1366513665 instruction->base.source_node, target);
1366613666 ir_link_new_instruction(result, &instruction->base);
1366713667 TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
......@@ -13806,7 +13806,7 @@ static TypeTableEntry *ir_analyze_instruction_type_id(IrAnalyze *ira,
1380613806 TypeTableEntry *result_type = var_value->data.x_type;
1380713807
1380813808 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
13809 out_val->data.x_enum.tag = type_id_index(type_entry->id);
13809 bigint_init_unsigned(&out_val->data.x_enum_tag, type_id_index(type_entry->id));
1381013810 return result_type;
1381113811}
1381213812
......@@ -13870,7 +13870,10 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc
1387013870
1387113871 int err;
1387213872 if ((err = parse_h_buf(child_import, &errors, &cimport_scope->buf, ira->codegen, node))) {
13873 zig_panic("unable to parse C file: %s\n", err_str(err));
13873 if (err != ErrorCCompileErrors) {
13874 ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err)));
13875 return ira->codegen->builtin_types.entry_invalid;
13876 }
1387413877 }
1387513878
1387613879 if (errors.length > 0) {
......@@ -14632,14 +14635,14 @@ static TypeTableEntry *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInst
1463214635 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
1463314636 out_val->data.x_type = field->type_entry;
1463414637 return ira->codegen->builtin_types.entry_type;
14635 } else if (container_type->id == TypeTableEntryIdEnum) {
14636 if (member_index >= container_type->data.enumeration.src_field_count) {
14638 } else if (container_type->id == TypeTableEntryIdUnion) {
14639 if (member_index >= container_type->data.unionation.src_field_count) {
1463714640 ir_add_error(ira, index_value,
1463814641 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members",
14639 member_index, buf_ptr(&container_type->name), container_type->data.enumeration.src_field_count));
14642 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count));
1464014643 return ira->codegen->builtin_types.entry_invalid;
1464114644 }
14642 TypeEnumField *field = &container_type->data.enumeration.fields[member_index];
14645 TypeUnionField *field = &container_type->data.unionation.fields[member_index];
1464314646
1464414647 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
1464514648 out_val->data.x_type = field->type_entry;
......@@ -14683,6 +14686,18 @@ static TypeTableEntry *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInst
1468314686 }
1468414687 TypeEnumField *field = &container_type->data.enumeration.fields[member_index];
1468514688
14689 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
14690 init_const_str_lit(ira->codegen, out_val, field->name);
14691 return out_val->type;
14692 } else if (container_type->id == TypeTableEntryIdUnion) {
14693 if (member_index >= container_type->data.unionation.src_field_count) {
14694 ir_add_error(ira, index_value,
14695 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members",
14696 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count));
14697 return ira->codegen->builtin_types.entry_invalid;
14698 }
14699 TypeUnionField *field = &container_type->data.unionation.fields[member_index];
14700
1468614701 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
1468714702 init_const_str_lit(ira->codegen, out_val, field->name);
1468814703 return out_val->type;
......@@ -14753,7 +14768,6 @@ static TypeTableEntry *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruc
1475314768 case TypeTableEntryIdErrorUnion:
1475414769 case TypeTableEntryIdPureError:
1475514770 case TypeTableEntryIdEnum:
14756 case TypeTableEntryIdEnumTag:
1475714771 case TypeTableEntryIdUnion:
1475814772 case TypeTableEntryIdFn:
1475914773 {
......@@ -15059,9 +15073,10 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira
1505915073 if (type_is_invalid(switch_type))
1506015074 return ira->codegen->builtin_types.entry_invalid;
1506115075
15062 if (switch_type->id == TypeTableEntryIdEnumTag) {
15063 TypeTableEntry *enum_type = switch_type->data.enum_tag.enum_type;
15064 AstNode **field_prev_uses = allocate<AstNode *>(enum_type->data.enumeration.src_field_count);
15076 if (switch_type->id == TypeTableEntryIdEnum) {
15077 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> field_prev_uses = {};
15078 field_prev_uses.init(switch_type->data.enumeration.src_field_count);
15079
1506515080 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) {
1506615081 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i];
1506715082
......@@ -15073,41 +15088,43 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira
1507315088 if (type_is_invalid(end_value->value.type))
1507415089 return ira->codegen->builtin_types.entry_invalid;
1507515090
15076 size_t start_index;
15077 size_t end_index;
15078 if (start_value->value.type->id == TypeTableEntryIdEnumTag) {
15079 start_index = bigint_as_unsigned(&start_value->value.data.x_bigint);
15080 } else if (start_value->value.type->id == TypeTableEntryIdEnum) {
15081 start_index = start_value->value.data.x_enum.tag;
15082 } else {
15083 zig_unreachable();
15084 }
15085 if (end_value->value.type->id == TypeTableEntryIdEnumTag) {
15086 end_index = bigint_as_unsigned(&end_value->value.data.x_bigint);
15087 } else if (end_value->value.type->id == TypeTableEntryIdEnum) {
15088 end_index = end_value->value.data.x_enum.tag;
15089 } else {
15090 zig_unreachable();
15091 }
15091 assert(start_value->value.type->id == TypeTableEntryIdEnum);
15092 BigInt start_index;
15093 bigint_init_bigint(&start_index, &start_value->value.data.x_enum_tag);
1509215094
15093 for (size_t field_index = start_index; field_index <= end_index; field_index += 1) {
15094 AstNode *prev_node = field_prev_uses[field_index];
15095 if (prev_node != nullptr) {
15096 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_index];
15095 assert(end_value->value.type->id == TypeTableEntryIdEnum);
15096 BigInt end_index;
15097 bigint_init_bigint(&end_index, &end_value->value.data.x_enum_tag);
15098
15099 BigInt field_index;
15100 bigint_init_bigint(&field_index, &start_index);
15101 for (;;) {
15102 Cmp cmp = bigint_cmp(&field_index, &end_index);
15103 if (cmp == CmpGT) {
15104 break;
15105 }
15106 auto entry = field_prev_uses.put_unique(field_index, start_value->source_node);
15107 if (entry) {
15108 AstNode *prev_node = entry->value;
15109 TypeEnumField *enum_field = find_enum_field_by_tag(switch_type, &field_index);
15110 assert(enum_field != nullptr);
1509715111 ErrorMsg *msg = ir_add_error(ira, start_value,
15098 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&enum_type->name),
15099 buf_ptr(type_enum_field->name)));
15112 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name),
15113 buf_ptr(enum_field->name)));
1510015114 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here"));
1510115115 }
15102 field_prev_uses[field_index] = start_value->source_node;
15116 bigint_incr(&field_index);
1510315117 }
1510415118 }
1510515119 if (!instruction->have_else_prong) {
15106 for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) {
15107 if (field_prev_uses[i] == nullptr) {
15120 for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) {
15121 TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i];
15122
15123 auto entry = field_prev_uses.maybe_get(enum_field->value);
15124 if (!entry) {
1510815125 ir_add_error(ira, &instruction->base,
15109 buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&enum_type->name),
15110 buf_ptr(enum_type->data.enumeration.fields[i].name)));
15126 buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name),
15127 buf_ptr(enum_field->name)));
1511115128 }
1511215129 }
1511315130 }
......@@ -15402,8 +15419,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
1540215419 zig_panic("TODO buf_write_value_bytes pure error type");
1540315420 case TypeTableEntryIdEnum:
1540415421 zig_panic("TODO buf_write_value_bytes enum type");
15405 case TypeTableEntryIdEnumTag:
15406 zig_panic("TODO buf_write_value_bytes enum tag type");
1540715422 case TypeTableEntryIdFn:
1540815423 zig_panic("TODO buf_write_value_bytes fn type");
1540915424 case TypeTableEntryIdUnion:
......@@ -15462,8 +15477,6 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
1546215477 zig_panic("TODO buf_read_value_bytes pure error type");
1546315478 case TypeTableEntryIdEnum:
1546415479 zig_panic("TODO buf_read_value_bytes enum type");
15465 case TypeTableEntryIdEnumTag:
15466 zig_panic("TODO buf_read_value_bytes enum tag type");
1546715480 case TypeTableEntryIdFn:
1546815481 zig_panic("TODO buf_read_value_bytes fn type");
1546915482 case TypeTableEntryIdUnion:
......@@ -15828,6 +15841,45 @@ static TypeTableEntry *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruc
1582815841 return ira->codegen->builtin_types.entry_type;
1582915842}
1583015843
15844static TypeTableEntry *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstructionTagType *instruction) {
15845 IrInstruction *target_inst = instruction->target->other;
15846 TypeTableEntry *enum_type = ir_resolve_type(ira, target_inst);
15847 if (type_is_invalid(enum_type))
15848 return ira->codegen->builtin_types.entry_invalid;
15849
15850 if (enum_type->id == TypeTableEntryIdEnum) {
15851 ensure_complete_type(ira->codegen, enum_type);
15852 if (type_is_invalid(enum_type))
15853 return ira->codegen->builtin_types.entry_invalid;
15854
15855 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
15856 out_val->data.x_type = enum_type->data.enumeration.tag_int_type;
15857 return ira->codegen->builtin_types.entry_type;
15858 } else if (enum_type->id == TypeTableEntryIdUnion) {
15859 ensure_complete_type(ira->codegen, enum_type);
15860 if (type_is_invalid(enum_type))
15861 return ira->codegen->builtin_types.entry_invalid;
15862
15863 AstNode *decl_node = enum_type->data.unionation.decl_node;
15864 if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) {
15865 assert(enum_type->data.unionation.tag_type != nullptr);
15866
15867 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
15868 out_val->data.x_type = enum_type->data.unionation.tag_type;
15869 return ira->codegen->builtin_types.entry_type;
15870 } else {
15871 ErrorMsg *msg = ir_add_error(ira, target_inst, buf_sprintf("union '%s' has no tag",
15872 buf_ptr(&enum_type->name)));
15873 add_error_note(ira->codegen, msg, decl_node, buf_sprintf("consider 'union(enum)' here"));
15874 return ira->codegen->builtin_types.entry_invalid;
15875 }
15876 } else {
15877 ir_add_error(ira, target_inst, buf_sprintf("expected enum or union, found '%s'",
15878 buf_ptr(&enum_type->name)));
15879 return ira->codegen->builtin_types.entry_invalid;
15880 }
15881}
15882
1583115883static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
1583215884 switch (instruction->id) {
1583315885 case IrInstructionIdInvalid:
......@@ -15838,9 +15890,7 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1583815890 case IrInstructionIdStructInit:
1583915891 case IrInstructionIdUnionInit:
1584015892 case IrInstructionIdStructFieldPtr:
15841 case IrInstructionIdEnumFieldPtr:
1584215893 case IrInstructionIdUnionFieldPtr:
15843 case IrInstructionIdInitEnum:
1584415894 case IrInstructionIdMaybeWrap:
1584515895 case IrInstructionIdErrWrapCode:
1584615896 case IrInstructionIdErrWrapPayload:
......@@ -15912,8 +15962,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1591215962 return ir_analyze_instruction_switch_target(ira, (IrInstructionSwitchTarget *)instruction);
1591315963 case IrInstructionIdSwitchVar:
1591415964 return ir_analyze_instruction_switch_var(ira, (IrInstructionSwitchVar *)instruction);
15915 case IrInstructionIdEnumTag:
15916 return ir_analyze_instruction_enum_tag(ira, (IrInstructionEnumTag *)instruction);
15965 case IrInstructionIdUnionTag:
15966 return ir_analyze_instruction_union_tag(ira, (IrInstructionUnionTag *)instruction);
1591715967 case IrInstructionIdImport:
1591815968 return ir_analyze_instruction_import(ira, (IrInstructionImport *)instruction);
1591915969 case IrInstructionIdArrayLen:
......@@ -16006,8 +16056,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1600616056 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction);
1600716057 case IrInstructionIdPtrToInt:
1600816058 return ir_analyze_instruction_ptr_to_int(ira, (IrInstructionPtrToInt *)instruction);
16009 case IrInstructionIdEnumTagName:
16010 return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionEnumTagName *)instruction);
16059 case IrInstructionIdTagName:
16060 return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionTagName *)instruction);
1601116061 case IrInstructionIdFieldParentPtr:
1601216062 return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction);
1601316063 case IrInstructionIdOffsetOf:
......@@ -16026,6 +16076,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1602616076 return ir_analyze_instruction_set_align_stack(ira, (IrInstructionSetAlignStack *)instruction);
1602716077 case IrInstructionIdArgType:
1602816078 return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction);
16079 case IrInstructionIdTagType:
16080 return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction);
1602916081 }
1603016082 zig_unreachable();
1603116083}
......@@ -16158,7 +16210,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1615816210 case IrInstructionIdPtrTypeChild:
1615916211 case IrInstructionIdArrayLen:
1616016212 case IrInstructionIdStructFieldPtr:
16161 case IrInstructionIdEnumFieldPtr:
1616216213 case IrInstructionIdUnionFieldPtr:
1616316214 case IrInstructionIdArrayType:
1616416215 case IrInstructionIdSliceType:
......@@ -16169,7 +16220,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1616916220 case IrInstructionIdCtz:
1617016221 case IrInstructionIdSwitchVar:
1617116222 case IrInstructionIdSwitchTarget:
16172 case IrInstructionIdEnumTag:
16223 case IrInstructionIdUnionTag:
1617316224 case IrInstructionIdRef:
1617416225 case IrInstructionIdMinValue:
1617516226 case IrInstructionIdMaxValue:
......@@ -16191,7 +16242,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1619116242 case IrInstructionIdErrWrapPayload:
1619216243 case IrInstructionIdFnProto:
1619316244 case IrInstructionIdTestComptime:
16194 case IrInstructionIdInitEnum:
1619516245 case IrInstructionIdPtrCast:
1619616246 case IrInstructionIdBitCast:
1619716247 case IrInstructionIdWidenOrShorten:
......@@ -16204,13 +16254,14 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1620416254 case IrInstructionIdDeclRef:
1620516255 case IrInstructionIdErrName:
1620616256 case IrInstructionIdTypeName:
16207 case IrInstructionIdEnumTagName:
16257 case IrInstructionIdTagName:
1620816258 case IrInstructionIdFieldParentPtr:
1620916259 case IrInstructionIdOffsetOf:
1621016260 case IrInstructionIdTypeId:
1621116261 case IrInstructionIdAlignCast:
1621216262 case IrInstructionIdOpaqueType:
1621316263 case IrInstructionIdArgType:
16264 case IrInstructionIdTagType:
1621416265 return false;
1621516266 case IrInstructionIdAsm:
1621616267 {
src/ir_print.cpp+19-29
......@@ -291,7 +291,7 @@ static void ir_print_struct_init(IrPrint *irp, IrInstructionStructInit *instruct
291291}
292292
293293static void ir_print_union_init(IrPrint *irp, IrInstructionUnionInit *instruction) {
294 Buf *field_name = instruction->field->name;
294 Buf *field_name = instruction->field->enum_field->name;
295295
296296 fprintf(irp->f, "%s {", buf_ptr(&instruction->union_type->name));
297297 fprintf(irp->f, ".%s = ", buf_ptr(field_name));
......@@ -361,17 +361,10 @@ static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr
361361 fprintf(irp->f, ")");
362362}
363363
364static void ir_print_enum_field_ptr(IrPrint *irp, IrInstructionEnumFieldPtr *instruction) {
365 fprintf(irp->f, "@EnumFieldPtr(&");
366 ir_print_other_instruction(irp, instruction->enum_ptr);
367 fprintf(irp->f, ".%s", buf_ptr(instruction->field->name));
368 fprintf(irp->f, ")");
369}
370
371364static void ir_print_union_field_ptr(IrPrint *irp, IrInstructionUnionFieldPtr *instruction) {
372365 fprintf(irp->f, "@UnionFieldPtr(&");
373366 ir_print_other_instruction(irp, instruction->union_ptr);
374 fprintf(irp->f, ".%s", buf_ptr(instruction->field->name));
367 fprintf(irp->f, ".%s", buf_ptr(instruction->field->enum_field->name));
375368 fprintf(irp->f, ")");
376369}
377370
......@@ -509,8 +502,8 @@ static void ir_print_switch_target(IrPrint *irp, IrInstructionSwitchTarget *inst
509502 ir_print_other_instruction(irp, instruction->target_value_ptr);
510503}
511504
512static void ir_print_enum_tag(IrPrint *irp, IrInstructionEnumTag *instruction) {
513 fprintf(irp->f, "enumtag ");
505static void ir_print_union_tag(IrPrint *irp, IrInstructionUnionTag *instruction) {
506 fprintf(irp->f, "uniontag ");
514507 ir_print_other_instruction(irp, instruction->value);
515508}
516509
......@@ -799,12 +792,6 @@ static void ir_print_test_comptime(IrPrint *irp, IrInstructionTestComptime *inst
799792 fprintf(irp->f, ")");
800793}
801794
802static void ir_print_init_enum(IrPrint *irp, IrInstructionInitEnum *instruction) {
803 fprintf(irp->f, "%s.%s {", buf_ptr(&instruction->enum_type->name), buf_ptr(instruction->field->name));
804 ir_print_other_instruction(irp, instruction->init_value);
805 fprintf(irp->f, "}");
806}
807
808795static void ir_print_ptr_cast(IrPrint *irp, IrInstructionPtrCast *instruction) {
809796 fprintf(irp->f, "@ptrCast(");
810797 if (instruction->dest_type) {
......@@ -885,8 +872,8 @@ static void ir_print_type_name(IrPrint *irp, IrInstructionTypeName *instruction)
885872 ir_print_other_instruction(irp, instruction->type_value);
886873}
887874
888static void ir_print_enum_tag_name(IrPrint *irp, IrInstructionEnumTagName *instruction) {
889 fprintf(irp->f, "enumtagname ");
875static void ir_print_tag_name(IrPrint *irp, IrInstructionTagName *instruction) {
876 fprintf(irp->f, "tagname ");
890877 ir_print_other_instruction(irp, instruction->target);
891878}
892879
......@@ -994,6 +981,12 @@ static void ir_print_arg_type(IrPrint *irp, IrInstructionArgType *instruction) {
994981 fprintf(irp->f, ")");
995982}
996983
984static void ir_print_enum_tag_type(IrPrint *irp, IrInstructionTagType *instruction) {
985 fprintf(irp->f, "@TagType(");
986 ir_print_other_instruction(irp, instruction->target);
987 fprintf(irp->f, ")");
988}
989
997990
998991static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
999992 ir_print_prefix(irp, instruction);
......@@ -1072,9 +1065,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
10721065 case IrInstructionIdStructFieldPtr:
10731066 ir_print_struct_field_ptr(irp, (IrInstructionStructFieldPtr *)instruction);
10741067 break;
1075 case IrInstructionIdEnumFieldPtr:
1076 ir_print_enum_field_ptr(irp, (IrInstructionEnumFieldPtr *)instruction);
1077 break;
10781068 case IrInstructionIdUnionFieldPtr:
10791069 ir_print_union_field_ptr(irp, (IrInstructionUnionFieldPtr *)instruction);
10801070 break;
......@@ -1117,8 +1107,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
11171107 case IrInstructionIdSwitchTarget:
11181108 ir_print_switch_target(irp, (IrInstructionSwitchTarget *)instruction);
11191109 break;
1120 case IrInstructionIdEnumTag:
1121 ir_print_enum_tag(irp, (IrInstructionEnumTag *)instruction);
1110 case IrInstructionIdUnionTag:
1111 ir_print_union_tag(irp, (IrInstructionUnionTag *)instruction);
11221112 break;
11231113 case IrInstructionIdImport:
11241114 ir_print_import(irp, (IrInstructionImport *)instruction);
......@@ -1231,9 +1221,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
12311221 case IrInstructionIdTestComptime:
12321222 ir_print_test_comptime(irp, (IrInstructionTestComptime *)instruction);
12331223 break;
1234 case IrInstructionIdInitEnum:
1235 ir_print_init_enum(irp, (IrInstructionInitEnum *)instruction);
1236 break;
12371224 case IrInstructionIdPtrCast:
12381225 ir_print_ptr_cast(irp, (IrInstructionPtrCast *)instruction);
12391226 break;
......@@ -1267,8 +1254,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
12671254 case IrInstructionIdTypeName:
12681255 ir_print_type_name(irp, (IrInstructionTypeName *)instruction);
12691256 break;
1270 case IrInstructionIdEnumTagName:
1271 ir_print_enum_tag_name(irp, (IrInstructionEnumTagName *)instruction);
1257 case IrInstructionIdTagName:
1258 ir_print_tag_name(irp, (IrInstructionTagName *)instruction);
12721259 break;
12731260 case IrInstructionIdCanImplicitCast:
12741261 ir_print_can_implicit_cast(irp, (IrInstructionCanImplicitCast *)instruction);
......@@ -1312,6 +1299,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
13121299 case IrInstructionIdArgType:
13131300 ir_print_arg_type(irp, (IrInstructionArgType *)instruction);
13141301 break;
1302 case IrInstructionIdTagType:
1303 ir_print_enum_tag_type(irp, (IrInstructionTagType *)instruction);
1304 break;
13151305 }
13161306 fprintf(irp->f, "\n");
13171307}
src/os.cpp+5
......@@ -931,6 +931,7 @@ int os_self_exe_path(Buf *out_path) {
931931#define VT_GREEN "\x1b[32;1m"
932932#define VT_CYAN "\x1b[36;1m"
933933#define VT_WHITE "\x1b[37;1m"
934#define VT_BOLD "\x1b[0;1m"
934935#define VT_RESET "\x1b[0m"
935936
936937static void set_color_posix(TermColor color) {
......@@ -947,6 +948,9 @@ static void set_color_posix(TermColor color) {
947948 case TermColorWhite:
948949 fprintf(stderr, VT_WHITE);
949950 break;
951 case TermColorBold:
952 fprintf(stderr, VT_BOLD);
953 break;
950954 case TermColorReset:
951955 fprintf(stderr, VT_RESET);
952956 break;
......@@ -989,6 +993,7 @@ void os_stderr_set_color(TermColor color) {
989993 SetConsoleTextAttribute(stderr_handle, FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
990994 break;
991995 case TermColorWhite:
996 case TermColorBold:
992997 SetConsoleTextAttribute(stderr_handle,
993998 FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
994999 break;
src/os.hpp+1
......@@ -21,6 +21,7 @@ enum TermColor {
2121 TermColorGreen,
2222 TermColorCyan,
2323 TermColorWhite,
24 TermColorBold,
2425 TermColorReset,
2526};
2627
src/parser.cpp+48-20
......@@ -2377,9 +2377,11 @@ static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index, VisibMod vi
23772377}
23782378
23792379/*
2380ContainerDecl = option("extern" | "packed") ("struct" | "enum" | "union") "{" many(ContainerMember) "}"
2380ContainerDecl = option("extern" | "packed")
2381 ("struct" option(GroupedExpression) | "union" option("enum" option(GroupedExpression) | GroupedExpression) | ("enum" option(GroupedExpression)))
2382 "{" many(ContainerMember) "}"
23812383ContainerMember = (ContainerField | FnDef | GlobalVarDecl)
2382ContainerField = Symbol option(":" Expression) ","
2384ContainerField = Symbol option(":" PrefixOpExpression option("=" PrefixOpExpression ","
23832385*/
23842386static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory) {
23852387 Token *first_token = &pc->tokens->at(*token_index);
......@@ -2415,6 +2417,28 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
24152417 node->data.container_decl.layout = layout;
24162418 node->data.container_decl.kind = kind;
24172419
2420 if (kind == ContainerKindUnion) {
2421 Token *lparen_token = &pc->tokens->at(*token_index);
2422 if (lparen_token->id == TokenIdLParen) {
2423 Token *enum_token = &pc->tokens->at(*token_index + 1);
2424 if (enum_token->id == TokenIdKeywordEnum) {
2425 Token *paren_token = &pc->tokens->at(*token_index + 2);
2426 if (paren_token->id == TokenIdLParen) {
2427 node->data.container_decl.auto_enum = true;
2428 *token_index += 2;
2429 node->data.container_decl.init_arg_expr = ast_parse_grouped_expr(pc, token_index, true);
2430 ast_eat_token(pc, token_index, TokenIdRParen);
2431 } else if (paren_token->id == TokenIdRParen) {
2432 node->data.container_decl.auto_enum = true;
2433 *token_index += 3;
2434 }
2435 }
2436 }
2437 }
2438 if (!node->data.container_decl.auto_enum) {
2439 node->data.container_decl.init_arg_expr = ast_parse_grouped_expr(pc, token_index, false);
2440 }
2441
24182442 ast_eat_token(pc, token_index, TokenIdLBrace);
24192443
24202444 for (;;) {
......@@ -2452,31 +2476,33 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
24522476 AstNode *field_node = ast_create_node(pc, NodeTypeStructField, token);
24532477 *token_index += 1;
24542478
2479 node->data.container_decl.fields.append(field_node);
24552480 field_node->data.struct_field.visib_mod = visib_mod;
24562481 field_node->data.struct_field.name = token_buf(token);
24572482
2458 Token *token = &pc->tokens->at(*token_index);
2459 if (token->id == TokenIdComma || token->id == TokenIdRBrace) {
2460 field_node->data.struct_field.type = ast_create_void_type_node(pc, token);
2483 Token *colon_token = &pc->tokens->at(*token_index);
2484 if (colon_token->id == TokenIdColon) {
2485 *token_index += 1;
2486 field_node->data.struct_field.type = ast_parse_prefix_op_expr(pc, token_index, true);
2487 }
2488 Token *eq_token = &pc->tokens->at(*token_index);
2489 if (eq_token->id == TokenIdEq) {
24612490 *token_index += 1;
2462 node->data.container_decl.fields.append(field_node);
2491 field_node->data.struct_field.value = ast_parse_prefix_op_expr(pc, token_index, true);
2492 }
24632493
2464 if (token->id == TokenIdRBrace) {
2465 break;
2466 }
2467 } else {
2468 ast_eat_token(pc, token_index, TokenIdColon);
2469 field_node->data.struct_field.type = ast_parse_expression(pc, token_index, true);
2470 node->data.container_decl.fields.append(field_node);
2494 Token *next_token = &pc->tokens->at(*token_index);
2495 if (next_token->id == TokenIdComma) {
2496 *token_index += 1;
2497 continue;
2498 }
24712499
2472 Token *token = &pc->tokens->at(*token_index);
2473 if (token->id == TokenIdRBrace) {
2474 *token_index += 1;
2475 break;
2476 } else {
2477 ast_eat_token(pc, token_index, TokenIdComma);
2478 }
2500 if (next_token->id == TokenIdRBrace) {
2501 *token_index += 1;
2502 break;
24792503 }
2504
2505 ast_invalid_token_error(pc, next_token);
24802506 } else {
24812507 ast_invalid_token_error(pc, token);
24822508 }
......@@ -2804,9 +2830,11 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
28042830 case NodeTypeContainerDecl:
28052831 visit_node_list(&node->data.container_decl.fields, visit, context);
28062832 visit_node_list(&node->data.container_decl.decls, visit, context);
2833 visit_field(&node->data.container_decl.init_arg_expr, visit, context);
28072834 break;
28082835 case NodeTypeStructField:
28092836 visit_field(&node->data.struct_field.type, visit, context);
2837 visit_field(&node->data.struct_field.value, visit, context);
28102838 break;
28112839 case NodeTypeContainerInitExpr:
28122840 visit_field(&node->data.container_init_expr.type, visit, context);
src/translate_c.cpp+30-3
......@@ -651,6 +651,14 @@ static bool c_is_unsigned_integer(Context *c, QualType qt) {
651651 }
652652}
653653
654static bool c_is_builtin_type(Context *c, QualType qt, BuiltinType::Kind kind) {
655 const Type *c_type = qual_type_canon(qt);
656 if (c_type->getTypeClass() != Type::Builtin)
657 return false;
658 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
659 return builtin_ty->getKind() == kind;
660}
661
654662static bool c_is_float(Context *c, QualType qt) {
655663 const Type *c_type = qt.getTypePtr();
656664 if (c_type->getTypeClass() != Type::Builtin)
......@@ -978,11 +986,23 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
978986 const AttributedType *attributed_ty = static_cast<const AttributedType *>(ty);
979987 return trans_qual_type(c, attributed_ty->getEquivalentType(), source_loc);
980988 }
989 case Type::IncompleteArray:
990 {
991 const IncompleteArrayType *incomplete_array_ty = static_cast<const IncompleteArrayType *>(ty);
992 QualType child_qt = incomplete_array_ty->getElementType();
993 AstNode *child_type_node = trans_qual_type(c, child_qt, source_loc);
994 if (child_type_node == nullptr) {
995 emit_warning(c, source_loc, "unresolved array element type");
996 return nullptr;
997 }
998 AstNode *pointer_node = trans_create_node_addr_of(c, child_qt.isConstQualified(),
999 child_qt.isVolatileQualified(), child_type_node);
1000 return pointer_node;
1001 }
9811002 case Type::BlockPointer:
9821003 case Type::LValueReference:
9831004 case Type::RValueReference:
9841005 case Type::MemberPointer:
985 case Type::IncompleteArray:
9861006 case Type::VariableArray:
9871007 case Type::DependentSizedArray:
9881008 case Type::DependentSizedExtVector:
......@@ -3417,7 +3437,14 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
34173437 AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl);
34183438 enum_node->data.container_decl.kind = ContainerKindEnum;
34193439 enum_node->data.container_decl.layout = ContainerLayoutExtern;
3420 enum_node->data.container_decl.init_arg_expr = tag_int_type;
3440 // TODO only emit this tag type if the enum tag type is not the default.
3441 // I don't know what the default is, need to figure out how clang is deciding.
3442 // it appears to at least be different across gcc/msvc
3443 if (!c_is_builtin_type(c, enum_decl->getIntegerType(), BuiltinType::UInt) &&
3444 !c_is_builtin_type(c, enum_decl->getIntegerType(), BuiltinType::Int))
3445 {
3446 enum_node->data.container_decl.init_arg_expr = tag_int_type;
3447 }
34213448
34223449 enum_node->data.container_decl.fields.resize(field_count);
34233450 uint32_t i = 0;
......@@ -4304,7 +4331,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
43044331 }
43054332 }
43064333
4307 return 0;
4334 return ErrorCCompileErrors;
43084335 }
43094336
43104337 c->ctx = &ast_unit->getASTContext();
src/zig_llvm.cpp+1-1
......@@ -793,7 +793,7 @@ bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_
793793 zig_unreachable();
794794
795795 case ZigLLVM_COFF:
796 return lld::coff::link(array_ref_args, false);
796 return lld::coff::link(array_ref_args, false, diag);
797797
798798 case ZigLLVM_ELF:
799799 return lld::elf::link(array_ref_args, false, diag);
std/buffer.zig+6
......@@ -4,6 +4,8 @@ const Allocator = mem.Allocator;
44const assert = debug.assert;
55const ArrayList = @import("array_list.zig").ArrayList;
66
7const fmt = @import("fmt/index.zig");
8
79/// A buffer that allocates memory and maintains a null byte at the end.
810pub const Buffer = struct {
911 list: ArrayList(u8),
......@@ -96,6 +98,10 @@ pub const Buffer = struct {
9698 mem.copy(u8, self.list.toSlice()[old_len..], m);
9799 }
98100
101 pub fn appendFormat(self: &Buffer, comptime format: []const u8, args: ...) -> %void {
102 return fmt.format(self, append, format, args);
103 }
104
99105 pub fn appendByte(self: &Buffer, byte: u8) -> %void {
100106 return self.appendByteNTimes(byte, 1);
101107 }
std/build.zig+21-21
......@@ -69,8 +69,8 @@ pub const Builder = struct {
6969 used: bool,
7070 };
7171
72 const UserValue = enum {
73 Flag,
72 const UserValue = union(enum) {
73 Flag: void,
7474 Scalar: []const u8,
7575 List: ArrayList([]const u8),
7676 };
......@@ -450,7 +450,7 @@ pub const Builder = struct {
450450 pub fn addUserInputOption(self: &Builder, name: []const u8, value: []const u8) -> bool {
451451 if (%%self.user_input_options.put(name, UserInputOption {
452452 .name = name,
453 .value = UserValue.Scalar { value },
453 .value = UserValue { .Scalar = value },
454454 .used = false,
455455 })) |*prev_value| {
456456 // option already exists
......@@ -462,7 +462,7 @@ pub const Builder = struct {
462462 %%list.append(value);
463463 _ = %%self.user_input_options.put(name, UserInputOption {
464464 .name = name,
465 .value = UserValue.List { list },
465 .value = UserValue { .List = list },
466466 .used = false,
467467 });
468468 },
......@@ -471,7 +471,7 @@ pub const Builder = struct {
471471 %%list.append(value);
472472 _ = %%self.user_input_options.put(name, UserInputOption {
473473 .name = name,
474 .value = UserValue.List { *list },
474 .value = UserValue { .List = *list },
475475 .used = false,
476476 });
477477 },
......@@ -487,7 +487,7 @@ pub const Builder = struct {
487487 pub fn addUserInputFlag(self: &Builder, name: []const u8) -> bool {
488488 if (%%self.user_input_options.put(name, UserInputOption {
489489 .name = name,
490 .value = UserValue.Flag,
490 .value = UserValue {.Flag = {} },
491491 .used = false,
492492 })) |*prev_value| {
493493 switch (prev_value.value) {
......@@ -685,8 +685,8 @@ const CrossTarget = struct {
685685 environ: builtin.Environ,
686686};
687687
688const Target = enum {
689 Native,
688const Target = union(enum) {
689 Native: void,
690690 Cross: CrossTarget,
691691
692692 pub fn oFileExt(self: &const Target) -> []const u8 {
......@@ -844,7 +844,7 @@ pub const LibExeObjStep = struct {
844844 .kind = kind,
845845 .root_src = root_src,
846846 .name = name,
847 .target = Target.Native,
847 .target = Target { .Native = {} },
848848 .linker_script = null,
849849 .link_libs = BufSet.init(builder.allocator),
850850 .frameworks = BufSet.init(builder.allocator),
......@@ -879,7 +879,7 @@ pub const LibExeObjStep = struct {
879879 .kind = kind,
880880 .version = *version,
881881 .static = static,
882 .target = Target.Native,
882 .target = Target { .Native = {} },
883883 .cflags = ArrayList([]const u8).init(builder.allocator),
884884 .source_files = ArrayList([]const u8).init(builder.allocator),
885885 .object_files = ArrayList([]const u8).init(builder.allocator),
......@@ -948,8 +948,8 @@ pub const LibExeObjStep = struct {
948948 pub fn setTarget(self: &LibExeObjStep, target_arch: builtin.Arch, target_os: builtin.Os,
949949 target_environ: builtin.Environ)
950950 {
951 self.target = Target.Cross {
952 CrossTarget {
951 self.target = Target {
952 .Cross = CrossTarget {
953953 .arch = target_arch,
954954 .os = target_os,
955955 .environ = target_environ,
......@@ -1186,13 +1186,13 @@ pub const LibExeObjStep = struct {
11861186 Target.Native => {},
11871187 Target.Cross => |cross_target| {
11881188 %%zig_args.append("--target-arch");
1189 %%zig_args.append(@enumTagName(cross_target.arch));
1189 %%zig_args.append(@tagName(cross_target.arch));
11901190
11911191 %%zig_args.append("--target-os");
1192 %%zig_args.append(@enumTagName(cross_target.os));
1192 %%zig_args.append(@tagName(cross_target.os));
11931193
11941194 %%zig_args.append("--target-environ");
1195 %%zig_args.append(@enumTagName(cross_target.environ));
1195 %%zig_args.append(@tagName(cross_target.environ));
11961196 },
11971197 }
11981198
......@@ -1553,7 +1553,7 @@ pub const TestStep = struct {
15531553 .name_prefix = "",
15541554 .filter = null,
15551555 .link_libs = BufSet.init(builder.allocator),
1556 .target = Target.Native,
1556 .target = Target { .Native = {} },
15571557 .exec_cmd_args = null,
15581558 }
15591559 }
......@@ -1581,8 +1581,8 @@ pub const TestStep = struct {
15811581 pub fn setTarget(self: &TestStep, target_arch: builtin.Arch, target_os: builtin.Os,
15821582 target_environ: builtin.Environ)
15831583 {
1584 self.target = Target.Cross {
1585 CrossTarget {
1584 self.target = Target {
1585 .Cross = CrossTarget {
15861586 .arch = target_arch,
15871587 .os = target_os,
15881588 .environ = target_environ,
......@@ -1620,13 +1620,13 @@ pub const TestStep = struct {
16201620 Target.Native => {},
16211621 Target.Cross => |cross_target| {
16221622 %%zig_args.append("--target-arch");
1623 %%zig_args.append(@enumTagName(cross_target.arch));
1623 %%zig_args.append(@tagName(cross_target.arch));
16241624
16251625 %%zig_args.append("--target-os");
1626 %%zig_args.append(@enumTagName(cross_target.os));
1626 %%zig_args.append(@tagName(cross_target.os));
16271627
16281628 %%zig_args.append("--target-environ");
1629 %%zig_args.append(@enumTagName(cross_target.environ));
1629 %%zig_args.append(@tagName(cross_target.environ));
16301630 },
16311631 }
16321632
std/debug.zig+22-24
......@@ -280,7 +280,7 @@ const AbbrevAttr = struct {
280280 form_id: u64,
281281};
282282
283const FormValue = enum {
283const FormValue = union(enum) {
284284 Address: u64,
285285 Block: []u8,
286286 Const: Constant,
......@@ -303,7 +303,7 @@ const Constant = struct {
303303 return error.InvalidDebugInfo;
304304 if (self.signed)
305305 return error.InvalidDebugInfo;
306 return mem.readInt(self.payload, u64, false);
306 return mem.readInt(self.payload, u64, builtin.Endian.Little);
307307 }
308308};
309309
......@@ -475,16 +475,16 @@ fn readAllocBytes(allocator: &mem.Allocator, in_stream: &io.InStream, size: usiz
475475
476476fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {
477477 const buf = %return readAllocBytes(allocator, in_stream, size);
478 return FormValue.Block { buf };
478 return FormValue { .Block = buf };
479479}
480480
481481fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {
482 const block_len = %return in_stream.readVarInt(false, usize, size);
482 const block_len = %return in_stream.readVarInt(builtin.Endian.Little, usize, size);
483483 return parseFormValueBlockLen(allocator, in_stream, block_len);
484484}
485485
486486fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: &io.InStream, signed: bool, size: usize) -> %FormValue {
487 FormValue.Const { Constant {
487 FormValue { .Const = Constant {
488488 .signed = signed,
489489 .payload = %return readAllocBytes(allocator, in_stream, size),
490490 }}
......@@ -510,7 +510,7 @@ fn parseFormValueTargetAddrSize(in_stream: &io.InStream) -> %u64 {
510510
511511fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {
512512 const buf = %return readAllocBytes(allocator, in_stream, size);
513 return FormValue.Ref { buf };
513 return FormValue { .Ref = buf };
514514}
515515
516516fn parseFormValueRef(allocator: &mem.Allocator, in_stream: &io.InStream, comptime T: type) -> %FormValue {
......@@ -520,7 +520,7 @@ fn parseFormValueRef(allocator: &mem.Allocator, in_stream: &io.InStream, comptim
520520
521521fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u64, is_64: bool) -> %FormValue {
522522 return switch (form_id) {
523 DW.FORM_addr => FormValue.Address { %return parseFormValueTargetAddrSize(in_stream) },
523 DW.FORM_addr => FormValue { .Address = %return parseFormValueTargetAddrSize(in_stream) },
524524 DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),
525525 DW.FORM_block2 => parseFormValueBlock(allocator, in_stream, 2),
526526 DW.FORM_block4 => parseFormValueBlock(allocator, in_stream, 4),
......@@ -540,13 +540,11 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
540540 DW.FORM_exprloc => {
541541 const size = %return readULeb128(in_stream);
542542 const buf = %return readAllocBytes(allocator, in_stream, size);
543 return FormValue.ExprLoc { buf };
544 },
545 DW.FORM_flag => FormValue.Flag { (%return in_stream.readByte()) != 0 },
546 DW.FORM_flag_present => FormValue.Flag { true },
547 DW.FORM_sec_offset => FormValue.SecOffset {
548 %return parseFormValueDwarfOffsetSize(in_stream, is_64)
543 return FormValue { .ExprLoc = buf };
549544 },
545 DW.FORM_flag => FormValue { .Flag = (%return in_stream.readByte()) != 0 },
546 DW.FORM_flag_present => FormValue { .Flag = true },
547 DW.FORM_sec_offset => FormValue { .SecOffset = %return parseFormValueDwarfOffsetSize(in_stream, is_64) },
550548
551549 DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, u8),
552550 DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, u16),
......@@ -557,11 +555,11 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
557555 parseFormValueRefLen(allocator, in_stream, ref_len)
558556 },
559557
560 DW.FORM_ref_addr => FormValue.RefAddr { %return parseFormValueDwarfOffsetSize(in_stream, is_64) },
561 DW.FORM_ref_sig8 => FormValue.RefSig8 { %return in_stream.readIntLe(u64) },
558 DW.FORM_ref_addr => FormValue { .RefAddr = %return parseFormValueDwarfOffsetSize(in_stream, is_64) },
559 DW.FORM_ref_sig8 => FormValue { .RefSig8 = %return in_stream.readIntLe(u64) },
562560
563 DW.FORM_string => FormValue.String { %return readStringRaw(allocator, in_stream) },
564 DW.FORM_strp => FormValue.StrPtr { %return parseFormValueDwarfOffsetSize(in_stream, is_64) },
561 DW.FORM_string => FormValue { .String = %return readStringRaw(allocator, in_stream) },
562 DW.FORM_strp => FormValue { .StrPtr = %return parseFormValueDwarfOffsetSize(in_stream, is_64) },
565563 DW.FORM_indirect => {
566564 const child_form_id = %return readULeb128(in_stream);
567565 parseFormValue(allocator, in_stream, child_form_id, is_64)
......@@ -671,10 +669,10 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
671669 continue;
672670 }
673671
674 const version = %return in_stream.readInt(st.elf.is_big_endian, u16);
672 const version = %return in_stream.readInt(st.elf.endian, u16);
675673 if (version != 2) return error.InvalidDebugInfo;
676674
677 const prologue_length = %return in_stream.readInt(st.elf.is_big_endian, u32);
675 const prologue_length = %return in_stream.readInt(st.elf.endian, u32);
678676 const prog_start_offset = (%return in_file.getPos()) + prologue_length;
679677
680678 const minimum_instruction_length = %return in_stream.readByte();
......@@ -741,7 +739,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
741739 return error.MissingDebugInfo;
742740 },
743741 DW.LNE_set_address => {
744 const addr = %return in_stream.readInt(st.elf.is_big_endian, usize);
742 const addr = %return in_stream.readInt(st.elf.endian, usize);
745743 prog.address = addr;
746744 },
747745 DW.LNE_define_file => {
......@@ -803,7 +801,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
803801 prog.address += inc_addr;
804802 },
805803 DW.LNS_fixed_advance_pc => {
806 const arg = %return in_stream.readInt(st.elf.is_big_endian, u16);
804 const arg = %return in_stream.readInt(st.elf.endian, u16);
807805 prog.address += arg;
808806 },
809807 DW.LNS_set_prologue_end => {
......@@ -841,13 +839,13 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
841839 return;
842840 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
843841
844 const version = %return in_stream.readInt(st.elf.is_big_endian, u16);
842 const version = %return in_stream.readInt(st.elf.endian, u16);
845843 if (version < 2 or version > 5) return error.InvalidDebugInfo;
846844
847845 const debug_abbrev_offset = if (is_64) {
848 %return in_stream.readInt(st.elf.is_big_endian, u64)
846 %return in_stream.readInt(st.elf.endian, u64)
849847 } else {
850 %return in_stream.readInt(st.elf.is_big_endian, u32)
848 %return in_stream.readInt(st.elf.endian, u32)
851849 };
852850
853851 const address_size = %return in_stream.readByte();
std/elf.zig+40-39
......@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
12const std = @import("index.zig");
23const io = std.io;
34const math = std.math;
......@@ -67,7 +68,7 @@ pub const Elf = struct {
6768 in_file: &io.File,
6869 auto_close_stream: bool,
6970 is_64: bool,
70 is_big_endian: bool,
71 endian: builtin.Endian,
7172 file_type: FileType,
7273 arch: Arch,
7374 entry_addr: u64,
......@@ -105,9 +106,9 @@ pub const Elf = struct {
105106 else => return error.InvalidFormat,
106107 };
107108
108 elf.is_big_endian = switch (%return in.readByte()) {
109 1 => false,
110 2 => true,
109 elf.endian = switch (%return in.readByte()) {
110 1 => builtin.Endian.Little,
111 2 => builtin.Endian.Big,
111112 else => return error.InvalidFormat,
112113 };
113114
......@@ -117,7 +118,7 @@ pub const Elf = struct {
117118 // skip over padding
118119 %return elf.in_file.seekForward(9);
119120
120 elf.file_type = switch (%return in.readInt(elf.is_big_endian, u16)) {
121 elf.file_type = switch (%return in.readInt(elf.endian, u16)) {
121122 1 => FileType.Relocatable,
122123 2 => FileType.Executable,
123124 3 => FileType.Shared,
......@@ -125,7 +126,7 @@ pub const Elf = struct {
125126 else => return error.InvalidFormat,
126127 };
127128
128 elf.arch = switch (%return in.readInt(elf.is_big_endian, u16)) {
129 elf.arch = switch (%return in.readInt(elf.endian, u16)) {
129130 0x02 => Arch.Sparc,
130131 0x03 => Arch.x86,
131132 0x08 => Arch.Mips,
......@@ -138,34 +139,34 @@ pub const Elf = struct {
138139 else => return error.InvalidFormat,
139140 };
140141
141 const elf_version = %return in.readInt(elf.is_big_endian, u32);
142 const elf_version = %return in.readInt(elf.endian, u32);
142143 if (elf_version != 1) return error.InvalidFormat;
143144
144145 if (elf.is_64) {
145 elf.entry_addr = %return in.readInt(elf.is_big_endian, u64);
146 elf.program_header_offset = %return in.readInt(elf.is_big_endian, u64);
147 elf.section_header_offset = %return in.readInt(elf.is_big_endian, u64);
146 elf.entry_addr = %return in.readInt(elf.endian, u64);
147 elf.program_header_offset = %return in.readInt(elf.endian, u64);
148 elf.section_header_offset = %return in.readInt(elf.endian, u64);
148149 } else {
149 elf.entry_addr = u64(%return in.readInt(elf.is_big_endian, u32));
150 elf.program_header_offset = u64(%return in.readInt(elf.is_big_endian, u32));
151 elf.section_header_offset = u64(%return in.readInt(elf.is_big_endian, u32));
150 elf.entry_addr = u64(%return in.readInt(elf.endian, u32));
151 elf.program_header_offset = u64(%return in.readInt(elf.endian, u32));
152 elf.section_header_offset = u64(%return in.readInt(elf.endian, u32));
152153 }
153154
154155 // skip over flags
155156 %return elf.in_file.seekForward(4);
156157
157 const header_size = %return in.readInt(elf.is_big_endian, u16);
158 const header_size = %return in.readInt(elf.endian, u16);
158159 if ((elf.is_64 and header_size != 64) or
159160 (!elf.is_64 and header_size != 52))
160161 {
161162 return error.InvalidFormat;
162163 }
163164
164 const ph_entry_size = %return in.readInt(elf.is_big_endian, u16);
165 const ph_entry_count = %return in.readInt(elf.is_big_endian, u16);
166 const sh_entry_size = %return in.readInt(elf.is_big_endian, u16);
167 const sh_entry_count = %return in.readInt(elf.is_big_endian, u16);
168 elf.string_section_index = u64(%return in.readInt(elf.is_big_endian, u16));
165 const ph_entry_size = %return in.readInt(elf.endian, u16);
166 const ph_entry_count = %return in.readInt(elf.endian, u16);
167 const sh_entry_size = %return in.readInt(elf.endian, u16);
168 const sh_entry_count = %return in.readInt(elf.endian, u16);
169 elf.string_section_index = u64(%return in.readInt(elf.endian, u16));
169170
170171 if (elf.string_section_index >= sh_entry_count) return error.InvalidFormat;
171172
......@@ -188,32 +189,32 @@ pub const Elf = struct {
188189 if (sh_entry_size != 64) return error.InvalidFormat;
189190
190191 for (elf.section_headers) |*section| {
191 section.name = %return in.readInt(elf.is_big_endian, u32);
192 section.sh_type = %return in.readInt(elf.is_big_endian, u32);
193 section.flags = %return in.readInt(elf.is_big_endian, u64);
194 section.addr = %return in.readInt(elf.is_big_endian, u64);
195 section.offset = %return in.readInt(elf.is_big_endian, u64);
196 section.size = %return in.readInt(elf.is_big_endian, u64);
197 section.link = %return in.readInt(elf.is_big_endian, u32);
198 section.info = %return in.readInt(elf.is_big_endian, u32);
199 section.addr_align = %return in.readInt(elf.is_big_endian, u64);
200 section.ent_size = %return in.readInt(elf.is_big_endian, u64);
192 section.name = %return in.readInt(elf.endian, u32);
193 section.sh_type = %return in.readInt(elf.endian, u32);
194 section.flags = %return in.readInt(elf.endian, u64);
195 section.addr = %return in.readInt(elf.endian, u64);
196 section.offset = %return in.readInt(elf.endian, u64);
197 section.size = %return in.readInt(elf.endian, u64);
198 section.link = %return in.readInt(elf.endian, u32);
199 section.info = %return in.readInt(elf.endian, u32);
200 section.addr_align = %return in.readInt(elf.endian, u64);
201 section.ent_size = %return in.readInt(elf.endian, u64);
201202 }
202203 } else {
203204 if (sh_entry_size != 40) return error.InvalidFormat;
204205
205206 for (elf.section_headers) |*section| {
206207 // TODO (multiple occurences) allow implicit cast from %u32 -> %u64 ?
207 section.name = %return in.readInt(elf.is_big_endian, u32);
208 section.sh_type = %return in.readInt(elf.is_big_endian, u32);
209 section.flags = u64(%return in.readInt(elf.is_big_endian, u32));
210 section.addr = u64(%return in.readInt(elf.is_big_endian, u32));
211 section.offset = u64(%return in.readInt(elf.is_big_endian, u32));
212 section.size = u64(%return in.readInt(elf.is_big_endian, u32));
213 section.link = %return in.readInt(elf.is_big_endian, u32);
214 section.info = %return in.readInt(elf.is_big_endian, u32);
215 section.addr_align = u64(%return in.readInt(elf.is_big_endian, u32));
216 section.ent_size = u64(%return in.readInt(elf.is_big_endian, u32));
208 section.name = %return in.readInt(elf.endian, u32);
209 section.sh_type = %return in.readInt(elf.endian, u32);
210 section.flags = u64(%return in.readInt(elf.endian, u32));
211 section.addr = u64(%return in.readInt(elf.endian, u32));
212 section.offset = u64(%return in.readInt(elf.endian, u32));
213 section.size = u64(%return in.readInt(elf.endian, u32));
214 section.link = %return in.readInt(elf.endian, u32);
215 section.info = %return in.readInt(elf.endian, u32);
216 section.addr_align = u64(%return in.readInt(elf.endian, u32));
217 section.ent_size = u64(%return in.readInt(elf.endian, u32));
217218 }
218219 }
219220
std/endian.zig+2-2
......@@ -9,8 +9,8 @@ pub fn swapIfBe(comptime T: type, x: T) -> T {
99 swapIf(true, T, x)
1010}
1111
12pub fn swapIf(is_be: bool, comptime T: type, x: T) -> T {
13 if (builtin.is_big_endian == is_be) swap(T, x) else x
12pub fn swapIf(endian: builtin.Endian, comptime T: type, x: T) -> T {
13 if (builtin.endian == endian) swap(T, x) else x
1414}
1515
1616pub fn swap(comptime T: type, x: T) -> T {
std/io.zig+7-7
......@@ -259,7 +259,7 @@ pub const File = struct {
259259 if (err > 0) {
260260 return switch (err) {
261261 system.EBADF => error.BadFd,
262 system.ENOMEM => error.OutOfMemory,
262 system.ENOMEM => error.SystemResources,
263263 else => os.unexpectedErrorPosix(err),
264264 }
265265 }
......@@ -441,26 +441,26 @@ pub const InStream = struct {
441441 }
442442
443443 pub fn readIntLe(self: &InStream, comptime T: type) -> %T {
444 return self.readInt(false, T);
444 return self.readInt(builtin.Endian.Little, T);
445445 }
446446
447447 pub fn readIntBe(self: &InStream, comptime T: type) -> %T {
448 return self.readInt(true, T);
448 return self.readInt(builtin.Endian.Big, T);
449449 }
450450
451 pub fn readInt(self: &InStream, is_be: bool, comptime T: type) -> %T {
451 pub fn readInt(self: &InStream, endian: builtin.Endian, comptime T: type) -> %T {
452452 var bytes: [@sizeOf(T)]u8 = undefined;
453453 %return self.readNoEof(bytes[0..]);
454 return mem.readInt(bytes, T, is_be);
454 return mem.readInt(bytes, T, endian);
455455 }
456456
457 pub fn readVarInt(self: &InStream, is_be: bool, comptime T: type, size: usize) -> %T {
457 pub fn readVarInt(self: &InStream, endian: builtin.Endian, comptime T: type, size: usize) -> %T {
458458 assert(size <= @sizeOf(T));
459459 assert(size <= 8);
460460 var input_buf: [8]u8 = undefined;
461461 const input_slice = input_buf[0..size];
462462 %return self.readNoEof(input_slice);
463 return mem.readInt(input_slice, T, is_be);
463 return mem.readInt(input_slice, T, endian);
464464 }
465465
466466
std/mem.zig+79-32
......@@ -1,6 +1,7 @@
11const debug = @import("debug.zig");
22const assert = debug.assert;
33const math = @import("math/index.zig");
4const builtin = @import("builtin");
45
56pub const Cmp = math.Cmp;
67
......@@ -180,43 +181,78 @@ test "mem.indexOf" {
180181/// Reads an integer from memory with size equal to bytes.len.
181182/// T specifies the return type, which must be large enough to store
182183/// the result.
183pub fn readInt(bytes: []const u8, comptime T: type, big_endian: bool) -> T {
184/// See also ::readIntBE or ::readIntLE.
185pub fn readInt(bytes: []const u8, comptime T: type, endian: builtin.Endian) -> T {
184186 if (T.bit_count == 8) {
185187 return bytes[0];
186188 }
187189 var result: T = 0;
188 if (big_endian) {
189 for (bytes) |b| {
190 result = (result << 8) | b;
191 }
192 } else {
193 const ShiftType = math.Log2Int(T);
194 for (bytes) |b, index| {
195 result = result | (T(b) << ShiftType(index * 8));
196 }
190 switch (endian) {
191 builtin.Endian.Big => {
192 for (bytes) |b| {
193 result = (result << 8) | b;
194 }
195 },
196 builtin.Endian.Little => {
197 const ShiftType = math.Log2Int(T);
198 for (bytes) |b, index| {
199 result = result | (T(b) << ShiftType(index * 8));
200 }
201 },
197202 }
198203 return result;
199204}
200205
206/// Reads a big-endian int of type T from bytes.
207/// bytes.len must be exactly @sizeOf(T).
208pub fn readIntBE(comptime T: type, bytes: []const u8) -> T {
209 if (T.is_signed) {
210 return @bitCast(T, readIntBE(@IntType(false, T.bit_count), bytes));
211 }
212 assert(bytes.len == @sizeOf(T));
213 var result: T = 0;
214 {comptime var i = 0; inline while (i < @sizeOf(T)) : (i += 1) {
215 result = (result << 8) | T(bytes[i]);
216 }}
217 return result;
218}
219
220/// Reads a little-endian int of type T from bytes.
221/// bytes.len must be exactly @sizeOf(T).
222pub fn readIntLE(comptime T: type, bytes: []const u8) -> T {
223 if (T.is_signed) {
224 return @bitCast(T, readIntLE(@IntType(false, T.bit_count), bytes));
225 }
226 assert(bytes.len == @sizeOf(T));
227 var result: T = 0;
228 {comptime var i = 0; inline while (i < @sizeOf(T)) : (i += 1) {
229 result |= T(bytes[i]) << i * 8;
230 }}
231 return result;
232}
233
201234/// Writes an integer to memory with size equal to bytes.len. Pads with zeroes
202235/// to fill the entire buffer provided.
203236/// value must be an integer.
204pub fn writeInt(buf: []u8, value: var, big_endian: bool) {
237pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) {
205238 const uint = @IntType(false, @typeOf(value).bit_count);
206239 var bits = @truncate(uint, value);
207 if (big_endian) {
208 var index: usize = buf.len;
209 while (index != 0) {
210 index -= 1;
211
212 buf[index] = @truncate(u8, bits);
213 bits >>= 8;
214 }
215 } else {
216 for (buf) |*b| {
217 *b = @truncate(u8, bits);
218 bits >>= 8;
219 }
240 switch (endian) {
241 builtin.Endian.Big => {
242 var index: usize = buf.len;
243 while (index != 0) {
244 index -= 1;
245
246 buf[index] = @truncate(u8, bits);
247 bits >>= 8;
248 }
249 },
250 builtin.Endian.Little => {
251 for (buf) |*b| {
252 *b = @truncate(u8, bits);
253 bits >>= 8;
254 }
255 },
220256 }
221257 assert(bits == 0);
222258}
......@@ -348,19 +384,30 @@ test "testReadInt" {
348384fn testReadIntImpl() {
349385 {
350386 const bytes = []u8{ 0x12, 0x34, 0x56, 0x78 };
351 assert(readInt(bytes, u32, true) == 0x12345678);
352 assert(readInt(bytes, u32, false) == 0x78563412);
387 assert(readInt(bytes, u32, builtin.Endian.Big) == 0x12345678);
388 assert(readIntBE(u32, bytes) == 0x12345678);
389 assert(readIntBE(i32, bytes) == 0x12345678);
390 assert(readInt(bytes, u32, builtin.Endian.Little) == 0x78563412);
391 assert(readIntLE(u32, bytes) == 0x78563412);
392 assert(readIntLE(i32, bytes) == 0x78563412);
353393 }
354394 {
355395 const buf = []u8{0x00, 0x00, 0x12, 0x34};
356 const answer = readInt(buf, u64, true);
396 const answer = readInt(buf, u64, builtin.Endian.Big);
357397 assert(answer == 0x00001234);
358398 }
359399 {
360400 const buf = []u8{0x12, 0x34, 0x00, 0x00};
361 const answer = readInt(buf, u64, false);
401 const answer = readInt(buf, u64, builtin.Endian.Little);
362402 assert(answer == 0x00003412);
363403 }
404 {
405 const bytes = []u8{0xff, 0xfe};
406 assert(readIntBE(u16, bytes) == 0xfffe);
407 assert(readIntBE(i16, bytes) == -0x0002);
408 assert(readIntLE(u16, bytes) == 0xfeff);
409 assert(readIntLE(i16, bytes) == -0x0101);
410 }
364411}
365412
366413test "testWriteInt" {
......@@ -370,16 +417,16 @@ test "testWriteInt" {
370417fn testWriteIntImpl() {
371418 var bytes: [4]u8 = undefined;
372419
373 writeInt(bytes[0..], u32(0x12345678), true);
420 writeInt(bytes[0..], u32(0x12345678), builtin.Endian.Big);
374421 assert(eql(u8, bytes, []u8{ 0x12, 0x34, 0x56, 0x78 }));
375422
376 writeInt(bytes[0..], u32(0x78563412), false);
423 writeInt(bytes[0..], u32(0x78563412), builtin.Endian.Little);
377424 assert(eql(u8, bytes, []u8{ 0x12, 0x34, 0x56, 0x78 }));
378425
379 writeInt(bytes[0..], u16(0x1234), true);
426 writeInt(bytes[0..], u16(0x1234), builtin.Endian.Big);
380427 assert(eql(u8, bytes, []u8{ 0x00, 0x00, 0x12, 0x34 }));
381428
382 writeInt(bytes[0..], u16(0x1234), false);
429 writeInt(bytes[0..], u16(0x1234), builtin.Endian.Little);
383430 assert(eql(u8, bytes, []u8{ 0x34, 0x12, 0x00, 0x00 }));
384431}
385432
std/os/child_process.zig+9-9
......@@ -58,7 +58,7 @@ pub const ChildProcess = struct {
5858 err_pipe: if (is_windows) void else [2]i32,
5959 llnode: if (is_windows) void else LinkedList(&ChildProcess).Node,
6060
61 pub const Term = enum {
61 pub const Term = union(enum) {
6262 Exited: i32,
6363 Signal: i32,
6464 Stopped: i32,
......@@ -213,9 +213,9 @@ pub const ChildProcess = struct {
213213 self.term = (%Term)({
214214 var exit_code: windows.DWORD = undefined;
215215 if (windows.GetExitCodeProcess(self.handle, &exit_code) == 0) {
216 Term.Unknown{0}
216 Term { .Unknown = 0 }
217217 } else {
218 Term.Exited {@bitCast(i32, exit_code)}
218 Term { .Exited = @bitCast(i32, exit_code)}
219219 }
220220 });
221221
......@@ -281,13 +281,13 @@ pub const ChildProcess = struct {
281281
282282 fn statusToTerm(status: i32) -> Term {
283283 return if (posix.WIFEXITED(status)) {
284 Term.Exited { posix.WEXITSTATUS(status) }
284 Term { .Exited = posix.WEXITSTATUS(status) }
285285 } else if (posix.WIFSIGNALED(status)) {
286 Term.Signal { posix.WTERMSIG(status) }
286 Term { .Signal = posix.WTERMSIG(status) }
287287 } else if (posix.WIFSTOPPED(status)) {
288 Term.Stopped { posix.WSTOPSIG(status) }
288 Term { .Stopped = posix.WSTOPSIG(status) }
289289 } else {
290 Term.Unknown { status }
290 Term { .Unknown = status }
291291 };
292292 }
293293
......@@ -722,14 +722,14 @@ const ErrInt = @IntType(false, @sizeOf(error) * 8);
722722
723723fn writeIntFd(fd: i32, value: ErrInt) -> %void {
724724 var bytes: [@sizeOf(ErrInt)]u8 = undefined;
725 mem.writeInt(bytes[0..], value, true);
725 mem.writeInt(bytes[0..], value, builtin.endian);
726726 os.posixWrite(fd, bytes[0..]) %% return error.SystemResources;
727727}
728728
729729fn readIntFd(fd: i32) -> %ErrInt {
730730 var bytes: [@sizeOf(ErrInt)]u8 = undefined;
731731 os.posixRead(fd, bytes[0..]) %% return error.SystemResources;
732 return mem.readInt(bytes[0..], ErrInt, true);
732 return mem.readInt(bytes[0..], ErrInt, builtin.endian);
733733}
734734
735735extern fn sigchld_handler(_: i32) {
std/os/index.zig+3-2
......@@ -939,6 +939,7 @@ start_over:
939939}
940940
941941pub const Dir = struct {
942 // See man getdents
942943 fd: i32,
943944 allocator: &Allocator,
944945 buf: []u8,
......@@ -981,7 +982,7 @@ pub const Dir = struct {
981982
982983 pub fn close(self: &Dir) {
983984 self.allocator.free(self.buf);
984 close(self.fd);
985 os.close(self.fd);
985986 }
986987
987988 /// Memory such as file names referenced in this returned entry becomes invalid
......@@ -1013,7 +1014,7 @@ pub const Dir = struct {
10131014 break;
10141015 }
10151016 }
1016 const linux_entry = @ptrCast(&LinuxEntry, &self.buf[self.index]);
1017 const linux_entry = @ptrCast(& align(1) LinuxEntry, &self.buf[self.index]);
10171018 const next_index = self.index + linux_entry.d_reclen;
10181019 self.index = next_index;
10191020
std/os/path.zig+1-1
......@@ -1016,7 +1016,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
10161016
10171017 return os.readLink(allocator, proc_path);
10181018 },
1019 else => @compileError("TODO implement os.path.real for " ++ @enumTagName(builtin.os)),
1019 else => @compileError("TODO implement os.path.real for " ++ @tagName(builtin.os)),
10201020 }
10211021}
10221022
std/rand.zig+3-3
......@@ -50,12 +50,12 @@ pub const Rand = struct {
5050 pub fn fillBytes(r: &Rand, buf: []u8) {
5151 var bytes_left = buf.len;
5252 while (bytes_left >= @sizeOf(usize)) {
53 mem.writeInt(buf[buf.len - bytes_left..], r.rng.get(), false);
53 mem.writeInt(buf[buf.len - bytes_left..], r.rng.get(), builtin.Endian.Little);
5454 bytes_left -= @sizeOf(usize);
5555 }
5656 if (bytes_left > 0) {
5757 var rand_val_array: [@sizeOf(usize)]u8 = undefined;
58 mem.writeInt(rand_val_array[0..], r.rng.get(), false);
58 mem.writeInt(rand_val_array[0..], r.rng.get(), builtin.Endian.Little);
5959 while (bytes_left > 0) {
6060 buf[buf.len - bytes_left] = rand_val_array[@sizeOf(usize) - bytes_left];
6161 bytes_left -= 1;
......@@ -98,7 +98,7 @@ pub const Rand = struct {
9898
9999 while (true) {
100100 r.fillBytes(rand_val_array[0..]);
101 const rand_val = mem.readInt(rand_val_array, T, false);
101 const rand_val = mem.readInt(rand_val_array, T, builtin.Endian.Little);
102102 if (rand_val < upper_bound) {
103103 return start + (rand_val % total_range);
104104 }
std/sort.zig+70
......@@ -4,6 +4,19 @@ const math = @import("math/index.zig");
44
55pub const Cmp = math.Cmp;
66
7/// Stable sort using O(1) space. Currently implemented as insertion sort.
8pub fn sort_stable(comptime T: type, array: []T, comptime cmp: fn(a: &const T, b: &const T)->Cmp) {
9 {var i: usize = 1; while (i < array.len) : (i += 1) {
10 const x = array[i];
11 var j: usize = i;
12 while (j > 0 and cmp(array[j - 1], x) == Cmp.Greater) : (j -= 1) {
13 array[j] = array[j - 1];
14 }
15 array[j] = x;
16 }}
17}
18
19/// Unstable sort using O(n) stack space. Currently implemented as quicksort.
720pub fn sort(comptime T: type, array: []T, comptime cmp: fn(a: &const T, b: &const T)->Cmp) {
821 if (array.len > 0) {
922 quicksort(T, array, 0, array.len - 1, cmp);
......@@ -58,6 +71,63 @@ fn reverse(was: Cmp) -> Cmp {
5871// ---------------------------------------
5972// tests
6073
74test "stable sort" {
75 testStableSort();
76 // TODO: uncomment this after https://github.com/zig-lang/zig/issues/639
77 //comptime testStableSort();
78}
79fn testStableSort() {
80 var expected = []IdAndValue {
81 IdAndValue{.id = 0, .value = 0},
82 IdAndValue{.id = 1, .value = 0},
83 IdAndValue{.id = 2, .value = 0},
84 IdAndValue{.id = 0, .value = 1},
85 IdAndValue{.id = 1, .value = 1},
86 IdAndValue{.id = 2, .value = 1},
87 IdAndValue{.id = 0, .value = 2},
88 IdAndValue{.id = 1, .value = 2},
89 IdAndValue{.id = 2, .value = 2},
90 };
91 var cases = [][9]IdAndValue {
92 []IdAndValue {
93 IdAndValue{.id = 0, .value = 0},
94 IdAndValue{.id = 0, .value = 1},
95 IdAndValue{.id = 0, .value = 2},
96 IdAndValue{.id = 1, .value = 0},
97 IdAndValue{.id = 1, .value = 1},
98 IdAndValue{.id = 1, .value = 2},
99 IdAndValue{.id = 2, .value = 0},
100 IdAndValue{.id = 2, .value = 1},
101 IdAndValue{.id = 2, .value = 2},
102 },
103 []IdAndValue {
104 IdAndValue{.id = 0, .value = 2},
105 IdAndValue{.id = 0, .value = 1},
106 IdAndValue{.id = 0, .value = 0},
107 IdAndValue{.id = 1, .value = 2},
108 IdAndValue{.id = 1, .value = 1},
109 IdAndValue{.id = 1, .value = 0},
110 IdAndValue{.id = 2, .value = 2},
111 IdAndValue{.id = 2, .value = 1},
112 IdAndValue{.id = 2, .value = 0},
113 },
114 };
115 for (cases) |*case| {
116 sort_stable(IdAndValue, (*case)[0..], cmpByValue);
117 for (*case) |item, i| {
118 assert(item.id == expected[i].id);
119 assert(item.value == expected[i].value);
120 }
121 }
122}
123const IdAndValue = struct {
124 id: i32,
125 value: i32,
126};
127fn cmpByValue(a: &const IdAndValue, b: &const IdAndValue) -> Cmp {
128 return i32asc(a.value, b.value);
129}
130
61131test "testSort" {
62132 const u8cases = [][]const []const u8 {
63133 [][]const u8{"", ""},
std/special/compiler_rt/udivmod.zig+1-1
......@@ -1,7 +1,7 @@
11const builtin = @import("builtin");
22const is_test = builtin.is_test;
33
4const low = if (builtin.is_big_endian) 1 else 0;
4const low = switch (builtin.endian) { builtin.Endian.Big => 1, builtin.Endian.Little => 0 };
55const high = 1 - low;
66
77pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: ?&DoubleInt) -> DoubleInt {
test/cases/bugs/394.zig+2-2
......@@ -1,9 +1,9 @@
1const E = enum { A: [9]u8, B: u64, };
1const E = union(enum) { A: [9]u8, B: u64, };
22const S = struct { x: u8, y: E, };
33
44const assert = @import("std").debug.assert;
55
66test "bug 394 fixed" {
7 const x = S { .x = 3, .y = E.B {1} };
7 const x = S { .x = 3, .y = E {.B = 1 } };
88 assert(x.x == 3);
99}
test/cases/enum.zig+171-17
......@@ -2,8 +2,8 @@ const assert = @import("std").debug.assert;
22const mem = @import("std").mem;
33
44test "enum type" {
5 const foo1 = Foo.One {13};
6 const foo2 = Foo.Two { Point { .x = 1234, .y = 5678, }};
5 const foo1 = Foo{ .One = 13};
6 const foo2 = Foo{. Two = Point { .x = 1234, .y = 5678, }};
77 const bar = Bar.B;
88
99 assert(bar == Bar.B);
......@@ -24,12 +24,12 @@ const Point = struct {
2424 x: u64,
2525 y: u64,
2626};
27const Foo = enum {
27const Foo = union(enum) {
2828 One: i32,
2929 Two: Point,
3030 Three: void,
3131};
32const FooNoVoid = enum {
32const FooNoVoid = union(enum) {
3333 One: i32,
3434 Two: Point,
3535};
......@@ -41,13 +41,13 @@ const Bar = enum {
4141};
4242
4343fn returnAnInt(x: i32) -> Foo {
44 Foo.One { x }
44 Foo { .One = x }
4545}
4646
4747
4848test "constant enum with payload" {
49 var empty = AnEnumWithPayload.Empty;
50 var full = AnEnumWithPayload.Full {13};
49 var empty = AnEnumWithPayload {.Empty = {}};
50 var full = AnEnumWithPayload {.Full = 13};
5151 shouldBeEmpty(empty);
5252 shouldBeNotEmpty(full);
5353}
......@@ -66,8 +66,8 @@ fn shouldBeNotEmpty(x: &const AnEnumWithPayload) {
6666 }
6767}
6868
69const AnEnumWithPayload = enum {
70 Empty,
69const AnEnumWithPayload = union(enum) {
70 Empty: void,
7171 Full: i32,
7272};
7373
......@@ -89,8 +89,8 @@ test "enum to int" {
8989 shouldEqual(Number.Four, 4);
9090}
9191
92fn shouldEqual(n: Number, expected: usize) {
93 assert(usize(n) == expected);
92fn shouldEqual(n: Number, expected: u3) {
93 assert(u3(n) == expected);
9494}
9595
9696
......@@ -98,7 +98,7 @@ test "int to enum" {
9898 testIntToEnumEval(3);
9999}
100100fn testIntToEnumEval(x: i32) {
101 assert(IntToEnumNumber(x) == IntToEnumNumber.Three);
101 assert(IntToEnumNumber(u3(x)) == IntToEnumNumber.Three);
102102}
103103const IntToEnumNumber = enum {
104104 Zero,
......@@ -109,13 +109,13 @@ const IntToEnumNumber = enum {
109109};
110110
111111
112test "@enumTagName" {
112test "@tagName" {
113113 assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
114114 comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
115115}
116116
117117fn testEnumTagNameBare(n: BareNumber) -> []const u8 {
118 return @enumTagName(n);
118 return @tagName(n);
119119}
120120
121121const BareNumber = enum {
......@@ -132,12 +132,11 @@ test "enum alignment" {
132132 }
133133}
134134
135const AlignTestEnum = enum {
135const AlignTestEnum = union(enum) {
136136 A: [9]u8,
137137 B: u64,
138138};
139139
140const ValueCount0 = enum {};
141140const ValueCount1 = enum { I0 };
142141const ValueCount2 = enum { I0, I1 };
143142const ValueCount256 = enum {
......@@ -183,10 +182,165 @@ const ValueCount257 = enum {
183182
184183test "enum sizes" {
185184 comptime {
186 assert(@sizeOf(ValueCount0) == 0);
187185 assert(@sizeOf(ValueCount1) == 0);
188186 assert(@sizeOf(ValueCount2) == 1);
189187 assert(@sizeOf(ValueCount256) == 1);
190188 assert(@sizeOf(ValueCount257) == 2);
191189 }
192190}
191
192const Small2 = enum (u2) {
193 One,
194 Two,
195};
196const Small = enum (u2) {
197 One,
198 Two,
199 Three,
200 Four,
201};
202
203test "set enum tag type" {
204 {
205 var x = Small.One;
206 x = Small.Two;
207 comptime assert(@TagType(Small) == u2);
208 }
209 {
210 var x = Small2.One;
211 x = Small2.Two;
212 comptime assert(@TagType(Small2) == u2);
213 }
214}
215
216
217const A = enum (u3) {
218 One,
219 Two,
220 Three,
221 Four,
222 One2,
223 Two2,
224 Three2,
225 Four2,
226};
227
228const B = enum (u3) {
229 One3,
230 Two3,
231 Three3,
232 Four3,
233 One23,
234 Two23,
235 Three23,
236 Four23,
237};
238
239const C = enum (u2) {
240 One4,
241 Two4,
242 Three4,
243 Four4,
244};
245
246const BitFieldOfEnums = packed struct {
247 a: A,
248 b: B,
249 c: C,
250};
251
252const bit_field_1 = BitFieldOfEnums {
253 .a = A.Two,
254 .b = B.Three3,
255 .c = C.Four4,
256};
257
258test "bit field access with enum fields" {
259 var data = bit_field_1;
260 assert(getA(&data) == A.Two);
261 assert(getB(&data) == B.Three3);
262 assert(getC(&data) == C.Four4);
263 comptime assert(@sizeOf(BitFieldOfEnums) == 1);
264
265 data.b = B.Four3;
266 assert(data.b == B.Four3);
267
268 data.a = A.Three;
269 assert(data.a == A.Three);
270 assert(data.b == B.Four3);
271}
272
273fn getA(data: &const BitFieldOfEnums) -> A {
274 return data.a;
275}
276
277fn getB(data: &const BitFieldOfEnums) -> B {
278 return data.b;
279}
280
281fn getC(data: &const BitFieldOfEnums) -> C {
282 return data.c;
283}
284
285test "casting enum to its tag type" {
286 testCastEnumToTagType(Small2.Two);
287 comptime testCastEnumToTagType(Small2.Two);
288}
289
290fn testCastEnumToTagType(value: Small2) {
291 assert(u2(value) == 1);
292}
293
294const MultipleChoice = enum(u32) {
295 A = 20,
296 B = 40,
297 C = 60,
298 D = 1000,
299};
300
301test "enum with specified tag values" {
302 testEnumWithSpecifiedTagValues(MultipleChoice.C);
303 comptime testEnumWithSpecifiedTagValues(MultipleChoice.C);
304}
305
306fn testEnumWithSpecifiedTagValues(x: MultipleChoice) {
307 assert(u32(x) == 60);
308 assert(1234 == switch (x) {
309 MultipleChoice.A => 1,
310 MultipleChoice.B => 2,
311 MultipleChoice.C => u32(1234),
312 MultipleChoice.D => 4,
313 });
314}
315
316const MultipleChoice2 = enum(u32) {
317 Unspecified1,
318 A = 20,
319 Unspecified2,
320 B = 40,
321 Unspecified3,
322 C = 60,
323 Unspecified4,
324 D = 1000,
325 Unspecified5,
326};
327
328test "enum with specified and unspecified tag values" {
329 testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D);
330 comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D);
331}
332
333fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) {
334 assert(u32(x) == 1000);
335 assert(1234 == switch (x) {
336 MultipleChoice2.A => 1,
337 MultipleChoice2.B => 2,
338 MultipleChoice2.C => 3,
339 MultipleChoice2.D => u32(1234),
340 MultipleChoice2.Unspecified1 => 5,
341 MultipleChoice2.Unspecified2 => 6,
342 MultipleChoice2.Unspecified3 => 7,
343 MultipleChoice2.Unspecified4 => 8,
344 MultipleChoice2.Unspecified5 => 9,
345 });
346}
test/cases/enum_with_members.zig+3-3
......@@ -2,7 +2,7 @@ const assert = @import("std").debug.assert;
22const mem = @import("std").mem;
33const fmt = @import("std").fmt;
44
5const ET = enum {
5const ET = union(enum) {
66 SINT: i32,
77 UINT: u32,
88
......@@ -15,8 +15,8 @@ const ET = enum {
1515};
1616
1717test "enum with members" {
18 const a = ET.SINT { -42 };
19 const b = ET.UINT { 42 };
18 const a = ET { .SINT = -42 };
19 const b = ET { .UINT = 42 };
2020 var buf: [20]u8 = undefined;
2121
2222 assert(%%a.print(buf[0..]) == 3);
test/cases/misc.zig+9-7
......@@ -324,8 +324,8 @@ test "constant enum initialization with differing sizes" {
324324 test3_1(test3_foo);
325325 test3_2(test3_bar);
326326}
327const Test3Foo = enum {
328 One,
327const Test3Foo = union(enum) {
328 One: void,
329329 Two: f32,
330330 Three: Test3Point,
331331};
......@@ -333,8 +333,8 @@ const Test3Point = struct {
333333 x: i32,
334334 y: i32,
335335};
336const test3_foo = Test3Foo.Three{Test3Point {.x = 3, .y = 4}};
337const test3_bar = Test3Foo.Two{13};
336const test3_foo = Test3Foo { .Three = Test3Point {.x = 3, .y = 4}};
337const test3_bar = Test3Foo { .Two = 13};
338338fn test3_1(f: &const Test3Foo) {
339339 switch (*f) {
340340 Test3Foo.Three => |pt| {
......@@ -449,7 +449,8 @@ fn testArray2DConstDoublePtr(ptr: &const f32) {
449449const Tid = builtin.TypeId;
450450const AStruct = struct { x: i32, };
451451const AnEnum = enum { One, Two, };
452const AnEnumWithPayload = enum { One: i32, Two, };
452const AUnionEnum = union(enum) { One: i32, Two: void, };
453const AUnion = union { One: void, Two: void };
453454
454455test "@typeId" {
455456 comptime {
......@@ -474,8 +475,9 @@ test "@typeId" {
474475 assert(@typeId(%i32) == Tid.ErrorUnion);
475476 assert(@typeId(error) == Tid.Error);
476477 assert(@typeId(AnEnum) == Tid.Enum);
477 assert(@typeId(@typeOf(AnEnumWithPayload.One)) == Tid.EnumTag);
478 // TODO union
478 assert(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);
479 assert(@typeId(AUnionEnum) == Tid.Union);
480 assert(@typeId(AUnion) == Tid.Union);
479481 assert(@typeId(fn()) == Tid.Fn);
480482 assert(@typeId(@typeOf(builtin)) == Tid.Namespace);
481483 assert(@typeId(@typeOf({this})) == Tid.Block);
test/cases/reflection.zig+2-2
......@@ -62,8 +62,8 @@ const Foo = struct {
6262 three: void,
6363};
6464
65const Bar = enum {
66 One,
65const Bar = union(enum) {
66 One: void,
6767 Two: i32,
6868 Three: bool,
6969 Four: f64,
test/cases/switch.zig+19-8
......@@ -83,14 +83,14 @@ const SwitchStatmentFoo = enum {
8383
8484
8585test "switch prong with variable" {
86 switchProngWithVarFn(SwitchProngWithVarEnum.One {13});
87 switchProngWithVarFn(SwitchProngWithVarEnum.Two {13.0});
88 switchProngWithVarFn(SwitchProngWithVarEnum.Meh);
86 switchProngWithVarFn(SwitchProngWithVarEnum { .One = 13});
87 switchProngWithVarFn(SwitchProngWithVarEnum { .Two = 13.0});
88 switchProngWithVarFn(SwitchProngWithVarEnum { .Meh = {}});
8989}
90const SwitchProngWithVarEnum = enum {
90const SwitchProngWithVarEnum = union(enum) {
9191 One: i32,
9292 Two: f32,
93 Meh,
93 Meh: void,
9494};
9595fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) {
9696 switch(*a) {
......@@ -112,7 +112,7 @@ test "switch on enum using pointer capture" {
112112}
113113
114114fn testSwitchEnumPtrCapture() {
115 var value = SwitchProngWithVarEnum.One { 1234 };
115 var value = SwitchProngWithVarEnum { .One = 1234 };
116116 switch (value) {
117117 SwitchProngWithVarEnum.One => |*x| *x += 1,
118118 else => unreachable,
......@@ -136,13 +136,13 @@ fn returnsFive() -> i32 {
136136}
137137
138138
139const Number = enum {
139const Number = union(enum) {
140140 One: u64,
141141 Two: u8,
142142 Three: f32,
143143};
144144
145const number = Number.Three { 1.23 };
145const number = Number { .Three = 1.23 };
146146
147147fn returnsFalse() -> bool {
148148 switch (number) {
......@@ -224,3 +224,14 @@ fn switchWithUnreachable(x: i32) -> i32 {
224224 }
225225 return 10;
226226}
227
228fn return_a_number() -> %i32 {
229 return 1;
230}
231
232test "capture value of switch with all unreachable prongs" {
233 const x = return_a_number() %% |err| switch (err) {
234 else => unreachable,
235 };
236 assert(x == 1);
237}
test/cases/switch_prong_err_enum.zig+2-2
......@@ -9,14 +9,14 @@ fn readOnce() -> %u64 {
99
1010error InvalidDebugInfo;
1111
12const FormValue = enum {
12const FormValue = union(enum) {
1313 Address: u64,
1414 Other: bool,
1515};
1616
1717fn doThing(form_id: u64) -> %FormValue {
1818 return switch (form_id) {
19 17 => FormValue.Address { %return readOnce() },
19 17 => FormValue { .Address = %return readOnce() },
2020 else => error.InvalidDebugInfo,
2121 }
2222}
test/cases/switch_prong_implicit_cast.zig+4-4
......@@ -1,7 +1,7 @@
11const assert = @import("std").debug.assert;
22
3const FormValue = enum {
4 One,
3const FormValue = union(enum) {
4 One: void,
55 Two: bool,
66};
77
......@@ -9,8 +9,8 @@ error Whatever;
99
1010fn foo(id: u64) -> %FormValue {
1111 switch (id) {
12 2 => FormValue.Two { true },
13 1 => FormValue.One,
12 2 => FormValue { .Two = true },
13 1 => FormValue { .One = {} },
1414 else => return error.Whatever,
1515 }
1616}
test/cases/union.zig+118-3
......@@ -1,6 +1,6 @@
11const assert = @import("std").debug.assert;
22
3const Value = enum {
3const Value = union(enum) {
44 Int: u64,
55 Array: [9]u8,
66};
......@@ -10,8 +10,8 @@ const Agg = struct {
1010 val2: Value,
1111};
1212
13const v1 = Value.Int { 1234 };
14const v2 = Value.Array { []u8{3} ** 9 };
13const v1 = Value { .Int = 1234 };
14const v2 = Value { .Array = []u8{3} ** 9 };
1515
1616const err = (%Agg)(Agg {
1717 .val1 = v1,
......@@ -75,3 +75,118 @@ test "basic extern unions" {
7575 assert(foo.float == 12.34);
7676}
7777
78
79const Letter = enum {
80 A,
81 B,
82 C,
83};
84const Payload = union(Letter) {
85 A: i32,
86 B: f64,
87 C: bool,
88};
89
90test "union with specified enum tag" {
91 doTest();
92 comptime doTest();
93}
94
95fn doTest() {
96 assert(bar(Payload {.A = 1234}) == -10);
97}
98
99fn bar(value: &const Payload) -> i32 {
100 assert(Letter(*value) == Letter.A);
101 return switch (*value) {
102 Payload.A => |x| return x - 1244,
103 Payload.B => |x| if (x == 12.34) i32(20) else 21,
104 Payload.C => |x| if (x) i32(30) else 31,
105 };
106}
107
108const MultipleChoice = union(enum(u32)) {
109 A = 20,
110 B = 40,
111 C = 60,
112 D = 1000,
113};
114test "simple union(enum(u32))" {
115 var x = MultipleChoice.C;
116 assert(x == MultipleChoice.C);
117 assert(u32(@TagType(MultipleChoice)(x)) == 60);
118}
119
120const MultipleChoice2 = union(enum(u32)) {
121 Unspecified1: i32,
122 A: f32 = 20,
123 Unspecified2: void,
124 B: bool = 40,
125 Unspecified3: i32,
126 C: i8 = 60,
127 Unspecified4: void,
128 D: void = 1000,
129 Unspecified5: i32,
130};
131
132test "union(enum(u32)) with specified and unspecified tag values" {
133 comptime assert(@TagType(@TagType(MultipleChoice2)) == u32);
134 testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 {.C = 123});
135 comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 { .C = 123} );
136}
137
138fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) {
139 assert(u32(@TagType(MultipleChoice2)(*x)) == 60);
140 assert(1123 == switch (*x) {
141 MultipleChoice2.A => 1,
142 MultipleChoice2.B => 2,
143 MultipleChoice2.C => |v| i32(1000) + v,
144 MultipleChoice2.D => 4,
145 MultipleChoice2.Unspecified1 => 5,
146 MultipleChoice2.Unspecified2 => 6,
147 MultipleChoice2.Unspecified3 => 7,
148 MultipleChoice2.Unspecified4 => 8,
149 MultipleChoice2.Unspecified5 => 9,
150 });
151}
152
153
154const ExternPtrOrInt = extern union {
155 ptr: &u8,
156 int: u64
157};
158test "extern union size" {
159 comptime assert(@sizeOf(ExternPtrOrInt) == 8);
160}
161
162const PackedPtrOrInt = packed union {
163 ptr: &u8,
164 int: u64
165};
166test "extern union size" {
167 comptime assert(@sizeOf(PackedPtrOrInt) == 8);
168}
169
170const ZeroBits = union {
171 OnlyField: void,
172};
173test "union with only 1 field which is void should be zero bits" {
174 comptime assert(@sizeOf(ZeroBits) == 0);
175}
176
177const TheTag = enum {A, B, C};
178const TheUnion = union(TheTag) { A: i32, B: i32, C: i32 };
179test "union field access gives the enum values" {
180 assert(TheUnion.A == TheTag.A);
181 assert(TheUnion.B == TheTag.B);
182 assert(TheUnion.C == TheTag.C);
183}
184
185test "cast union to tag type of union" {
186 testCastUnionToTagType(TheUnion {.B = 1234});
187 comptime testCastUnionToTagType(TheUnion {.B = 1234});
188}
189
190fn testCastUnionToTagType(x: &const TheUnion) {
191 assert(TheTag(*x) == TheTag.B);
192}
test/compile_errors.zig+336-14
......@@ -930,8 +930,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
930930 \\fn bad_eql_1(a: []u8, b: []u8) -> bool {
931931 \\ a == b
932932 \\}
933 \\const EnumWithData = enum {
934 \\ One,
933 \\const EnumWithData = union(enum) {
934 \\ One: void,
935935 \\ Two: i32,
936936 \\};
937937 \\fn bad_eql_2(a: &const EnumWithData, b: &const EnumWithData) -> bool {
......@@ -1145,19 +1145,19 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
11451145 \\const JasonHM = u8;
11461146 \\const JasonList = &JsonNode;
11471147 \\
1148 \\const JsonOA = enum {
1148 \\const JsonOA = union(enum) {
11491149 \\ JSONArray: JsonList,
11501150 \\ JSONObject: JasonHM,
11511151 \\};
11521152 \\
1153 \\const JsonType = enum {
1153 \\const JsonType = union(enum) {
11541154 \\ JSONNull: void,
11551155 \\ JSONInteger: isize,
11561156 \\ JSONDouble: f64,
11571157 \\ JSONBool: bool,
11581158 \\ JSONString: []u8,
1159 \\ JSONArray,
1160 \\ JSONObject,
1159 \\ JSONArray: void,
1160 \\ JSONObject: void,
11611161 \\};
11621162 \\
11631163 \\pub const JsonNode = struct {
......@@ -2138,7 +2138,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
21382138 \\
21392139 \\const MdText = ArrayList(u8);
21402140 \\
2141 \\const MdNode = enum {
2141 \\const MdNode = union(enum) {
21422142 \\ Header: struct {
21432143 \\ text: MdText,
21442144 \\ weight: HeaderValue,
......@@ -2297,6 +2297,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
22972297 ,
22982298 ".tmp_source.zig:2:21: error: type 'i32' does not support @memberType");
22992299
2300 cases.add("@memberType on enum",
2301 \\comptime {
2302 \\ _ = @memberType(Foo, 0);
2303 \\}
2304 \\const Foo = enum {A,};
2305 ,
2306 ".tmp_source.zig:2:21: error: type 'Foo' does not support @memberType");
2307
23002308 cases.add("@memberType struct out of bounds",
23012309 \\comptime {
23022310 \\ _ = @memberType(Foo, 0);
......@@ -2305,13 +2313,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
23052313 ,
23062314 ".tmp_source.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members");
23072315
2308 cases.add("@memberType enum out of bounds",
2316 cases.add("@memberType union out of bounds",
23092317 \\comptime {
2310 \\ _ = @memberType(Foo, 0);
2318 \\ _ = @memberType(Foo, 1);
23112319 \\}
2312 \\const Foo = enum {};
2320 \\const Foo = union {A: void,};
23132321 ,
2314 ".tmp_source.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members");
2322 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");
23152323
23162324 cases.add("@memberName on unsupported type",
23172325 \\comptime {
......@@ -2330,11 +2338,19 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
23302338
23312339 cases.add("@memberName enum out of bounds",
23322340 \\comptime {
2333 \\ _ = @memberName(Foo, 0);
2341 \\ _ = @memberName(Foo, 1);
23342342 \\}
2335 \\const Foo = enum {};
2343 \\const Foo = enum {A,};
23362344 ,
2337 ".tmp_source.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members");
2345 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");
2346
2347 cases.add("@memberName union out of bounds",
2348 \\comptime {
2349 \\ _ = @memberName(Foo, 1);
2350 \\}
2351 \\const Foo = union {A:i32,};
2352 ,
2353 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");
23382354
23392355 cases.add("calling var args extern function, passing array instead of pointer",
23402356 \\export fn entry() {
......@@ -2362,4 +2378,310 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
23622378 ".tmp_source.zig:4:25: error: aoeu",
23632379 ".tmp_source.zig:1:36: note: called from here",
23642380 ".tmp_source.zig:12:20: note: referenced here");
2381
2382 cases.add("specify enum tag type that is too small",
2383 \\const Small = enum (u2) {
2384 \\ One,
2385 \\ Two,
2386 \\ Three,
2387 \\ Four,
2388 \\ Five,
2389 \\};
2390 \\
2391 \\export fn entry() {
2392 \\ var x = Small.One;
2393 \\}
2394 ,
2395 ".tmp_source.zig:1:20: error: 'u2' too small to hold all bits; must be at least 'u3'");
2396
2397 cases.add("specify non-integer enum tag type",
2398 \\const Small = enum (f32) {
2399 \\ One,
2400 \\ Two,
2401 \\ Three,
2402 \\};
2403 \\
2404 \\export fn entry() {
2405 \\ var x = Small.One;
2406 \\}
2407 ,
2408 ".tmp_source.zig:1:20: error: expected integer, found 'f32'");
2409
2410 cases.add("implicitly casting enum to tag type",
2411 \\const Small = enum(u2) {
2412 \\ One,
2413 \\ Two,
2414 \\ Three,
2415 \\ Four,
2416 \\};
2417 \\
2418 \\export fn entry() {
2419 \\ var x: u2 = Small.Two;
2420 \\}
2421 ,
2422 ".tmp_source.zig:9:22: error: expected type 'u2', found 'Small'");
2423
2424 cases.add("explicitly casting enum to non tag type",
2425 \\const Small = enum(u2) {
2426 \\ One,
2427 \\ Two,
2428 \\ Three,
2429 \\ Four,
2430 \\};
2431 \\
2432 \\export fn entry() {
2433 \\ var x = u3(Small.Two);
2434 \\}
2435 ,
2436 ".tmp_source.zig:9:15: error: enum to integer cast to 'u3' instead of its tag type, 'u2'");
2437
2438 cases.add("explicitly casting non tag type to enum",
2439 \\const Small = enum(u2) {
2440 \\ One,
2441 \\ Two,
2442 \\ Three,
2443 \\ Four,
2444 \\};
2445 \\
2446 \\export fn entry() {
2447 \\ var y = u3(3);
2448 \\ var x = Small(y);
2449 \\}
2450 ,
2451 ".tmp_source.zig:10:18: error: integer to enum cast from 'u3' instead of its tag type, 'u2'");
2452
2453 cases.add("non unsigned integer enum tag type",
2454 \\const Small = enum(i2) {
2455 \\ One,
2456 \\ Two,
2457 \\ Three,
2458 \\ Four,
2459 \\};
2460 \\
2461 \\export fn entry() {
2462 \\ var y = Small.Two;
2463 \\}
2464 ,
2465 ".tmp_source.zig:1:19: error: expected unsigned integer, found 'i2'");
2466
2467 cases.add("struct fields with value assignments",
2468 \\const MultipleChoice = struct {
2469 \\ A: i32 = 20,
2470 \\};
2471 \\export fn entry() {
2472 \\ var x: MultipleChoice = undefined;
2473 \\}
2474 ,
2475 ".tmp_source.zig:2:14: error: enums, not structs, support field assignment");
2476
2477 cases.add("union fields with value assignments",
2478 \\const MultipleChoice = union {
2479 \\ A: i32 = 20,
2480 \\};
2481 \\export fn entry() {
2482 \\ var x: MultipleChoice = undefined;
2483 \\}
2484 ,
2485 ".tmp_source.zig:2:14: error: non-enum union field assignment",
2486 ".tmp_source.zig:1:24: note: consider 'union(enum)' here");
2487
2488 cases.add("enum with 0 fields",
2489 \\const Foo = enum {};
2490 \\export fn entry() -> usize {
2491 \\ return @sizeOf(Foo);
2492 \\}
2493 ,
2494 ".tmp_source.zig:1:13: error: enums must have 1 or more fields");
2495
2496 cases.add("union with 0 fields",
2497 \\const Foo = union {};
2498 \\export fn entry() -> usize {
2499 \\ return @sizeOf(Foo);
2500 \\}
2501 ,
2502 ".tmp_source.zig:1:13: error: unions must have 1 or more fields");
2503
2504 cases.add("enum value already taken",
2505 \\const MultipleChoice = enum(u32) {
2506 \\ A = 20,
2507 \\ B = 40,
2508 \\ C = 60,
2509 \\ D = 1000,
2510 \\ E = 60,
2511 \\};
2512 \\export fn entry() {
2513 \\ var x = MultipleChoice.C;
2514 \\}
2515 ,
2516 ".tmp_source.zig:6:9: error: enum tag value 60 already taken",
2517 ".tmp_source.zig:4:9: note: other occurrence here");
2518
2519 cases.add("union with specified enum omits field",
2520 \\const Letter = enum {
2521 \\ A,
2522 \\ B,
2523 \\ C,
2524 \\};
2525 \\const Payload = union(Letter) {
2526 \\ A: i32,
2527 \\ B: f64,
2528 \\};
2529 \\export fn entry() -> usize {
2530 \\ return @sizeOf(Payload);
2531 \\}
2532 ,
2533 ".tmp_source.zig:6:17: error: enum field missing: 'C'",
2534 ".tmp_source.zig:4:5: note: declared here");
2535
2536 cases.add("@TagType when union has no attached enum",
2537 \\const Foo = union {
2538 \\ A: i32,
2539 \\};
2540 \\export fn entry() {
2541 \\ const x = @TagType(Foo);
2542 \\}
2543 ,
2544 ".tmp_source.zig:5:24: error: union 'Foo' has no tag",
2545 ".tmp_source.zig:1:13: note: consider 'union(enum)' here");
2546
2547 cases.add("non-integer tag type to automatic union enum",
2548 \\const Foo = union(enum(f32)) {
2549 \\ A: i32,
2550 \\};
2551 \\export fn entry() {
2552 \\ const x = @TagType(Foo);
2553 \\}
2554 ,
2555 ".tmp_source.zig:1:23: error: expected integer tag type, found 'f32'");
2556
2557 cases.add("non-enum tag type passed to union",
2558 \\const Foo = union(u32) {
2559 \\ A: i32,
2560 \\};
2561 \\export fn entry() {
2562 \\ const x = @TagType(Foo);
2563 \\}
2564 ,
2565 ".tmp_source.zig:1:18: error: expected enum tag type, found 'u32'");
2566
2567 cases.add("union auto-enum value already taken",
2568 \\const MultipleChoice = union(enum(u32)) {
2569 \\ A = 20,
2570 \\ B = 40,
2571 \\ C = 60,
2572 \\ D = 1000,
2573 \\ E = 60,
2574 \\};
2575 \\export fn entry() {
2576 \\ var x = MultipleChoice { .C = {} };
2577 \\}
2578 ,
2579 ".tmp_source.zig:6:9: error: enum tag value 60 already taken",
2580 ".tmp_source.zig:4:9: note: other occurrence here");
2581
2582 cases.add("union enum field does not match enum",
2583 \\const Letter = enum {
2584 \\ A,
2585 \\ B,
2586 \\ C,
2587 \\};
2588 \\const Payload = union(Letter) {
2589 \\ A: i32,
2590 \\ B: f64,
2591 \\ C: bool,
2592 \\ D: bool,
2593 \\};
2594 \\export fn entry() {
2595 \\ var a = Payload {.A = 1234};
2596 \\}
2597 ,
2598 ".tmp_source.zig:10:5: error: enum field not found: 'D'",
2599 ".tmp_source.zig:1:16: note: enum declared here");
2600
2601 cases.add("field type supplied in an enum",
2602 \\const Letter = enum {
2603 \\ A: void,
2604 \\ B,
2605 \\ C,
2606 \\};
2607 \\export fn entry() {
2608 \\ var b = Letter.B;
2609 \\}
2610 ,
2611 ".tmp_source.zig:2:8: error: structs and unions, not enums, support field types",
2612 ".tmp_source.zig:1:16: note: consider 'union(enum)' here");
2613
2614 cases.add("struct field missing type",
2615 \\const Letter = struct {
2616 \\ A,
2617 \\};
2618 \\export fn entry() {
2619 \\ var a = Letter { .A = {} };
2620 \\}
2621 ,
2622 ".tmp_source.zig:2:5: error: struct field missing type");
2623
2624 cases.add("extern union field missing type",
2625 \\const Letter = extern union {
2626 \\ A,
2627 \\};
2628 \\export fn entry() {
2629 \\ var a = Letter { .A = {} };
2630 \\}
2631 ,
2632 ".tmp_source.zig:2:5: error: union field missing type");
2633
2634 cases.add("extern union given enum tag type",
2635 \\const Letter = enum {
2636 \\ A,
2637 \\ B,
2638 \\ C,
2639 \\};
2640 \\const Payload = extern union(Letter) {
2641 \\ A: i32,
2642 \\ B: f64,
2643 \\ C: bool,
2644 \\};
2645 \\export fn entry() {
2646 \\ var a = Payload { .A = { 1234 } };
2647 \\}
2648 ,
2649 ".tmp_source.zig:6:29: error: extern union does not support enum tag type");
2650
2651 cases.add("packed union given enum tag type",
2652 \\const Letter = enum {
2653 \\ A,
2654 \\ B,
2655 \\ C,
2656 \\};
2657 \\const Payload = packed union(Letter) {
2658 \\ A: i32,
2659 \\ B: f64,
2660 \\ C: bool,
2661 \\};
2662 \\export fn entry() {
2663 \\ var a = Payload { .A = { 1234 } };
2664 \\}
2665 ,
2666 ".tmp_source.zig:6:29: error: packed union does not support enum tag type");
2667
2668 cases.add("switch on union with no attached enum",
2669 \\const Payload = union {
2670 \\ A: i32,
2671 \\ B: f64,
2672 \\ C: bool,
2673 \\};
2674 \\export fn entry() {
2675 \\ const a = Payload { .A = { 1234 } };
2676 \\ foo(a);
2677 \\}
2678 \\fn foo(a: &const Payload) {
2679 \\ switch (*a) {
2680 \\ Payload.A => {},
2681 \\ else => unreachable,
2682 \\ }
2683 \\}
2684 ,
2685 ".tmp_source.zig:11:13: error: switch on union which has no attached enum",
2686 ".tmp_source.zig:1:17: note: consider 'union(enum)' here");
23652687}
test/tests.zig+5-5
......@@ -150,8 +150,8 @@ pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []cons
150150 continue;
151151 }
152152 const these_tests = b.addTest(root_src);
153 these_tests.setNamePrefix(b.fmt("{}-{}-{}-{}-{} ", name, @enumTagName(test_target.os),
154 @enumTagName(test_target.arch), @enumTagName(mode), if (link_libc) "c" else "bare"));
153 these_tests.setNamePrefix(b.fmt("{}-{}-{}-{}-{} ", name, @tagName(test_target.os),
154 @tagName(test_target.arch), @tagName(mode), if (link_libc) "c" else "bare"));
155155 these_tests.setFilter(test_filter);
156156 these_tests.setBuildMode(mode);
157157 if (!is_native) {
......@@ -428,7 +428,7 @@ pub const CompareOutputContext = struct {
428428 Special.None => {
429429 for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast}) |mode| {
430430 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "{} {} ({})",
431 "compare-output", case.name, @enumTagName(mode));
431 "compare-output", case.name, @tagName(mode));
432432 if (self.test_filter) |filter| {
433433 if (mem.indexOf(u8, annotated_case_name, filter) == null)
434434 continue;
......@@ -682,7 +682,7 @@ pub const CompileErrorContext = struct {
682682
683683 for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast}) |mode| {
684684 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "compile-error {} ({})",
685 case.name, @enumTagName(mode));
685 case.name, @tagName(mode));
686686 if (self.test_filter) |filter| {
687687 if (mem.indexOf(u8, annotated_case_name, filter) == null)
688688 continue;
......@@ -750,7 +750,7 @@ pub const BuildExamplesContext = struct {
750750
751751 for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast}) |mode| {
752752 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "build {} ({})",
753 root_src, @enumTagName(mode));
753 root_src, @tagName(mode));
754754 if (self.test_filter) |filter| {
755755 if (mem.indexOf(u8, annotated_case_name, filter) == null)
756756 continue;
test/translate_c.zig+10
......@@ -1178,4 +1178,14 @@ pub fn addCases(cases: &tests.TranslateCContext) {
11781178 ,
11791179 \\pub var v0: ?&const u8 = c"0.0.0";
11801180 );
1181
1182 cases.add("static incomplete array inside function",
1183 \\void foo(void) {
1184 \\ static const char v2[] = "2.2.2";
1185 \\}
1186 ,
1187 \\pub fn foo() {
1188 \\ const v2: &const u8 = c"2.2.2";
1189 \\}
1190 );
11811191}