diff options
| -rw-r--r-- | c/c.c | 19 | ||||
| -rw-r--r-- | c/eval.c | 2 | ||||
| -rw-r--r-- | io.c | 3 | ||||
| -rw-r--r-- | targ.c | 6 | ||||
| -rw-r--r-- | type.h | 9 |
5 files changed, 31 insertions, 8 deletions
@@ -137,7 +137,7 @@ isdecltok(struct comp *cm) kw(_Thread_local), kw(thread_local), kw(_Static_assert), kw(inline), kw(_Noreturn), kw(const), kw(volatile), kw(restrict), kw(_Atomic), - kw(void), kw(float), kw(double), + kw(void), kw(float), kw(double), kw(_Complex), kw(signed), kw(unsigned), kw(short), kw(long), kw(int), kw(char), kw(_Bool), kw(bool), kw(struct), kw(union), kw(enum), @@ -2254,6 +2254,7 @@ declspec(struct declstate *st, struct comp *cm, struct span *pspan) KINT = 1<<7, KFLOAT = 1<<8, KDOUBLE = 1<<9, + KCOMPLEX = 1<<10, } arith = 0; struct span span = {0}; union type ty = st->base; @@ -2345,6 +2346,10 @@ declspec(struct declstate *st, struct comp *cm, struct span *pspan) if (arith & KDOUBLE) goto DupArith; arith |= KDOUBLE; break; + case TKW_Complex: + if (arith & KCOMPLEX) goto DupArith; + arith |= KCOMPLEX; + break; case TKWenum: case TKWstruct: case TKWunion: @@ -2372,7 +2377,7 @@ declspec(struct declstate *st, struct comp *cm, struct span *pspan) /* fallthru */ default: goto End; - case TKW_BitInt: case TKW_Complex: + case TKW_BitInt: case TKW_Decimal128: case TKW_Decimal32: case TKW_Decimal64: case TKW_Imaginary: error(&tk.span, "%'tk is unsupported", &tk); @@ -2405,9 +2410,9 @@ End: t = TYFLOAT; else if (arith == KDOUBLE) t = TYDOUBLE; - else if (arith == (KLONG | KDOUBLE)) { + else if (arith == (KLONG | KDOUBLE)) t = TYLDOUBLE; - } else if (arith == KBOOL) + else if (arith == KBOOL) t = TYBOOL; else if (arith == KCHAR) t = TYCHAR; @@ -2431,6 +2436,12 @@ End: t = TYVLONG; else if ((arith & ~KINT) == (KUNSIGNED | KLONGLONG)) t = TYUVLONG; + else if (arith == (KCOMPLEX | KFLOAT)) + t = TYCOMPLEXF; + else if (arith == (KCOMPLEX | KDOUBLE)) + t = TYCOMPLEX; + else if (arith == (KCOMPLEX | KLONG | KDOUBLE)) + t = TYCOMPLEXL; else goto Bad; st->base = mktype(t ? t : TYINT); @@ -20,7 +20,7 @@ targ2hosttype(enum typetag t) #undef U #undef S } else if (t == TYLDOUBLE) return TYDOUBLE; - else if (isfltt(t)) return t; + else if (isfltt(t) || iscomplext(t)) return t; return 0; } @@ -210,6 +210,9 @@ pritypebefore(struct wbuf *buf, union type ty, int qual) case TYFLOAT: s = "float"; goto Prim; case TYDOUBLE: s = "double"; goto Prim; case TYLDOUBLE:s = "long double"; goto Prim; + case TYCOMPLEXF:s = "float complex"; goto Prim; + case TYCOMPLEX: s = "double complex"; goto Prim; + case TYCOMPLEXL:s = "long double complex"; goto Prim; case TYPTR: chld = typechild(ty); n = pritypebefore(buf, chld, ty.flag & TFCHLDQUAL); @@ -103,6 +103,12 @@ targ_init(const char *starg) align[TYDOUBLE] = t->doublealign; align[TYLDOUBLE] = t->doublealign; align[TYPTR] = t->ptralign; + sizes[TYCOMPLEXF] = sizes[TYFLOAT]*2; + sizes[TYCOMPLEX] = sizes[TYDOUBLE]*2; + sizes[TYCOMPLEXL] = sizes[TYLDOUBLE]*2; + align[TYCOMPLEXF] = align[TYFLOAT]; + align[TYCOMPLEX] = align[TYDOUBLE]; + align[TYCOMPLEXL] = align[TYLDOUBLE]; targ_valistsize = t->valistsize; targ_sizetype = t->sizetype; targ_ptrdifftype = t->ptrdifftype; @@ -11,14 +11,14 @@ enum typetag { /* ordering is important here! */ TYXXX, TYENUM, TYBOOL, TYCHAR, TYSCHAR, TYUCHAR, TYSHORT, TYUSHORT, TYINT, TYUINT, TYLONG, TYULONG, TYVLONG, TYUVLONG, - TYFLOAT, TYDOUBLE, TYLDOUBLE, + TYFLOAT, TYDOUBLE, TYLDOUBLE, TYCOMPLEXF, TYCOMPLEX, TYCOMPLEXL, TYVOID, TYPTR, TYARRAY, TYFUNC, TYSTRUCT, TYUNION, NTYPETAG, TYSIGNEDSET_ = 1<<TYSCHAR | 1<<TYSHORT | 1<<TYINT | 1<<TYLONG | 1<<TYVLONG, TYUNSIGNEDSET_ = 1<<TYUCHAR | 1<<TYUSHORT | 1<<TYUINT | 1<<TYULONG | 1<<TYUVLONG, - TYSCALARSET_ = ((1u << (TYLDOUBLE - TYENUM + 1)) - 1) << TYENUM | 1<<TYPTR + TYSCALARSET_ = ((1u << (TYCOMPLEXL - TYENUM + 1)) - 1) << TYENUM | 1<<TYPTR }; enum typeflagmask { @@ -51,7 +51,7 @@ static_assert(sizeof(union type) == 4); #define issignedt(t) ((TYSIGNEDSET_ | targ_charsigned << TYCHAR) >> (t) & 1) #define isunsignedt(t) ((TYUNSIGNEDSET_ | !targ_charsigned << TYCHAR) >> (t) & 1) #define isfltt(t) in_range((t), TYFLOAT, TYLDOUBLE) -#define isaritht(t) in_range((t), TYENUM, TYLDOUBLE) +#define isaritht(t) in_range((t), TYENUM, TYCOMPLEXL) #define isscalart(t) (TYSCALARSET_ >> (t) & 1) #define isptrcvtt(t) in_range((t), TYPTR, TYFUNC) #define isaggt(t) in_range((t), TYSTRUCT, TYUNION) @@ -64,6 +64,8 @@ static_assert(sizeof(union type) == 4); #define isscalar(ty) isscalart((ty).t) #define isptrcvt(ty) isptrcvtt((ty).t) #define isagg(ty) isaggt((ty).t) +#define iscomplext(t) in_range((t), TYCOMPLEXF, TYCOMPLEXL) +#define iscomplex(ty) iscomplext((ty).t) #define mktype(...) ((union type) {{ __VA_ARGS__ }}) struct enumvar { @@ -151,6 +153,7 @@ scalartypet(union type t) { if (t.t == TYENUM) return t.backing ? t.backing : typedata[t.dat].backing; if (isptrcvt(t)) return TYPTR; + assert(!iscomplex(t)); return t.t; } static inline uint |