BOOLEAN matchOverload(TYPE *tnew, TYPE *told) { HASHREC *hnew = basetype(tnew)->syms->table[0]; HASHREC *hold = basetype(told)->syms->table[0]; // if (snew->templateLevel != sold->templateLevel) // return FALSE; if (isconst(tnew) != isconst(told)) return FALSE; while (hnew && hold) { SYMBOL *snew = (SYMBOL *)hnew->p; SYMBOL *sold = (SYMBOL *)hold->p; if (sold->thisPtr) { hold = hold->next; if (!hold) break; sold = hold->p; } if (snew->thisPtr) { hnew = hnew->next; if (!hnew) break; snew = hnew->p; } if (snew->tp->type == bt_templateparam) { if (sold->tp->type != bt_templateparam || snew->tp->templateParam->p->type != sold->tp->templateParam->p->type || snew->tp->templateParam->p->type != kw_typename || (snew->tp->templateParam->p->byClass.dflt || sold->tp->templateParam->p->byClass.dflt) && (!snew->tp->templateParam->p->byClass.dflt || !sold->tp->templateParam->p->byClass.dflt || !comparetypes(sold->tp->templateParam->p->byClass.dflt, snew->tp->templateParam->p->byClass.dflt, TRUE))) break; } else if (sold->tp->type == bt_any || snew->tp->type == bt_any) // packed template param break; else if (!comparetypes(sold->tp, snew->tp, TRUE) && !sameTemplate(sold->tp, snew->tp) || basetype(sold->tp)->type != basetype(snew->tp)->type) break; else { TYPE *tps = sold->tp; TYPE *tpn = snew->tp; if (isref(tps)) tps = basetype(tps)->btp; if (isref(tpn)) tpn = basetype(tpn)->btp; if (isconst(tpn) != isconst(tps) || isvolatile(tpn) != isvolatile(tps)) break; } hold = hold->next; hnew = hnew->next; } if (!hold && !hnew) return TRUE; return NULL; }
static BOOLEAN isStandardLayout(TYPE *tp, SYMBOL **result) { if (isstructured(tp) && !hasVTab(basetype(tp)->sp) && !basetype(tp)->sp->vbaseEntries ) { int n; int access = -1; SYMBOL *found = NULL, *first; HASHREC *hr; n = FindBaseClassWithData(tp->sp, &found); if (n > 1) return FALSE; if (n) { SYMBOL *first = NULL; hr = basetype(found->tp)->syms->table[0]; while (hr) { SYMBOL *sp = (SYMBOL *)hr->p; if (!first) first = sp; if (sp->storage_class == sc_member || sp->storage_class == sc_mutable) { if (isstructured(sp->tp) && !isStandardLayout(sp->tp, NULL)) return FALSE; if (access != -1) { if (access != sp->access) return FALSE; } access = sp->access; } hr = hr->next; } if (first && isstructured(first->tp)) { BASECLASS *bc = found->baseClasses; while (bc) { if (comparetypes(bc->cls->tp, first->tp, TRUE)) return FALSE; bc = bc->next; } } } if (result) *result = found; return TRUE; } return FALSE; /* hasnonon-staticdatamembersoftypenon-standard-layoutclass(orarrayofsuchtypes)orreference, — has no virtual functions (10.3) and no virtual base classes (10.1), — has the same access control (Clause 11) for all non-static data members, — has no non-standard-layout base classes, — either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and — has no base classes of the same type as the ?rst non-static data member. */ }
BOOL checktypeassign(TYPE *typ1, TYPE *typ2) { /* this is so we can put an ampersand in front of a func name we are using */ if (isfuncptr(typ1) && isfuncptr(typ2)) return TRUE; while (typ1 && typ2) { typ1 = basetype(typ1); typ2 = basetype(typ2); if (isarithmetic(typ1) && isarithmetic(typ2)) return TRUE; if (isstructured(typ1) && comparetypes(typ1, typ2, TRUE)) return TRUE; typ1 = typ1->btp; typ2 = typ2->btp; } if (!typ1 && !typ2) return (TRUE); return (FALSE); }
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; }
static BOOLEAN is_convertible_to(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp) { BOOLEAN rv = TRUE; FUNCTIONCALL funcparams; memset(&funcparams, 0, sizeof(funcparams)); funcparams.sp = sym; *lex = getTypeList(*lex, funcsp, &funcparams.arguments); if (funcparams.arguments && funcparams.arguments->next && !funcparams.arguments->next->next) { TYPE *from = funcparams.arguments->tp; TYPE *to = funcparams.arguments->next->tp; if (isref(from) && isref(to)) { if (basetype(to)->type == bt_lref) { if (basetype(from)->type == bt_rref) rv = FALSE; } } else if (isref(from)) rv = FALSE; if (isfunction(from)) from = basetype(from)->btp; if (rv) { while (isref(from)) from = basetype(from)->btp; while (isref(to)) to = basetype(to)->btp; rv = comparetypes(to, from, FALSE); if (!rv && isstructured(from) && isstructured(to)) { if (classRefCount(basetype(to)->sp, basetype(from)->sp) == 1) rv = TRUE; } if (!rv && isstructured(from)) { SYMBOL *sp = search("$bcall", basetype(from)->syms); if (sp) { HASHREC *hr = sp->tp->syms->table[0]; while (hr) { if (comparetypes(basetype(((SYMBOL *)hr->p)->tp)->btp, to, FALSE)) { rv= TRUE; break; } hr = hr->next; } } } } } else { rv = FALSE; } *exp = intNode(en_c_i, rv); *tp = &stdint; return TRUE; }
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; }
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; }