Move type_incompatibility_error earlier

also move type_incompatibility_warning and type_to_str.
This commit is contained in:
Michael Matz 2020-04-15 02:08:09 +02:00
parent 096c93c0c6
commit 00fbf65524

308
tccgen.c
View File

@ -2429,6 +2429,160 @@ static void gen_opif(int op)
}
}
/* print a type. If 'varstr' is not NULL, then the variable is also
printed in the type */
/* XXX: union */
/* XXX: add array and function pointers */
static void type_to_str(char *buf, int buf_size,
CType *type, const char *varstr)
{
int bt, v, t;
Sym *s, *sa;
char buf1[256];
const char *tstr;
t = type->t;
bt = t & VT_BTYPE;
buf[0] = '\0';
if (t & VT_EXTERN)
pstrcat(buf, buf_size, "extern ");
if (t & VT_STATIC)
pstrcat(buf, buf_size, "static ");
if (t & VT_TYPEDEF)
pstrcat(buf, buf_size, "typedef ");
if (t & VT_INLINE)
pstrcat(buf, buf_size, "inline ");
if (t & VT_VOLATILE)
pstrcat(buf, buf_size, "volatile ");
if (t & VT_CONSTANT)
pstrcat(buf, buf_size, "const ");
if (((t & VT_DEFSIGN) && bt == VT_BYTE)
|| ((t & VT_UNSIGNED)
&& (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
&& !IS_ENUM(t)
))
pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
buf_size -= strlen(buf);
buf += strlen(buf);
switch(bt) {
case VT_VOID:
tstr = "void";
goto add_tstr;
case VT_BOOL:
tstr = "_Bool";
goto add_tstr;
case VT_BYTE:
tstr = "char";
goto add_tstr;
case VT_SHORT:
tstr = "short";
goto add_tstr;
case VT_INT:
tstr = "int";
goto maybe_long;
case VT_LLONG:
tstr = "long long";
maybe_long:
if (t & VT_LONG)
tstr = "long";
if (!IS_ENUM(t))
goto add_tstr;
tstr = "enum ";
goto tstruct;
case VT_FLOAT:
tstr = "float";
goto add_tstr;
case VT_DOUBLE:
tstr = "double";
if (!(t & VT_LONG))
goto add_tstr;
case VT_LDOUBLE:
tstr = "long double";
add_tstr:
pstrcat(buf, buf_size, tstr);
break;
case VT_STRUCT:
tstr = "struct ";
if (IS_UNION(t))
tstr = "union ";
tstruct:
pstrcat(buf, buf_size, tstr);
v = type->ref->v & ~SYM_STRUCT;
if (v >= SYM_FIRST_ANOM)
pstrcat(buf, buf_size, "<anonymous>");
else
pstrcat(buf, buf_size, get_tok_str(v, NULL));
break;
case VT_FUNC:
s = type->ref;
buf1[0]=0;
if (varstr && '*' == *varstr) {
pstrcat(buf1, sizeof(buf1), "(");
pstrcat(buf1, sizeof(buf1), varstr);
pstrcat(buf1, sizeof(buf1), ")");
}
pstrcat(buf1, buf_size, "(");
sa = s->next;
while (sa != NULL) {
char buf2[256];
type_to_str(buf2, sizeof(buf2), &sa->type, NULL);
pstrcat(buf1, sizeof(buf1), buf2);
sa = sa->next;
if (sa)
pstrcat(buf1, sizeof(buf1), ", ");
}
if (s->f.func_type == FUNC_ELLIPSIS)
pstrcat(buf1, sizeof(buf1), ", ...");
pstrcat(buf1, sizeof(buf1), ")");
type_to_str(buf, buf_size, &s->type, buf1);
goto no_var;
case VT_PTR:
s = type->ref;
if (t & VT_ARRAY) {
if (varstr && '*' == *varstr)
snprintf(buf1, sizeof(buf1), "(%s)[%d]", varstr, s->c);
else
snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c);
type_to_str(buf, buf_size, &s->type, buf1);
goto no_var;
}
pstrcpy(buf1, sizeof(buf1), "*");
if (t & VT_CONSTANT)
pstrcat(buf1, buf_size, "const ");
if (t & VT_VOLATILE)
pstrcat(buf1, buf_size, "volatile ");
if (varstr)
pstrcat(buf1, sizeof(buf1), varstr);
type_to_str(buf, buf_size, &s->type, buf1);
goto no_var;
}
if (varstr) {
pstrcat(buf, buf_size, " ");
pstrcat(buf, buf_size, varstr);
}
no_var: ;
}
static void type_incompatibility_error(CType* st, CType* dt, const char* fmt)
{
char buf1[256], buf2[256];
type_to_str(buf1, sizeof(buf1), st, NULL);
type_to_str(buf2, sizeof(buf2), dt, NULL);
tcc_error(fmt, buf1, buf2);
}
static void type_incompatibility_warning(CType* st, CType* dt, const char* fmt)
{
char buf1[256], buf2[256];
type_to_str(buf1, sizeof(buf1), st, NULL);
type_to_str(buf2, sizeof(buf2), dt, NULL);
tcc_warning(fmt, buf1, buf2);
}
static int pointed_size(CType *type)
{
int align;
@ -3175,160 +3329,6 @@ static int is_compatible_unqualified_types(CType *type1, CType *type2)
return compare_types(type1,type2,1);
}
/* print a type. If 'varstr' is not NULL, then the variable is also
printed in the type */
/* XXX: union */
/* XXX: add array and function pointers */
static void type_to_str(char *buf, int buf_size,
CType *type, const char *varstr)
{
int bt, v, t;
Sym *s, *sa;
char buf1[256];
const char *tstr;
t = type->t;
bt = t & VT_BTYPE;
buf[0] = '\0';
if (t & VT_EXTERN)
pstrcat(buf, buf_size, "extern ");
if (t & VT_STATIC)
pstrcat(buf, buf_size, "static ");
if (t & VT_TYPEDEF)
pstrcat(buf, buf_size, "typedef ");
if (t & VT_INLINE)
pstrcat(buf, buf_size, "inline ");
if (t & VT_VOLATILE)
pstrcat(buf, buf_size, "volatile ");
if (t & VT_CONSTANT)
pstrcat(buf, buf_size, "const ");
if (((t & VT_DEFSIGN) && bt == VT_BYTE)
|| ((t & VT_UNSIGNED)
&& (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
&& !IS_ENUM(t)
))
pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
buf_size -= strlen(buf);
buf += strlen(buf);
switch(bt) {
case VT_VOID:
tstr = "void";
goto add_tstr;
case VT_BOOL:
tstr = "_Bool";
goto add_tstr;
case VT_BYTE:
tstr = "char";
goto add_tstr;
case VT_SHORT:
tstr = "short";
goto add_tstr;
case VT_INT:
tstr = "int";
goto maybe_long;
case VT_LLONG:
tstr = "long long";
maybe_long:
if (t & VT_LONG)
tstr = "long";
if (!IS_ENUM(t))
goto add_tstr;
tstr = "enum ";
goto tstruct;
case VT_FLOAT:
tstr = "float";
goto add_tstr;
case VT_DOUBLE:
tstr = "double";
if (!(t & VT_LONG))
goto add_tstr;
case VT_LDOUBLE:
tstr = "long double";
add_tstr:
pstrcat(buf, buf_size, tstr);
break;
case VT_STRUCT:
tstr = "struct ";
if (IS_UNION(t))
tstr = "union ";
tstruct:
pstrcat(buf, buf_size, tstr);
v = type->ref->v & ~SYM_STRUCT;
if (v >= SYM_FIRST_ANOM)
pstrcat(buf, buf_size, "<anonymous>");
else
pstrcat(buf, buf_size, get_tok_str(v, NULL));
break;
case VT_FUNC:
s = type->ref;
buf1[0]=0;
if (varstr && '*' == *varstr) {
pstrcat(buf1, sizeof(buf1), "(");
pstrcat(buf1, sizeof(buf1), varstr);
pstrcat(buf1, sizeof(buf1), ")");
}
pstrcat(buf1, buf_size, "(");
sa = s->next;
while (sa != NULL) {
char buf2[256];
type_to_str(buf2, sizeof(buf2), &sa->type, NULL);
pstrcat(buf1, sizeof(buf1), buf2);
sa = sa->next;
if (sa)
pstrcat(buf1, sizeof(buf1), ", ");
}
if (s->f.func_type == FUNC_ELLIPSIS)
pstrcat(buf1, sizeof(buf1), ", ...");
pstrcat(buf1, sizeof(buf1), ")");
type_to_str(buf, buf_size, &s->type, buf1);
goto no_var;
case VT_PTR:
s = type->ref;
if (t & VT_ARRAY) {
if (varstr && '*' == *varstr)
snprintf(buf1, sizeof(buf1), "(%s)[%d]", varstr, s->c);
else
snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c);
type_to_str(buf, buf_size, &s->type, buf1);
goto no_var;
}
pstrcpy(buf1, sizeof(buf1), "*");
if (t & VT_CONSTANT)
pstrcat(buf1, buf_size, "const ");
if (t & VT_VOLATILE)
pstrcat(buf1, buf_size, "volatile ");
if (varstr)
pstrcat(buf1, sizeof(buf1), varstr);
type_to_str(buf, buf_size, &s->type, buf1);
goto no_var;
}
if (varstr) {
pstrcat(buf, buf_size, " ");
pstrcat(buf, buf_size, varstr);
}
no_var: ;
}
static void type_incompatibility_error(CType* st, CType* dt, const char* fmt)
{
char buf1[256], buf2[256];
type_to_str(buf1, sizeof(buf1), st, NULL);
type_to_str(buf2, sizeof(buf2), dt, NULL);
tcc_error(fmt, buf1, buf2);
}
static void type_incompatibility_warning(CType* st, CType* dt, const char* fmt)
{
char buf1[256], buf2[256];
type_to_str(buf1, sizeof(buf1), st, NULL);
type_to_str(buf2, sizeof(buf2), dt, NULL);
tcc_warning(fmt, buf1, buf2);
}
static void cast_error(CType *st, CType *dt)
{
type_incompatibility_error(st, dt, "cannot convert '%s' to '%s'");