aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--c/c.c19
-rw-r--r--c/eval.c2
-rw-r--r--io.c3
-rw-r--r--targ.c6
-rw-r--r--type.h9
5 files changed, 31 insertions, 8 deletions
diff --git a/c/c.c b/c/c.c
index a723a65..aa291e1 100644
--- a/c/c.c
+++ b/c/c.c
@@ -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);
diff --git a/c/eval.c b/c/eval.c
index d227c91..c004813 100644
--- a/c/eval.c
+++ b/c/eval.c
@@ -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;
}
diff --git a/io.c b/io.c
index d98eacd..0211320 100644
--- a/io.c
+++ b/io.c
@@ -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);
diff --git a/targ.c b/targ.c
index 510b6e5..fdc11f8 100644
--- a/targ.c
+++ b/targ.c
@@ -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;
diff --git a/type.h b/type.h
index 6647e70..ad8e1b1 100644
--- a/type.h
+++ b/type.h
@@ -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