BOOLEAN assignDiscardsConst(TYPE *dest, TYPE *source) { source = basetype(source); dest = basetype(dest); if (!ispointer(source) || !ispointer(dest)) return FALSE; while (TRUE) { BOOLEAN destc = FALSE; BOOLEAN sourcc = FALSE; BOOLEAN done = FALSE; while (!done) { switch(dest->type) { case bt_const: destc = TRUE; case bt_restrict: case bt_volatile: case bt_static: case bt_typedef: case bt_lrqual: case bt_rrqual: case bt_derivedfromtemplate: dest = dest->btp; break; default: done = TRUE; break; } } done = FALSE; while (!done) { switch(source->type) { case bt_const: sourcc = TRUE; case bt_restrict: case bt_volatile: case bt_static: case bt_typedef: case bt_lrqual: case bt_rrqual: source = source->btp; break; default: done = TRUE; break; } } if (sourcc && !destc) return TRUE; if (source->type != bt_pointer || dest->type != bt_pointer) return FALSE; dest = dest->btp; source = source->btp; } }
/** * Used by #DNA_struct_get_compareflags (below) to recursively mark all structs * containing a field of type structnr as changed between old and current SDNAs. */ static void recurs_test_compflags(const SDNA *sdna, char *compflags, int structnr) { int a, b, typenr, elems; const short *sp; const char *cp; /* check all structs, test if it's inside another struct */ sp = sdna->structs[structnr]; typenr = sp[0]; for (a = 0; a < sdna->nr_structs; a++) { if ((a != structnr) && (compflags[a] == SDNA_CMP_EQUAL)) { sp = sdna->structs[a]; elems = sp[1]; sp += 2; for (b = 0; b < elems; b++, sp += 2) { if (sp[0] == typenr) { cp = sdna->names[sp[1]]; if (!ispointer(cp)) { compflags[a] = SDNA_CMP_NOT_EQUAL; recurs_test_compflags(sdna, compflags, a); } } } } } }
/** * Returns the size of struct fields of the specified type and name. * * \param type Index into sdna->types/typelens * \param name Index into sdna->names, * needed to extract possible pointer/array information. */ static int elementsize(const SDNA *sdna, short type, short name) { int mul, namelen, len; const char *cp; cp = sdna->names[name]; len = 0; namelen = strlen(cp); /* is it a pointer or function pointer? */ if (ispointer(cp)) { /* has the name an extra length? (array) */ mul = 1; if (cp[namelen - 1] == ']') { mul = DNA_elem_array_size(cp); } len = sdna->pointerlen * mul; } else if (sdna->typelens[type]) { /* has the name an extra length? (array) */ mul = 1; if (cp[namelen - 1] == ']') { mul = DNA_elem_array_size(cp); } len = mul * sdna->typelens[type]; } return len; }
BOOLEAN matchingCharTypes(TYPE *typ1, TYPE *typ2) { if (isref(typ1)) typ1 = basetype(typ1)->btp; if (isref(typ2)) typ2 = basetype(typ2)->btp; while (ispointer(typ1) && ispointer(typ2)) { typ1 = basetype(typ1)->btp; typ2 = basetype(typ2)->btp; } typ1 = basetype(typ1); typ2 = basetype(typ2); if (typ1->type == bt_char) { if (cparams.prm_charisunsigned) { if (typ2->type == bt_unsigned_char) return TRUE; } else { if (typ2->type == bt_signed_char) return TRUE; } } else if (typ2->type == bt_char) { if (cparams.prm_charisunsigned) { if (typ1->type == bt_unsigned_char) return TRUE; } else { if (typ1->type == bt_signed_char) return TRUE; } } return FALSE; }
void typenumptr(char *buf, TYPE *tp) { char bf[256], *p = bf; p = putpointer(p, tp); tp = enumConst(buf, tp->btp); while (ispointer(tp)) { p = putpointer(p, tp); tp = enumConst(buf, tp->btp); // tp = tp->btp; } typenum(buf, tp); strcat(buf, bf); }
BOOLEAN ispointer(TYPE *tp) { tp = basetype(tp); switch(tp->type) { case bt_far: case bt_pointer: case bt_seg: return TRUE; case bt_templateparam: if (tp->templateParam->p->type == kw_int) return ispointer(tp->templateParam->p->byNonType.tp); return FALSE; default: return FALSE; } }
SYMBOL *getFunctionSP(TYPE **tp) { TYPE *btp = basetype(*tp); BOOLEAN pointer = ispointer(btp); if (pointer) { btp = basetype(btp)->btp; } if (isfunction(btp)) { *tp = btp; return basetype(btp)->sp; } else if (btp->type == bt_aggregate) { return btp->sp; } return NULL; }
BOOL comparetypes(TYPE *typ1, TYPE *typ2, int exact) { if (typ1->type == bt_any || typ2->type == bt_any) return TRUE; if (typ1->type == bt_typedef) typ1 = basetype(typ1); if (typ2->type == bt_typedef) typ2 = basetype(typ2); if (isref(typ1)) typ1 = basetype(typ1)->btp; if (isref(typ2)) typ2 = basetype(typ2)->btp; if (ispointer(typ1) && ispointer(typ2)) if (exact) { int arr = FALSE; int first = TRUE; while (ispointer(typ1) && ispointer(typ2)) { if (!first && (exact == 1)) if (isconst(typ2) && !isconst(typ1) || isvolatile(typ2) && !isvolatile(typ1)) return FALSE; first = FALSE; typ1 = basetype(typ1); typ2 = basetype(typ2); if (typ1->type != typ2->type) return FALSE; if (arr && typ1->array != typ2->array) return FALSE; if (arr && typ1->size != typ2->size) return FALSE; arr |= typ1->array | typ2->array; typ1 = typ1->btp; typ2 = typ2->btp; } if ((exact == 1) && (isconst(typ2) && !isconst(typ1) || isvolatile(typ2) && !isvolatile(typ1))) return FALSE; return comparetypes(typ1, typ2, TRUE); } else return TRUE; typ1 = basetype(typ1); typ2 = basetype(typ2); if (exact && (isfunction(typ1) || isfuncptr(typ1)) && (isfunction(typ2) || isfuncptr(typ2))) { HASHREC *hr1; HASHREC *hr2; typ1 = basetype(typ1); typ2 = basetype(typ2); if (ispointer(typ1)) typ1 = basetype(typ1->btp); if (ispointer(typ2)) typ2 = basetype(typ2->btp); if (!comparetypes(typ1->btp, typ2->btp, exact)) return FALSE; hr1 = typ1->syms->table[0]; hr2 = typ2->syms->table[0]; while (hr1 && hr2) { SYMBOL *sp1 = (SYMBOL *)hr1->p; SYMBOL *sp2 = (SYMBOL *)hr2->p; if (!comparetypes(sp1->tp, sp2->tp, exact)) return FALSE; hr1 = hr1->next; hr2 = hr2->next; } if (hr1 || hr2) return FALSE; return TRUE; } if (cparams.prm_cplusplus) { if (typ1->scoped != typ2->scoped) return FALSE; if (typ1->type == bt_enum) { if (typ2->type == bt_enum) return typ1->sp == typ2->sp; else return isint(typ2); } else if (typ2->type == bt_enum) { return isint(typ1); } if (typ1->type == typ2->type && typ1->type == bt_memberptr) { if (typ1->sp != typ2->sp) { if (classRefCount(typ2->sp, typ1->sp) != 1) return FALSE; } return comparetypes(typ1->btp, typ2->btp, exact); } } if (typ1->type == typ2->type && (isstructured(typ1) || exact && typ1->type == bt_enum)) return typ1->sp == typ2->sp; if (typ1->type == typ2->type || !exact && isarithmetic(typ2) && isarithmetic(typ1)) return TRUE; if (isfunction(typ1) && isfunction(typ2) && typ1->sp->linkage == typ2->sp->linkage) return TRUE; else if (!exact && (ispointer(typ1) && (isfuncptr(typ2) || isfunction(typ2) || isint(typ2)) || ispointer(typ2) && (isfuncptr(typ1) || isfunction(typ1) || isint(typ1)))) return (TRUE); else if (typ1->type == bt_enum && isint(typ2)) { return TRUE; } else if (typ2->type == bt_enum && isint(typ1)) { return TRUE; } return FALSE; }
BOOLEAN isarray(TYPE *tp) { tp = basetype(tp); return ispointer(tp) && tp->array; }
BOOLEAN isfuncptr(TYPE *tp) { tp = basetype(tp); return ispointer(tp) && tp->btp && isfunction(tp->btp); }
BOOLEAN isvoidptr(TYPE *tp) { tp = basetype(tp); return ispointer(tp) && isvoid(tp->btp); }
TYPE *destSize(TYPE *tp1, TYPE *tp2, EXPRESSION **exp1, EXPRESSION **exp2, BOOLEAN minimizeInt, TYPE *atp) /* * compare two types and determine if they are compatible for purposes * of the current operation. Return an appropriate type. Also checks for * dangerous pointer conversions... */ { int isctp1, isctp2; if (tp1->type == bt_any) return tp1; if (tp2->type == bt_any) return tp2; if (isvoid(tp1) || isvoid(tp2)) { error(ERR_NOT_AN_ALLOWED_TYPE); return tp1; } if (isref(tp1)) tp1 = basetype(tp1)->btp; if (isref(tp2)) tp2 = basetype(tp2)->btp; tp1 = basetype(tp1); tp2 = basetype(tp2); isctp1 = isarithmetic(tp1); isctp2 = isarithmetic(tp2); /* if (isctp1 && isctp2 && tp1->type == tp2->type) return tp1 ; */ if (tp1->type >= bt_float || tp2->type >= bt_float) { int isim1 = tp1->type >= bt_float_imaginary && tp1->type <= bt_long_double_imaginary; int isim2 = tp2->type >= bt_float_imaginary && tp2->type <= bt_long_double_imaginary; if (isim1 && !isim2 && tp2->type < bt_float_imaginary) { TYPE *tp ; if (tp1->type == bt_long_double_imaginary || tp2->type == bt_long_double) tp = &stdlongdoublecomplex; else if (tp1->type == bt_double_imaginary || tp2->type == bt_double || tp1->type == bt_long_long || tp1->type == bt_unsigned_long_long) tp = &stddoublecomplex; else tp = &stdfloatcomplex; if (exp1) cast(tp, exp1); if (exp2) cast(tp, exp2); return tp; } else if (isim2 && !isim1 && tp1->type < bt_float_imaginary) { TYPE *tp ; if (tp2->type == bt_long_double_imaginary || tp1->type == bt_long_double) tp = &stdlongdoublecomplex; else if (tp2->type == bt_double_imaginary || tp1->type == bt_double || tp1->type == bt_long_long || tp1->type == bt_unsigned_long_long) tp = &stddoublecomplex; else tp = &stdfloatcomplex; if (exp1) cast(tp, exp1); if (exp2) cast(tp, exp2); return tp; } else if (tp1->type > tp2->type) { if (exp2) cast(tp1, exp2); } else if (tp1->type < tp2->type) { if (exp1) cast(tp2, exp1); } if (tp1->type == bt_long_double_complex && isctp2) return tp1; if (tp2->type == bt_long_double_complex && isctp1) return tp2; if (tp1->type == bt_long_double_imaginary && isim2) return tp1; if (tp2->type == bt_long_double_imaginary && isim1) return tp2; if (tp1->type == bt_long_double && isctp2) return tp1; if (tp2->type == bt_long_double && isctp1) return tp2; if (tp1->type == bt_double_complex && isctp2) return tp1; if (tp2->type == bt_double_complex && isctp1) return tp2; if (tp1->type == bt_double_imaginary && isim2) return tp1; if (tp2->type == bt_double_imaginary && isim1) return tp2; if (tp1->type == bt_double && isctp2) return tp1; if (tp2->type == bt_double && isctp1) return tp2; if (tp1->type == bt_float_complex && isctp2) return tp1; if (tp2->type == bt_float_complex && isctp1) return tp2; if (tp1->type == bt_float_imaginary && isim2) return tp1; if (tp2->type == bt_float_imaginary && isim1) return tp2; if (tp1->type == bt_float && isctp2) return tp1; if (tp2->type == bt_float && isctp1) return tp2; } if (isctp1 && isctp2) { TYPE *rv ; enum e_bt t1, t2; t1 = tp1->type; t2 = tp2->type; /* if (cparams.prm_cplusplus && (t1 == bt_enum || t2 == bt_enum)) { if (t1 == t2) { if (tp1->sp->mainsym == tp2->sp->mainsym) { return tp1; } genmismatcherror(ERR_ENUMMISMATCH, tp1, tp2); } } */ if (t1 == bt_enum) t1= bt_int; if (t2 == bt_enum) t2= bt_int; if (t1 == bt_wchar_t) t1 = bt_unsigned; if (t2 == bt_wchar_t) t2 = bt_unsigned; if (t1 < bt_int) t1= bt_int; if (t2 < bt_int) t2= bt_int; t1 = imax(t1, t2); rv = inttype(t1); if (rv->type != tp1->type && exp1) cast(rv, exp1); if (rv->type != tp2->type && exp2) cast(rv,exp2); return rv; } else { /* have a pointer or other exceptional case*/ if (tp1->type == bt_void && tp2->type == bt_void) return tp1; if (tp1->type <= bt_unsigned_long_long && ispointer(tp2)) { if (!ispointer(tp1)) cast(tp2, exp1); return tp2; } if (tp2->type <= bt_unsigned_long_long && ispointer(tp1)) { if (!ispointer(tp2)) cast(tp1, exp2); return tp1; } if (isstructured(tp1)) { return tp2; /* if (comparetypes(tp1, tp2, FALSE)) return tp1; if (cparams.prm_cplusplus) { cppcast(tp2, tp1, exp1, FALSE, ERR_CPPMISMATCH); } else error(ERR_ILL_STRUCTURE_OPERATION); return tp2; */ } if (isstructured(tp2)) { return tp1; /* if (comparetypes(tp1, tp2, FALSE)) return tp2; if (cparams.prm_cplusplus) { cppcast(tp1, tp2, exp1, FALSE, ERR_CPPMISMATCH); } else error(ERR_ILL_STRUCTURE_OPERATION); return tp1; */ } if (isfunction(tp1)) if (isfunction(tp2) || ispointer(tp2)) return tp1; if (isfunction(tp2)) if (isfunction(tp1) || ispointer(tp1)) return tp2; if (ispointer(tp1)) if (ispointer(tp2)) { /* if (tp1->type != tp2->type || !comparetypes(tp1->btp, tp2->btp, TRUE)) generror(ERR_SUSPICIOUS, 0, 0); */ return tp1; } } return tp1; }
static BOOLEAN is_constructible(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp) { INITLIST *lst; BOOLEAN rv = FALSE; FUNCTIONCALL funcparams; memset(&funcparams, 0, sizeof(funcparams)); funcparams.sp = sym; *lex = getTypeList(*lex, funcsp, &funcparams.arguments); lst = funcparams.arguments; while (lst) { lst->tp = PerformDeferredInitialization(lst->tp, NULL); lst = lst->next; } if (funcparams.arguments) { TYPE *tp2 = funcparams.arguments->tp; if (isarray(tp2)) { while (isarray(tp2) && tp2->size != 0) tp2 = tp2->btp; if (isarray(tp2)) { tp2 = FALSE; } } if (tp2) { if (isarithmetic(tp2) || ispointer(tp2) || basetype(tp2)->type == bt_enum) { if (!funcparams.arguments->next) { rv = TRUE; } else if (!funcparams.arguments->next->next) { rv = comparetypes(tp2, funcparams.arguments->next->tp, TRUE); } } else if (isref(tp2)) { if (funcparams.arguments->next && !funcparams.arguments->next->next) { rv = comparetypes(tp2, funcparams.arguments->next->tp, TRUE); } } else if (isstructured(tp2)) { TYPE *ctp = tp2; EXPRESSION *cexp = NULL; SYMBOL *cons = search(overloadNameTab[CI_CONSTRUCTOR], basetype(tp2)->syms); funcparams.thisptr = intNode(en_c_i, 0); funcparams.thistp = Alloc(sizeof(TYPE)); funcparams.thistp->type = bt_pointer; funcparams.thistp->btp = basetype(tp2); funcparams.thistp->size = getSize(bt_pointer); funcparams.ascall = TRUE; funcparams.arguments = funcparams.arguments->next; rv = GetOverloadedFunction(tp, &funcparams.fcall, cons, &funcparams, NULL, FALSE, FALSE, FALSE, _F_SIZEOF) != NULL; } } } *exp = intNode(en_c_i, rv); *tp = &stdint; return TRUE; }
/** * Constructs and returns an array of byte flags with one element for each struct in oldsdna, * indicating how it compares to newsdna: */ const char *DNA_struct_get_compareflags(const SDNA *oldsdna, const SDNA *newsdna) { int a, b; const short *sp_old, *sp_new; const char *str1, *str2; char *compflags; if (oldsdna->nr_structs == 0) { printf("error: file without SDNA\n"); return NULL; } compflags = MEM_callocN(oldsdna->nr_structs, "compflags"); /* we check all structs in 'oldsdna' and compare them with * the structs in 'newsdna' */ unsigned int newsdna_index_last = 0; for (a = 0; a < oldsdna->nr_structs; a++) { sp_old = oldsdna->structs[a]; /* search for type in cur */ int sp_new_index = DNA_struct_find_nr_ex(newsdna, oldsdna->types[sp_old[0]], &newsdna_index_last); /* The next indices will almost always match */ newsdna_index_last++; if (sp_new_index != -1) { sp_new = newsdna->structs[sp_new_index]; /* initial assumption */ compflags[a] = SDNA_CMP_NOT_EQUAL; /* compare length and amount of elems */ if (sp_new[1] == sp_old[1]) { if (newsdna->typelens[sp_new[0]] == oldsdna->typelens[sp_old[0]]) { /* same length, same amount of elems, now per type and name */ b = sp_old[1]; sp_old += 2; sp_new += 2; while (b > 0) { str1 = newsdna->types[sp_new[0]]; str2 = oldsdna->types[sp_old[0]]; if (strcmp(str1, str2) != 0) break; str1 = newsdna->names[sp_new[1]]; str2 = oldsdna->names[sp_old[1]]; if (strcmp(str1, str2) != 0) break; /* same type and same name, now pointersize */ if (ispointer(str1)) { if (oldsdna->pointerlen != newsdna->pointerlen) break; } b--; sp_old += 2; sp_new += 2; } if (b == 0) { /* no differences found */ compflags[a] = SDNA_CMP_EQUAL; } } } } } /* first struct in util.h is struct Link, this is skipped in compflags (als # 0). * was a bug, and this way dirty patched! Solve this later.... */ compflags[0] = SDNA_CMP_EQUAL; /* Because structs can be inside structs, we recursively * set flags when a struct is altered */ for (a = 0; a < oldsdna->nr_structs; a++) { if (compflags[a] == SDNA_CMP_NOT_EQUAL) { recurs_test_compflags(oldsdna, compflags, a); } } #if 0 for (a = 0; a < oldsdna->nr_structs; a++) { if (compflags[a] == SDNA_CMP_NOT_EQUAL) { spold = oldsdna->structs[a]; printf("changed: %s\n", oldsdna->types[spold[0]]); } } #endif return compflags; }
BOOLEAN comparetypes(TYPE *typ1, TYPE *typ2, int exact) { if (typ1->type == bt_any || typ2->type == bt_any) return TRUE; while (typ1->type == bt_typedef) typ1 = basetype(typ1); while (typ2->type == bt_typedef) typ2 = basetype(typ2); typ1 = replaceTemplateSelector(typ1); typ2 = replaceTemplateSelector(typ2); if (isDerivedFromTemplate(typ1)) typ1 = typ1->btp; if (isDerivedFromTemplate(typ2)) typ2 = typ2->btp; while (isref(typ1)) typ1 = basetype(typ1)->btp; while (isref(typ2)) typ2 = basetype(typ2)->btp; while (typ1->type == bt_typedef) typ1 = basetype(typ1); while (typ2->type == bt_typedef) typ2 = basetype(typ2); if (typ1->type == bt_templateselector && typ2->type == bt_templateselector) return templateselectorcompare(typ1->sp->templateSelector, typ2->sp->templateSelector); if (typ1->type == bt_templatedecltype && typ2->type == bt_templatedecltype) return templatecompareexpressions(typ1->templateDeclType, typ2->templateDeclType); if (ispointer(typ1) && ispointer(typ2)) { if (exact) { int arr = FALSE; int first = TRUE; while (ispointer(typ1) && ispointer(typ2)) { if (!first && (exact == 1)) if ((isconst(typ2) && !isconst(typ1)) || (isvolatile(typ2) && !isvolatile(typ1))) return FALSE; first = FALSE; typ1 = basetype(typ1); typ2 = basetype(typ2); if (typ1->type != typ2->type) return FALSE; if (arr && typ1->array != typ2->array) return FALSE; if (arr && typ1->size != typ2->size) return FALSE; arr |= typ1->array | typ2->array; typ1 = typ1->btp; typ2 = typ2->btp; } if (exact == 1 && ((isconst(typ2) && !isconst(typ1)) || (isvolatile(typ2) && !isvolatile(typ1)))) return FALSE; return comparetypes(typ1, typ2, TRUE); } else return TRUE; } typ1 = basetype(typ1); typ2 = basetype(typ2); if (exact && (isfunction(typ1) || isfuncptr(typ1)) && (isfunction(typ2) || isfuncptr(typ2))) { HASHREC *hr1; HASHREC *hr2; typ1 = basetype(typ1); typ2 = basetype(typ2); if (ispointer(typ1)) typ1 = basetype(typ1)->btp; if (ispointer(typ2)) typ2 = basetype(typ2)->btp; if (!comparetypes(typ1->btp, typ2->btp, exact)) return FALSE; if (!matchOverload(typ1, typ2, TRUE)) return FALSE; return TRUE; } if (cparams.prm_cplusplus) { if (typ1->scoped != typ2->scoped) return FALSE; if (typ1->type == bt_enum) { if (typ2->type == bt_enum) return typ1->sp == typ2->sp; else return isint(typ2); } else if (typ2->type == bt_enum) { return isint(typ1); } if (typ1->type == typ2->type && typ1->type == bt_memberptr) { if (typ1->sp != typ2->sp) { if (classRefCount(typ1->sp, typ2->sp) != 1) return FALSE; } return comparetypes(typ1->btp, typ2->btp, exact); } } if (typ1->type == typ2->type && (isstructured(typ1) || (exact && typ1->type == bt_enum))) return typ1->sp == typ2->sp; if (typ1->type == typ2->type || (!exact && isarithmetic(typ2) && isarithmetic(typ1))) return TRUE; if (isfunction(typ1) && isfunction(typ2) && typ1->sp->linkage == typ2->sp->linkage) return TRUE; else if (!exact && ((ispointer(typ1) && (isfuncptr(typ2) || isfunction(typ2) || isint(typ2))) || (ispointer(typ2) && (isfuncptr(typ1) || isfunction(typ1) || isint(typ1))))) return (TRUE); else if (typ1->type == bt_enum && isint(typ2)) { return TRUE; } else if (typ2->type == bt_enum && isint(typ1)) { return TRUE; } return FALSE; }