-/* $OpenBSD: complex.h,v 1.2 2008/12/04 03:52:31 ray Exp $ */
+/* $OpenBSD: complex.h,v 1.3 2010/07/24 22:17:03 guenther Exp $ */
/*
* Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org>
*
#define _Complex __complex__
#endif
#define _Complex_I 1.0fi
+#elif defined(lint)
+#define _Complex_I 1.0fi
#endif
#define complex _Complex
-/* $OpenBSD: stdbool.h,v 1.4 2007/10/02 14:06:16 otto Exp $ */
+/* $OpenBSD: stdbool.h,v 1.5 2010/07/24 22:17:03 guenther Exp $ */
/*
* Written by Marc Espie, September 25, 1999
#ifndef __cplusplus
-#if (defined(__GNUC__) && __GNUC__ >= 3) || defined(__PCC__)
+#if (defined(__GNUC__) && __GNUC__ >= 3) || defined(__PCC__) || defined(lint)
/* Support for _C99: type _Bool is already built-in. */
#define false 0
#define true 1
-/* $OpenBSD: decl.c,v 1.24 2007/11/27 16:22:14 martynas Exp $ */
+/* $OpenBSD: decl.c,v 1.25 2010/07/24 22:17:03 guenther Exp $ */
/* $NetBSD: decl.c,v 1.11 1995/10/02 17:34:16 jpo Exp $ */
/*
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: decl.c,v 1.24 2007/11/27 16:22:14 martynas Exp $";
+static char rcsid[] = "$OpenBSD: decl.c,v 1.25 2010/07/24 22:17:03 guenther Exp $";
#endif
#include <sys/param.h>
{ UNSIGN, { 0, 0, 0,
SIGNED, UNSIGN,
0, 0, 0, 0, 0, "unsigned" } },
+ { BOOL, { sizeof (_Bool) * CHAR_BIT, CHAR_BIT, 1,
+ BOOL, BOOL,
+ 1, 1, 0, 1, 1, "_Bool" } },
{ CHAR, { CHAR_BIT, CHAR_BIT, 20,
SCHAR, UCHAR,
1, 0, 0, 1, 1, "char" } },
{ LDOUBLE, { sizeof (ldbl_t) * CHAR_BIT, 10 * CHAR_BIT, -1,
LDOUBLE, LDOUBLE,
0, 0, 1, 1, 1, "long double" } },
+ { COMPLEX, { sizeof (float _Complex) * CHAR_BIT,
+ 8 * CHAR_BIT, -1,
+ COMPLEX, COMPLEX,
+ 0, 0, 1, 1, 3, "float _Complex" } },
+ { DCOMPLEX, { sizeof (double _Complex) * CHAR_BIT,
+ 16 * CHAR_BIT, -1,
+ DCOMPLEX, DCOMPLEX,
+ 0, 0, 1, 1, 3, "double _Complex" } },
+ { LDCOMPLEX,{ sizeof (long double _Complex) * CHAR_BIT,
+ 20 * CHAR_BIT, -1,
+ LDCOMPLEX, LDCOMPLEX,
+ 0, 0, 1, 1, 3, "long double _Complex" } },
+#if 0
+ { IMAGINARY,{ sizeof (float _Imaginary) * CHAR_BIT,
+ 4 * CHAR_BIT, -1,
+ IMAGINARY, IMAGINARY,
+ 0, 0, 1, 1, 2, "float _Imaginary" } },
+ { DIMAGINARY,{ sizeof (double _Imaginary) * CHAR_BIT,
+ 8 * CHAR_BIT, -1,
+ DIMAGINARY, DIMAGINARY,
+ 0, 0, 1, 1, 2, "double _Imaginary" } },
+ { LDIMAGINARY,{ sizeof (long double _Imaginary) * CHAR_BIT,
+ 10 * CHAR_BIT, -1,
+ LDIMAGINARY, LDIMAGINARY,
+ 0, 0, 1, 1, 2, "long double _Imaginary" } },
+#endif
{ VOID, { -1, -1, -1,
VOID, VOID,
0, 0, 0, 0, 0, "void" } },
typetab = xcalloc(NTSPEC, sizeof (type_t));
for (i = 0; i < NTSPEC; i++)
typetab[i].t_tspec = NOTSPEC;
+ typetab[BOOL].t_tspec = BOOL;
typetab[CHAR].t_tspec = CHAR;
typetab[SCHAR].t_tspec = SCHAR;
typetab[UCHAR].t_tspec = UCHAR;
typetab[FLOAT].t_tspec = FLOAT;
typetab[DOUBLE].t_tspec = DOUBLE;
typetab[LDOUBLE].t_tspec = LDOUBLE;
+ typetab[COMPLEX].t_tspec = COMPLEX;
+ typetab[DCOMPLEX].t_tspec = DCOMPLEX;
+ typetab[LDCOMPLEX].t_tspec = LDCOMPLEX;
+ typetab[IMAGINARY].t_tspec = IMAGINARY;
+ typetab[DIMAGINARY].t_tspec = DIMAGINARY;
+ typetab[LDIMAGINARY].t_tspec = LDIMAGINARY;
typetab[VOID].t_tspec = VOID;
/*
* Next two are not real types. They are only used by the parser
}
/*
- * Returns a shared type structure vor arithmetic types and void.
+ * Returns a shared type structure for arithmetic types and void.
*
* It's important to duplicate this structure (using duptyp() or tduptyp())
* if it is to be modified (adding qualifiers or anything else).
if (tp->t_typedef) {
if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
- dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC) {
+ dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC ||
+ dcs->d_dmod != NOTSPEC) {
/*
* something like "typedef int a; int a b;"
* This should not happen with current grammar.
* struct/union/enum with anything else is not allowed
*/
if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC ||
- dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC) {
+ dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC ||
+ dcs->d_dmod != NOTSPEC) {
/*
* remember that an error must be reported in
* deftyp().
*/
dcs->d_terr = 1;
- dcs->d_atyp = dcs->d_lmod = dcs->d_smod = NOTSPEC;
+ dcs->d_atyp = dcs->d_smod = dcs->d_lmod =
+ dcs->d_dmod = NOTSPEC;
}
dcs->d_type = tp;
return;
/* more than one, print error in deftyp() */
dcs->d_terr = 1;
dcs->d_lmod = t;
+ } else if (t == COMPLEX || t == IMAGINARY) {
+ /*
+ * remember specifiers "_Complex" and "_Imaginary" in
+ * dcs->d_dmod
+ */
+ if (dcs->d_dmod != NOTSPEC)
+ /* more than one, print error in deftyp() */
+ dcs->d_terr = 1;
+ dcs->d_dmod = t;
} else {
/*
* remember specifiers "void", "char", "int", "float" or
break;
case LONG:
if (t2 == INT || t2 == UINT || t2 == LONG || t2 == ULONG ||
- t2 == FLOAT || t2 == DOUBLE) {
+ t2 == FLOAT || t2 == DOUBLE || t2 == COMPLEX ||
+ t2 == IMAGINARY) {
/* modifying typedef with ... */
warning(5, "long");
if (t2 == INT) {
td = gettyp(DOUBLE);
} else if (t2 == DOUBLE) {
td = gettyp(LDOUBLE);
+ } else if (t2 == COMPLEX) {
+ td = gettyp(DCOMPLEX);
+ } else if (t2 == DCOMPLEX) {
+ td = gettyp(LDCOMPLEX);
+ } else if (t2 == IMAGINARY) {
+ td = gettyp(DIMAGINARY);
+ } else if (t2 == DIMAGINARY) {
+ td = gettyp(LDIMAGINARY);
}
td = duptyp(td);
td->t_typedef = 1;
void
clrtyp(void)
{
- dcs->d_atyp = dcs->d_smod = dcs->d_lmod = NOTSPEC;
+ dcs->d_atyp = dcs->d_smod = dcs->d_lmod = dcs->d_dmod = NOTSPEC;
dcs->d_scl = NOSCL;
dcs->d_type = NULL;
dcs->d_const = dcs->d_volatile = 0;
dcs->d_notyp = 0;
}
+/*
+ * Merge the domain (_Complex or _Imaginary) into a type. Returns non-zero
+ * if the merge doesn't make sense. e.g., no "int _Complex".
+ */
+int
+mergedomain(tspec_t *tp, tspec_t domain)
+{
+ if (domain == NOTSPEC)
+ return (0);
+ if (domain != COMPLEX && domain != IMAGINARY)
+ lerror("mergedomain()");
+ switch (*tp) {
+ case FLOAT:
+ *tp = domain;
+ break;
+ case DOUBLE:
+ *tp = domain == COMPLEX ? DCOMPLEX : DIMAGINARY;
+ break;
+ case LDOUBLE:
+ *tp = domain == COMPLEX ? LDCOMPLEX : LDIMAGINARY;
+ break;
+ default:
+ return (1);
+ }
+ return (0);
+}
+
/*
* Create a type structure from the informations gathered in
* the declaration stack.
void
deftyp(void)
{
- tspec_t t, s, l;
+ tspec_t t, s, l, d;
type_t *tp;
scl_t scl;
- t = dcs->d_atyp; /* CHAR, INT, FLOAT, DOUBLE, VOID */
+ t = dcs->d_atyp; /* BOOL, CHAR, INT, FLOAT,
+ DOUBLE, VOID */
s = dcs->d_smod; /* SIGNED, UNSIGNED */
l = dcs->d_lmod; /* SHORT, LONG, QUAD */
+ d = dcs->d_dmod; /* COMPLEX, IMAGINARY */
tp = dcs->d_type;
scl = dcs->d_scl;
case NOTSPEC:
t = INT;
/* FALLTHROUGH */
+ case BOOL:
+ break;
case INT:
if (s == NOTSPEC)
s = SIGNED;
default:
lerror("deftyp() 2");
}
+ if (mergedomain(&t, d))
+ dcs->d_terr = 1;
if (t != INT && t != CHAR && (s != NOTSPEC || l != NOTSPEC)) {
dcs->d_terr = 1;
l = s = NOTSPEC;
warning(34);
}
} else if (t != INT && t != UINT && t != LONG &&
- t != ULONG && t != QUAD && t != UQUAD) {
+ t != ULONG && t != QUAD && t != UQUAD && t != BOOL) {
/* illegal bit-field type */
error(35);
sz = tp->t_flen;
if (promot) {
if (t == FLOAT) {
t = DOUBLE;
+ } else if (t == BOOL) {
+ t = INT;
} else if (t == CHAR || t == SCHAR) {
t = INT;
} else if (t == UCHAR) {
} else if (t == USHORT) {
/* CONSTCOND */
t = INT_MAX < USHRT_MAX ? UINT : INT;
+ } else if (t == COMPLEX) {
+ t = DCOMPLEX;
+ } else if (t == IMAGINARY) {
+ t = DIMAGINARY;
}
}
*warn = 1;
}
for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt) {
- if ((t = arg->s_type->t_tspec) == FLOAT ||
+ if ((t = arg->s_type->t_tspec) == FLOAT || t == BOOL ||
t == CHAR || t == SCHAR || t == UCHAR ||
- t == SHORT || t == USHORT) {
+ t == SHORT || t == USHORT || t == COMPLEX ||
+ t == DCOMPLEX || t == LDCOMPLEX || t == IMAGINARY ||
+ t == DIMAGINARY || t == LDIMAGINARY) {
if (warn != NULL)
*warn = 1;
}
-/* $OpenBSD: emit1.c,v 1.7 2007/03/21 03:31:19 tedu Exp $ */
+/* $OpenBSD: emit1.c,v 1.8 2010/07/24 22:17:03 guenther Exp $ */
/* $NetBSD: emit1.c,v 1.4 1995/10/02 17:21:28 jpo Exp $ */
/*
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: emit1.c,v 1.7 2007/03/21 03:31:19 tedu Exp $";
+static char rcsid[] = "$OpenBSD: emit1.c,v 1.8 2010/07/24 22:17:03 guenther Exp $";
#endif
#include <ctype.h>
* The type is written as a sequence of substrings, each of which describes a
* node of type type_t
* a node is coded as follows:
+ * _Bool B
* char C
* signed char s C
* unsigned char u C
* float s D
* double D
* long double l D
+ * float _Complex s X
+ * double _Complex X
+ * long double _Complex l X
+ * float _Imaginary s J
+ * double _Imaginary J
+ * long double _Imaginary l J
* void V
* * P
* [n] A n
if ((ts = tp->t_tspec) == INT && tp->t_isenum)
ts = ENUM;
switch (ts) {
+ case BOOL: t = 'B'; s = '\0'; break;
case CHAR: t = 'C'; s = '\0'; break;
case SCHAR: t = 'C'; s = 's'; break;
case UCHAR: t = 'C'; s = 'u'; break;
case FLOAT: t = 'D'; s = 's'; break;
case DOUBLE: t = 'D'; s = '\0'; break;
case LDOUBLE: t = 'D'; s = 'l'; break;
+ case COMPLEX: t = 'X'; s = 's'; break;
+ case DCOMPLEX: t = 'X'; s = '\0'; break;
+ case LDCOMPLEX: t = 'X'; s = 'l'; break;
+ case IMAGINARY: t = 'J'; s = 's'; break;
+ case DIMAGINARY: t = 'J'; s = '\0'; break;
+ case LDIMAGINARY:t = 'J'; s = 'l'; break;
case VOID: t = 'V'; s = '\0'; break;
case PTR: t = 'P'; s = '\0'; break;
case ARRAY: t = 'A'; s = '\0'; break;
-/* $OpenBSD: externs1.h,v 1.15 2006/05/29 20:47:22 cloder Exp $ */
+/* $OpenBSD: externs1.h,v 1.16 2010/07/24 22:17:03 guenther Exp $ */
/* $NetBSD: externs1.h,v 1.7 1995/10/02 17:31:39 jpo Exp $ */
/*
extern void popdecl(void);
extern void setasm(void);
extern void clrtyp(void);
+extern int mergedomain(tspec_t *, tspec_t);
extern void deftyp(void);
extern int length(type_t *, const char *);
extern int getbound(type_t *);
-/* $OpenBSD: lint.h,v 1.6 2006/05/29 20:47:22 cloder Exp $ */
+/* $OpenBSD: lint.h,v 1.7 2010/07/24 22:17:03 guenther Exp $ */
/* $NetBSD: lint.h,v 1.2 1995/07/03 21:24:18 cgd Exp $ */
/*
NOTSPEC,
SIGNED, /* keyword "signed", only used in the parser */
UNSIGN, /* keyword "unsigned", only used in the parser */
+ BOOL, /* _Bool */
CHAR, /* char */
SCHAR, /* signed char */
UCHAR, /* unsigned char */
FLOAT, /* float */
DOUBLE, /* double */
LDOUBLE, /* long double */
+ COMPLEX, /* float _Complex */
+ DCOMPLEX, /* double _Complex */
+ LDCOMPLEX, /* long double _Complex */
+ IMAGINARY, /* float _Imaginary */
+ DIMAGINARY, /* double _Imaginary */
+ LDIMAGINARY, /* long double _Imaginary */
VOID, /* void */
STRUCT, /* structure tag */
UNION, /* union tag */
u_int tt_isutyp : 1; /* 1 if unsigned integer type */
u_int tt_isftyp : 1; /* 1 if floating point type */
u_int tt_isatyp : 1; /* 1 if arithmetic type */
- u_int tt_issclt : 1; /* 1 if scalar type */
+ u_int tt_domain : 2; /* 0 if non-scalar, 1 if real,
+ 2 if imaginary, 3 if complex */
char *tt_name; /* type name */
} ttab_t;
#define isutyp(t) (ttab[t].tt_isutyp)
#define isftyp(t) (ttab[t].tt_isftyp)
#define isatyp(t) (ttab[t].tt_isatyp)
-#define issclt(t) (ttab[t].tt_issclt)
+#define issclt(t) (ttab[t].tt_domain != 0)
+#define iscomplex(t) (ttab[t].tt_domain == 3)
+#define isimag(t) (ttab[t].tt_domain == 2)
extern ttab_t ttab[];
-/* $OpenBSD: lint1.h,v 1.13 2006/04/18 02:59:40 cloder Exp $ */
+/* $OpenBSD: lint1.h,v 1.14 2010/07/24 22:17:03 guenther Exp $ */
/* $NetBSD: lint1.h,v 1.6 1995/10/02 17:31:41 jpo Exp $ */
/*
tqual_t _s_tqu; /* qualifier (only for keywords) */
struct sym *_s_args; /* arguments in old style function
definitions */
+ op_t _s_op; /* op type (only for operators) */
} u;
struct sym *s_link; /* next symbol with same hash value */
struct sym **s_rlink; /* pointer to s_link of prev. symbol */
#define s_etyp u._s_et
#define s_tspec u._s_tsp
#define s_tqual u._s_tqu
+#define s_op u._s_op
#define s_args u._s_args
/*
*
*/
typedef struct dinfo {
- tspec_t d_atyp; /* VOID, CHAR, INT, FLOAT or DOUBLE */
- tspec_t d_smod; /* SIGNED or UNSIGN */
- tspec_t d_lmod; /* SHORT, LONG or QUAD */
+ tspec_t d_atyp; /* NOTSPEC, VOID, CHAR, INT, FLOAT or DOUBLE */
+ tspec_t d_smod; /* sign: NOTSPEC, SIGNED or UNSIGN */
+ tspec_t d_lmod; /* length: NOTSPEC, SHORT, LONG or QUAD */
+ tspec_t d_dmod; /* domain: NOTSPEC, COMPLEX or IMAGINARY */
scl_t d_scl; /* storage class */
type_t *d_type; /* after deftyp() pointer to the type used
for all declarators */
-/* $OpenBSD: op.h,v 1.3 2005/11/29 20:09:57 cloder Exp $ */
+/* $OpenBSD: op.h,v 1.4 2010/07/24 22:17:03 guenther Exp $ */
/* $NetBSD: op.h,v 1.2 1995/07/03 21:24:27 cgd Exp $ */
/*
LOAD,
PUSH,
RETURN,
+ REAL, /* gcc extension: __real__ */
+ IMAG, /* gcc extension: __imag__ */
INIT, /* pseudo op, not used in trees */
CASE, /* pseudo op, not used in trees */
FARG /* pseudo op, not used in trees */
%{
-/* $OpenBSD: scan.l,v 1.31 2007/09/05 16:32:17 fgsch Exp $ */
+/* $OpenBSD: scan.l,v 1.32 2010/07/24 22:17:03 guenther Exp $ */
/* $NetBSD: scan.l,v 1.8 1995/10/23 13:38:51 jpo Exp $ */
/*
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: scan.l,v 1.31 2007/09/05 16:32:17 fgsch Exp $";
+static char rcsid[] = "$OpenBSD: scan.l,v 1.32 2010/07/24 22:17:03 guenther Exp $";
#endif
#include <stdlib.h>
HD [0-9A-Fa-f]
EX ([eE][+-]?[0-9]+)
HEX ([pP][+-]?[0-9]+)
+FSUFF ([fFlL][iIjJ]?|[iIjJ][fFlL]?)?
%%
0{OD}*[lLuU]* return (icon(8));
{NZD}{D}*[lLuU]* return (icon(10));
0[xX]{HD}+[lLuU]* return (icon(16));
-{D}+\.{D}*{EX}?[fFlL]? |
-{D}+{EX}[fFlL]? |
-\.{D}+{EX}?[fFlL]? return (fcon());
-0[xX]{HD}+\.{HD}*{HEX}[fFlL]? |
-0[xX]{HD}+{HEX}[fFlL]? |
-0[xX]\.{HD}+{HEX}[fFlL]? return (fhexcon());
+{D}+\.{D}*{EX}?{FSUFF} |
+{D}+{EX}{FSUFF} |
+\.{D}+{EX}?{FSUFF} return (fcon());
+0[xX]{HD}+\.{HD}*{HEX}{FSUFF} |
+0[xX]{HD}+{HEX}{FSUFF} |
+0[xX]\.{HD}+{HEX}{FSUFF} return (fhexcon());
"=" return (operator(T_ASSIGN, ASSIGN));
"*=" return (operator(T_OPASS, MULASS));
"/=" return (operator(T_OPASS, DIVASS));
scl_t kw_scl; /* storage class if kw_token T_SCLASS */
tspec_t kw_tspec; /* type spec. if kw_token T_TYPE or T_SOU */
tqual_t kw_tqual; /* type qual. if kw_token T_QUAL */
+ op_t kw_op; /* operator if kw_token T_UNOP */
} kw_u;
u_int kw_stdc : 1; /* STDC keyword */
u_int kw_gcc : 1; /* GCC keyword */
{ "__asm__", T_ASM, { 0 }, 0, 0 },
{ "__attribute__", T_ATTRIBUTE, { 0 }, 0, 0 },
{ "auto", T_SCLASS, { AUTO }, 0, 0 },
+ { "_Bool", T_TYPE, { BOOL }, 1, 0 },
{ "break", T_BREAK, { 0 }, 0, 0 },
{ "case", T_CASE, { 0 }, 0, 0 },
{ "char", T_TYPE, { CHAR }, 0, 0 },
+ { "_Complex", T_TYPE, { COMPLEX }, 1, 0 },
+ { "__complex__", T_TYPE, { COMPLEX }, 0, 1 },
{ "const", T_QUAL, { CONST }, 1, 0 },
{ "__const__", T_QUAL, { CONST }, 0, 0 },
{ "__const", T_QUAL, { CONST }, 0, 0 },
{ "for", T_FOR, { 0 }, 0, 0 },
{ "goto", T_GOTO, { 0 }, 0, 0 },
{ "if", T_IF, { 0 }, 0, 0 },
+ { "__imag__", T_UNOP, { IMAG }, 0, 0 /*1*/ },
+/* { "_Imaginary", T_TYPE, { IMAGINARY }, 1, 0 }, */
{ "inline", T_SCLASS, { INLINE }, 1, 0 },
{ "__inline__", T_SCLASS, { INLINE }, 0, 0 },
{ "__inline", T_SCLASS, { INLINE }, 0, 0 },
{ "int", T_TYPE, { INT }, 0, 0 },
{ "__lint_equal__", T_LEQUAL, { 0 }, 0, 0 },
{ "long", T_TYPE, { LONG }, 0, 0 },
+ { "__real__", T_UNOP, { REAL }, 0, 0 /*1*/ },
{ "register", T_SCLASS, { REG }, 0, 0 },
{ "__restrict", T_QUAL, { RESTRICT }, 0, 0 },
{ "__restrict__", T_QUAL, { RESTRICT }, 0, 0 },
#define kw_scl kw_u.kw_scl
#define kw_tspec kw_u.kw_tspec
#define kw_tqual kw_u.kw_tqual
+#define kw_op kw_u.kw_op
/* Symbol table */
static sym_t *symtab[HSHSIZ1];
sym->s_scl = kw->kw_scl;
} else if (kw->kw_token == T_QUAL) {
sym->s_tqual = kw->kw_tqual;
+ } else if (kw->kw_token == T_UNOP) {
+ sym->s_op = kw->kw_op;
}
h = hash(sym->s_name);
if ((sym->s_link = symtab[h]) != NULL)
yylval.y_tspec = sym->s_tspec;
} else if (t == T_QUAL) {
yylval.y_tqual = sym->s_tqual;
+ } else if (t == T_UNOP) {
+ yylval.y_op = sym->s_op;
}
return (t);
}
const char *cp;
int len;
tspec_t typ;
+ tspec_t domain = NOTSPEC;
char c, *eptr;
double d;
float f;
cp = yytext;
len = yyleng;
- if ((c = cp[len - 1]) == 'f' || c == 'F') {
+ c = cp[len - 1];
+ if (c == 'i' || c == 'I' || c == 'j' || c == 'J') {
+ domain = COMPLEX; /* XXX should be IMAGINARY */
+ len--;
+ c = cp[len - 1];
+ }
+ if (c == 'f' || c == 'F') {
typ = FLOAT;
len--;
+ c = cp[len - 1];
} else if (c == 'l' || c == 'L') {
typ = LDOUBLE;
len--;
+ c = cp[len - 1];
} else {
typ = DOUBLE;
}
+ if (c == 'i' || c == 'I' || c == 'j' || c == 'J') {
+ if (domain != NOTSPEC)
+ lerror("fcon() 2"); /* can't happen */
+ domain = COMPLEX; /* XXX should be IMAGINARY */
+ len--;
+ }
errno = 0;
d = strtod(cp, &eptr);
}
}
- (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ;
+ yylval.y_val = xcalloc(1, sizeof (val_t));
if (typ == FLOAT) {
yylval.y_val->v_ldbl = f;
} else {
yylval.y_val->v_ldbl = d;
}
+ if (mergedomain(&typ, domain))
+ lerror("fcon() 3");
+ yylval.y_val->v_tspec = typ;
return (T_CON);
}
const char *cp;
int len;
tspec_t typ;
+ tspec_t domain = NOTSPEC;
char c;
double d;
float f;
cp = yytext;
len = yyleng;
- if ((c = cp[len - 1]) == 'f' || c == 'F') {
+ c = cp[len - 1];
+ if (c == 'i' || c == 'I' || c == 'j' || c == 'J') {
+ domain = COMPLEX; /* XXX should be IMAGINARY */
+ len--;
+ c = cp[len - 1];
+ }
+ if (c == 'f' || c == 'F') {
typ = FLOAT;
len--;
+ c = cp[len - 1];
} else if (c == 'l' || c == 'L') {
typ = LDOUBLE;
len--;
+ c = cp[len - 1];
} else {
typ = DOUBLE;
}
+ if (c == 'i' || c == 'I' || c == 'j' || c == 'J') {
+ if (domain != NOTSPEC)
+ lerror("fhexcon() 1"); /* can't happen */
+ domain = COMPLEX; /* XXX should be IMAGINARY */
+ len--;
+ }
/* arbitrary value, until strtod can cope */
d = 1.0;
f = (float)d;
}
- (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ;
+ yylval.y_val = xcalloc(1, sizeof (val_t));
if (typ == FLOAT) {
yylval.y_val->v_ldbl = f;
} else {
yylval.y_val->v_ldbl = d;
}
+ if (mergedomain(&typ, domain))
+ lerror("fhexcon() 2");
+ yylval.y_val->v_tspec = typ;
return (T_CON);
}
-/* $OpenBSD: tree.c,v 1.46 2007/10/17 20:10:44 chl Exp $ */
+/* $OpenBSD: tree.c,v 1.47 2010/07/24 22:17:03 guenther Exp $ */
/* $NetBSD: tree.c,v 1.12 1995/10/02 17:37:57 jpo Exp $ */
/*
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: tree.c,v 1.46 2007/10/17 20:10:44 chl Exp $";
+static char rcsid[] = "$OpenBSD: tree.c,v 1.47 2010/07/24 22:17:03 guenther Exp $";
#endif
#include <stdlib.h>
"PUSH" } },
{ RETURN, { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,
"RETURN" } },
+ { REAL, { 0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,
+ "__real__" } },
+ { IMAG, { 0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,
+ "__imag__" } },
{ INIT, { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
"INIT" } },
{ FARG, { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
case QUEST:
ntn = mktnode(op, rn->tn_type, ln, rn);
break;
+ case REAL:
+ case IMAG:
+ rtp = ln->tn_type;
+ if (rtp->t_tspec == COMPLEX)
+ rtp = gettyp(FLOAT);
+ else if (rtp->t_tspec == DCOMPLEX)
+ rtp = gettyp(DOUBLE);
+ else if (rtp->t_tspec == LDCOMPLEX)
+ rtp = gettyp(LDOUBLE);
+ ntn = mktnode(op, rtp, ln, rn);
+ break;
default:
rtp = mp->m_logop ? gettyp(INT) : ln->tn_type;
if (!mp->m_binary && rn != NULL)
}
if (mp->m_rqint) {
+ if (op == COMPL && iscomplex(lt)) {
+ /* use of '~' for complex conjugation is a GNUism */
+ } else
/* integer types required */
if (!isityp(lt) || (mp->m_binary && !isityp(rt))) {
incompat(op, lt, rt);
} else {
lerror("mktnode() 2");
}
+ } else if (op == REAL || op == IMAG) {
+ ntn->tn_lvalue = ln->tn_lvalue;
}
return (ntn);
if (op == CVT)
return;
+ /* logical ops return int, so silently convert int to _Bool */
+ if (ot == INT && nt == BOOL)
+ return;
+
if (rank(nt) < rank(ot)) {
/* coercion from greater to lesser width */
if (op == FARG) {
if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) {
switch (nt) {
+ case BOOL:
+ max = 1; min = 0; break;
case CHAR:
max = CHAR_MAX; min = CHAR_MIN; break;
case UCHAR:
/* Already an error because of float --> ptr */
case LDOUBLE:
max = LDBL_MAX; min = -LDBL_MAX; break;
+ case COMPLEX:
+ max = FLT_MAX; min = -FLT_MAX; break;
+ case DCOMPLEX:
+ max = DBL_MAX; min = -DBL_MAX; break;
+ case LDCOMPLEX:
+ max = LDBL_MAX; min = -LDBL_MAX; break;
+ case IMAGINARY:
+ case DIMAGINARY:
+ case LDIMAGINARY:
+ max = 0; min = 0; break;
default:
lerror("cvtcon() 1");
}
if (v->v_ldbl > max || v->v_ldbl < min) {
- if (nt == LDOUBLE)
+ if (nt == LDOUBLE || nt == LDCOMPLEX)
lerror("cvtcon() 2");
if (op == FARG) {
/* %s arg #%d: conv. of %s to %s is out of range */
(u_quad_t)v->v_ldbl : (quad_t)v->v_ldbl;
}
} else {
- if (nt == FLOAT) {
+ if (nt == FLOAT || nt == COMPLEX) {
nv->v_ldbl = (ot == PTR || isutyp(ot)) ?
(float)(u_quad_t)v->v_quad : (float)v->v_quad;
- } else if (nt == DOUBLE) {
+ } else if (nt == DOUBLE || nt == DCOMPLEX) {
nv->v_ldbl = (ot == PTR || isutyp(ot)) ?
(double)(u_quad_t)v->v_quad : (double)v->v_quad;
- } else if (nt == LDOUBLE) {
+ } else if (nt == LDOUBLE || nt == LDCOMPLEX) {
nv->v_ldbl = (ot == PTR || isutyp(ot)) ?
(ldbl_t)(u_quad_t)v->v_quad : (ldbl_t)v->v_quad;
+ } else if (nt == IMAGINARY || nt == DIMAGINARY ||
+ nt == LDIMAGINARY) {
+ nv->v_ldbl = 0;
} else {
rchk = 1; /* Check for lost precision. */
nv->v_quad = v->v_quad;
t = ENUM;
switch (t) {
+ case BOOL: s = "_Bool"; break;
case CHAR: s = "char"; break;
case UCHAR: s = "unsigned char"; break;
case SCHAR: s = "signed char"; break;
case FLOAT: s = "float"; break;
case DOUBLE: s = "double"; break;
case LDOUBLE: s = "long double"; break;
+ case COMPLEX: s = "float _Complex"; break;
+ case DCOMPLEX: s = "double _Complex"; break;
+ case LDCOMPLEX: s = "long double _Complex"; break;
+ case IMAGINARY: s = "float _Imaginary"; break;
+ case DIMAGINARY: s = "double _Imaginary"; break;
+ case LDIMAGINARY:s = "long double _Imaginary"; break;
case PTR: s = "pointer"; break;
case ENUM: s = "enum"; break;
case STRUCT: s = "struct"; break;
case OR:
q = utyp ? ul | ur : sl | sr;
break;
+ case REAL:
+ case IMAG:
+ q = sl;
default:
lerror("fold() 5");
}
case NE:
v->v_quad = l != r;
break;
+ case REAL:
+ case IMAG:
+ v->v_ldbl = l;
+ break;
default:
lerror("foldflt() 4");
}
case STAR:
case NAME:
case STRING:
+ case REAL:
+ case IMAG:
break;
default:
warning(312, modtab[tn->tn_op].m_name);
case XORASS:
case SHLASS:
case SHRASS:
+ case REAL:
+ case IMAG:
if (ln->tn_op == NAME && (reached || rchflg)) {
sc = ln->tn_sym->s_scl;
/*
-/* $OpenBSD: chk.c,v 1.16 2007/05/26 00:36:04 krw Exp $ */
+/* $OpenBSD: chk.c,v 1.17 2010/07/24 22:17:03 guenther Exp $ */
/* $NetBSD: chk.c,v 1.2 1995/07/03 21:24:42 cgd Exp $ */
/*
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: chk.c,v 1.16 2007/05/26 00:36:04 krw Exp $";
+static char rcsid[] = "$OpenBSD: chk.c,v 1.17 2010/07/24 22:17:03 guenther Exp $";
#endif
#include <stdlib.h>
{ UNSIGN, { 0, 0, 0,
SIGNED, UNSIGN,
0, 0, 0, 0, 0, "unsigned" } },
+ { BOOL, { sizeof (_Bool) * CHAR_BIT, CHAR_BIT, 1,
+ BOOL, BOOL,
+ 1, 1, 0, 1, 1, "_Bool" } },
{ CHAR, { CHAR_BIT, CHAR_BIT, 20,
SCHAR, UCHAR,
1, 0, 0, 1, 1, "char" } },
{ LDOUBLE, { sizeof (ldbl_t) * CHAR_BIT, 10 * CHAR_BIT, -1,
LDOUBLE, LDOUBLE,
0, 0, 1, 1, 1, "long double" } },
+ { COMPLEX, { sizeof (_Complex float) * CHAR_BIT,
+ 8 * CHAR_BIT, -1,
+ COMPLEX, COMPLEX,
+ 0, 0, 1, 1, 1, "float _Complex" } },
+ { DCOMPLEX, { sizeof (double _Complex) * CHAR_BIT,
+ 16 * CHAR_BIT, -1,
+ DCOMPLEX, DCOMPLEX,
+ 0, 0, 1, 1, 1, "double _Complex" } },
+ { LDCOMPLEX,{ sizeof (long double _Complex) * CHAR_BIT,
+ 20 * CHAR_BIT, -1,
+ LDCOMPLEX, LDCOMPLEX,
+ 0, 0, 1, 1, 1, "long double _Complex" } },
{ VOID, { -1, -1, -1,
VOID, VOID,
0, 0, 0, 0, 0, "void" } },
-/* $OpenBSD: emit2.c,v 1.5 2005/11/20 17:09:55 cloder Exp $ */
+/* $OpenBSD: emit2.c,v 1.6 2010/07/24 22:17:03 guenther Exp $ */
/* $NetBSD: emit2.c,v 1.2 1995/07/03 21:24:44 cgd Exp $ */
/*
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: emit2.c,v 1.5 2005/11/20 17:09:55 cloder Exp $";
+static char rcsid[] = "$OpenBSD: emit2.c,v 1.6 2010/07/24 22:17:03 guenther Exp $";
#endif
#include <err.h>
if ((ts = tp->t_tspec) == INT && tp->t_isenum)
ts = ENUM;
switch (ts) {
+ case BOOL: t = 'B'; s = '\0'; break;
case CHAR: t = 'C'; s = '\0'; break;
case SCHAR: t = 'C'; s = 's'; break;
case UCHAR: t = 'C'; s = 'u'; break;
case FLOAT: t = 'D'; s = 's'; break;
case DOUBLE: t = 'D'; s = '\0'; break;
case LDOUBLE: t = 'D'; s = 'l'; break;
+ case COMPLEX: t = 'X'; s = 's'; break;
+ case DCOMPLEX: t = 'X'; s = '\0'; break;
+ case LDCOMPLEX: t = 'X'; s = 'l'; break;
+ case IMAGINARY: t = 'J'; s = 's'; break;
+ case DIMAGINARY: t = 'J'; s = '\0'; break;
+ case LDIMAGINARY:t = 'J'; s = 'l'; break;
case VOID: t = 'V'; s = '\0'; break;
case PTR: t = 'P'; s = '\0'; break;
case ARRAY: t = 'A'; s = '\0'; break;
-/* $OpenBSD: read.c,v 1.9 2005/12/01 05:06:40 cloder Exp $ */
+/* $OpenBSD: read.c,v 1.10 2010/07/24 22:17:03 guenther Exp $ */
/* $NetBSD: read.c,v 1.2 1995/07/03 21:24:59 cgd Exp $ */
/*
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: read.c,v 1.9 2005/12/01 05:06:40 cloder Exp $";
+static char rcsid[] = "$OpenBSD: read.c,v 1.10 2010/07/24 22:17:03 guenther Exp $";
#endif
#include <stdio.h>
}
switch (c) {
+ case 'B':
+ tp->t_tspec = BOOL;
+ break;
case 'C':
tp->t_tspec = s == 's' ? SCHAR : (s == 'u' ? UCHAR : CHAR);
break;
case 'D':
tp->t_tspec = s == 's' ? FLOAT : (s == 'l' ? LDOUBLE : DOUBLE);
break;
+ case 'X':
+ tp->t_tspec = s == 's' ? COMPLEX : (s == 'l' ?
+ LDCOMPLEX : DCOMPLEX);
+ break;
+ case 'J':
+ tp->t_tspec = s == 's' ? IMAGINARY : (s == 'l' ?
+ LDIMAGINARY : DIMAGINARY);
+ break;
case 'V':
tp->t_tspec = VOID;
break;
t = NOTSPEC;
switch (c) {
+ case 'B':
+ t = BOOL;
+ break;
case 'C':
if (s == 's') {
t = SCHAR;
t = DOUBLE;
}
break;
+ case 'X':
+ if (s == 's') {
+ t = COMPLEX;
+ } else if (s == 'l') {
+ t = LDCOMPLEX;
+ } else if (s == '\0') {
+ t = DCOMPLEX;
+ }
+ break;
+ case 'J':
+ if (s == 's') {
+ t = IMAGINARY;
+ } else if (s == 'l') {
+ t = LDIMAGINARY;
+ } else if (s == '\0') {
+ t = DIMAGINARY;
+ }
+ break;
case 'V':
if (s == '\0')
t = VOID;