int Plookup_by_addr(struct ps_prochandle *P, uintptr_t addr, char *buf, size_t size, GElf_Sym *symp) { SYMBOL_INFO *s; s = (SYMBOL_INFO *) malloc(sizeof(SYMBOL_INFO) + size-1); if (s == NULL) return -1; s->SizeOfStruct = sizeof(SYMBOL_INFO); s->MaxNameLen = size; if (SymFromAddr(P->phandle, addr, 0, s) == TRUE) { isfunction(P, s); symp->st_name = 0; symp->st_info = GELF_ST_INFO((STB_GLOBAL), (STT_FUNC)); symp->st_other = 0; symp->st_shndx = 1; symp->st_value = s->Address; symp->st_size = s->Size; strncpy(buf, s->Name, size); return 0; } return dw_lookup_by_addr(P, addr, buf, size, symp); }
BOOL CALLBACK MyEnumSymbolsCallback( SYMBOL_INFO* SymInfo, ULONG SymbolSize, PVOID UserContext ) { struct lookup_uc *tmp = (struct lookup_uc *) UserContext; GElf_Sym *symp = (GElf_Sym *) tmp->cd; if (SymInfo != NULL) { if (isfunction(tmp->ps, SymInfo)) { symp->st_name = 0; symp->st_info = GELF_ST_INFO((STB_GLOBAL), (STT_FUNC)); symp->st_other = 0; symp->st_shndx = 1; symp->st_value = SymInfo->Address; symp->st_size = SymInfo->Size; } else { symp->st_name = 0; symp->st_info = GELF_ST_INFO((STB_GLOBAL), (STT_NOTYPE)); symp->st_other = 0; symp->st_shndx = SHN_UNDEF; symp->st_value = SymInfo->Address; symp->st_size = SymInfo->Size; } } return TRUE; }
BOOL CALLBACK SymEnumSymbolsProc(PSYMBOL_INFO s, ULONG SymbolSize, PVOID UserContext) { GElf_Sym symp; struct lookup_uc *tmp = (struct lookup_uc *) UserContext; if (s != NULL) { if (isfunction(tmp->ps, s)) { symp.st_name = 0; symp.st_info = GELF_ST_INFO((STB_GLOBAL), (STT_FUNC)); symp.st_other = 0; symp.st_shndx = 1; symp.st_value = s->Address; symp.st_size = s->Size; } else { symp.st_name = 0; symp.st_info = GELF_ST_INFO((STB_GLOBAL), (STT_NOTYPE)); symp.st_other = 0; symp.st_shndx = SHN_UNDEF; symp.st_value = s->Address; symp.st_size = s->Size; } tmp->count++; tmp->f(tmp->cd, &symp, s->Name); } return TRUE; }
/* Devolve o proximo token */ void Parser::get_token (void) { register char *temp; tok_type = 0; temp = token; *temp = '\0'; if (!*prog) return; /* final da expressao */ while (isspace(*prog)) ++prog; /* ignora espacos em branco */ if (strchr("+-*/%^=()", *prog)) { tok_type = DELIMITADOR; /* avanca para o proximo char */ *temp++ = *prog++; } else if (isalpha(*prog)) { while(!isdelim(*prog)) *temp++ = toupper (*prog++); *temp = '\0'; if (isfunction (token)) tok_type = FUNCAO; else tok_type = VARIAVEL; } else if (isdigit(*prog)) { while(!isdelim(*prog)) *temp++ = *prog++; tok_type = NUMERO; } *temp = '\0'; }
EXPRESSION *doinline(FUNCTIONCALL *params, SYMBOL *funcsp) { static SYMBOL *curfunc; STATEMENT *stmt = NULL, **stp = &stmt; EXPRESSION *newExpression; BOOL allocated = FALSE; if (funcsp) curfunc = funcsp; if (!isfunction(params->functp)) return NULL; if (params->sp->linkage != lk_inline) return NULL; if (!params->sp->inlineFunc.syms) return NULL; if (!localNameSpace->syms) { allocated = TRUE; AllocateLocalContext(NULL, NULL); } stmt = SetupArguments(params); SetupVariables(params->sp); while (*stp) stp = &(*stp)->next; *stp = inlinestmt(params->sp->inlineFunc.stmt); newExpression = exprNode(en_stmt, NULL, NULL); newExpression->v.stmt = stmt; if (params->sp->retcount == 1) { /* optimization for simple inline functions that only have * one return statement, don't save to an intermediate variable */ newExpression->left = scanReturn(stmt, basetype(params->sp->tp)->btp); } else { newExpression->left = newReturn(basetype(params->sp->tp)->btp); reduceReturns(stmt, params->sp->tp->btp, newExpression->left); } if (params->sp->storage_class == sc_virtual || params->sp->storage_class == sc_member) thisptrs = thisptrs->next; if (allocated) { FreeLocalContext(NULL, NULL); } if (funcsp) curfunc = NULL; return newExpression; }
void InsertInline(SYMBOL *sp) { LIST *temp = Alloc(sizeof(LIST)); temp->data = sp; if (isfunction(sp->tp)) if (inlineHead) inlineTail = inlineTail->next = temp; else inlineHead = inlineTail = temp; else if (inlineVTabHead) inlineVTabTail = inlineVTabTail->next = temp; else inlineVTabHead = inlineVTabTail = temp; }
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; }
void identifier(){ char* name = getname(); if(!idexists(name)) error("Identifier '%s' is undeclared", name); if(look == '('){ if(!isfunction(name)) error("Cannot call variable '%s'", name); int len = 0; match("("); while(look != ')'){ expression(); emitln("push eax"); if(look != ')') match(","); len++; } match(")"); if(len != numargs(name)) error("Call to %s with wrong number of args", name); emitln("call %s", getaccessor(name)); } else { emitln("xor eax, eax"); current_type = gettype(name); STRSWITCH(current_type) STRCASE("char") emitln("mov al, byte [%s]", getaccessor(name)); STRCASE("short") emitln("mov ax, word [%s]", getaccessor(name)); STRDEFAULT emitln("mov eax, dword [%s]", getaccessor(name)); STRSWITCHEND } }
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 ismemberdata(SYMBOL *sp) { return !isfunction(sp->tp) && ismember(sp); }
BOOLEAN isfuncptr(TYPE *tp) { tp = basetype(tp); return ispointer(tp) && tp->btp && isfunction(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; }
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; }
void SetLinkerNames(SYMBOL *sym, enum e_lk linkage) { char errbuf[8192], *p = errbuf; SYMBOL *lastParent; mangledNamesCount = 0; if (linkage == lk_none || linkage == lk_cdecl) { if (cparams.prm_cplusplus) { if (sym->storage_class != sc_label && sym->storage_class != sc_parameter && sym->storage_class != sc_namespace && sym->storage_class != sc_namespacealias && sym->storage_class != sc_ulabel && (isfunction(sym->tp) || istype(sym) || sym->parentNameSpace || sym->parentClass)) linkage = lk_cpp; else linkage = lk_c; } else { linkage = lk_c; } } if (linkage == lk_auto && !cparams.prm_cplusplus) linkage = lk_c; if (linkage == lk_c && !cparams.prm_cmangle) linkage = lk_stdcall; if (linkage == lk_virtual) { if (cparams.prm_cplusplus) linkage = lk_cpp; else linkage = lk_c; } switch (linkage) { case lk_auto: p = mangleClasses(p, theCurrentFunc); sprintf(p, "@%s", sym->name); break; case lk_pascal: strcpy(errbuf, sym->name); while (*p) { *p = toupper(*p); p++; } break; case lk_stdcall: strcpy(errbuf, sym->name); break; case lk_c: default: errbuf[0] = '_'; strcpy(errbuf+1, sym->name); break; case lk_cpp: lastParent = sym; while (lastParent->parentClass) lastParent = lastParent->parentClass; p = mangleNameSpaces(p, lastParent->parentNameSpace); p = mangleClasses(p, sym->parentClass); *p++ = '@'; if (sym->templateLevel && sym->templateParams) { p = mangleTemplate(p, sym, sym->templateParams); } else { strcpy(p, sym->name); p += strlen(p); } if (isfunction(sym->tp)) { *p++ = '$'; if (sym->castoperator) { int tmplCount = 0; *p++ = 'o'; p = mangleType(p, basetype(sym->tp)->btp, TRUE); // cast operators get their cast type in the name *p++ = '$'; p = mangleType(p, sym->tp, TRUE); // add the $qv while (p > errbuf && (*--p != '$' || tmplCount)) if (*p == '~') tmplCount++; else if (*p == '#') tmplCount--; p[1] = 0; } else { p = mangleType(p, sym->tp, TRUE); // otherwise functions get their parameter list in the name // if (!sym->templateLevel) { int tmplCount = 0; while (p > errbuf && (*--p != '$' || tmplCount)) if (*p == '~') tmplCount++; else if (*p == '#') tmplCount--; if (basetype(sym->tp)->btp->type == bt_memberptr) { while (p > errbuf && (*--p != '$' || tmplCount)) if (*p == '~') tmplCount++; else if (*p == '#') tmplCount--; } p[1] = 0; } } } *p = 0; break; } sym->decoratedName = sym->errname = litlate(errbuf); }
char *mangleType (char *in, TYPE *tp, BOOLEAN first) { char nm[4096]; int i; HASHREC *hr ; if(!tp) { sprintf(in, "%d%s", strlen("initializer-list"), "initializer-list"); in += strlen(in); } else if (tp->type == bt_typedef) { in = mangleType(in, tp->btp, FALSE); } else if (isstructured(tp) && basetype(tp)->sp->templateLevel) { { if (isconst(tp)) *in++ = 'x'; if (isvolatile(tp)) *in++ = 'y'; if (islrqual(tp)) *in++ = 'r'; if (isrrqual(tp)) *in++ = 'R'; } in = mangleTemplate(in, basetype(tp)->sp, basetype(tp)->sp->templateParams); } else { // if (ispointer(tp) || isref(tp)) // { // if (basetype(tp)->btp) // { // if (isconst(basetype(tp)->btp)) // *in++ = 'x'; // if (isvolatile(basetype(tp)->btp)) // *in++ = 'y'; // } // } // if (isfunction(tp)) { if (isconst(tp)) *in++ = 'x'; if (isvolatile(tp)) *in++ = 'y'; if (islrqual(tp)) *in++ = 'r'; if (isrrqual(tp)) *in++ = 'R'; } tp = basetype(tp); switch (tp->type) { /* case bt_templateplaceholder: tplPlaceholder(nm, tp->lst.head->name, tp->lst.tail); sprintf(buf, "%d%s", strlen(nm), nm); buf += strlen(buf); break; */ case bt_func: case bt_ifunc: if (basetype(tp)->sp && basetype(tp)->sp->parentClass && !first) { *in++ = 'M'; in = getName(in, tp->sp->parentClass); in += strlen(in); } *in++ = 'q'; hr = tp->syms->table[0]; while (hr) { SYMBOL *sp = (SYMBOL *)hr->p; if (!sp->thisPtr) in = mangleType(in, sp->tp, TRUE); hr = hr->next ; } *in++ = '$'; // return value in = mangleType(in, tp->btp, TRUE); break; case bt_memberptr: *in++ = 'M'; in = getName(in, tp->sp); if (isfunction(tp->btp)) { *in++ = 'q'; hr = basetype(tp->btp)->syms->table[0]; while (hr) { SYMBOL *sp = (SYMBOL *)hr->p; if (!sp->thisPtr) in = mangleType(in, sp->tp, TRUE); hr = hr->next ; } *in++ = '$'; in = mangleType (in, tp->btp->btp, TRUE); } else { *in++ = '$'; in = mangleType (in, basetype(tp)->btp, TRUE); } break; case bt_enum: case bt_struct: case bt_union: case bt_class: in = getName(in, tp->sp); break; case bt_bool: in = lookupName(in, "bool"); in += strlen(in); break; case bt_unsigned_short: *in++ = 'u'; case bt_short: *in++ = 's'; break; case bt_unsigned: *in++ = 'u'; case bt_int: *in++ = 'i'; break; case bt_char16_t: *in++ = 'h'; break; case bt_char32_t: *in++ = 'H'; break; case bt_unsigned_long: *in++ = 'u'; case bt_long: *in++ = 'l'; break; case bt_unsigned_long_long: *in++ = 'u'; case bt_long_long: *in++ = 'L'; break; case bt_unsigned_char: *in++ = 'u'; case bt_char: *in++ = 'c'; break; case bt_signed_char: *in++ = 'S'; *in++ = 'c'; break; case bt_wchar_t: *in++ = 'C'; break; case bt_float_complex: *in++ = 'F'; break; case bt_double_complex: *in++ = 'D'; break; case bt_long_double_complex: *in++ = 'G'; break; case bt_float: *in++ = 'f'; break; case bt_double: *in++ = 'd'; break; case bt_long_double: *in++ = 'g'; break; case bt_pointer: if (tp->nullptrType) { in = lookupName(in, "nullptr_t"); in += strlen(in); } else { if (first|| !tp->array) { *in++ = 'p'; } else { sprintf(in,"A%ld",tp->btp->size ? tp->size / tp->btp->size : 0); in += strlen(in); } in = mangleType(in, tp->btp, FALSE); } break; case bt_far: *in++ = 'P'; in = mangleType(in, tp->btp, FALSE); break; case bt_lref: *in++ = 'r'; in = mangleType(in, tp->btp, FALSE); break; case bt_rref: *in++ = 'R'; in = mangleType(in, tp->btp, FALSE); break; case bt_ellipse: *in++ = 'e'; break; case bt_void: case bt_any: *in++ = 'v'; break; case bt_templateparam: in = getName(in, tp->templateParam->p->sym); break; case bt_templateselector: { TEMPLATESELECTOR *s = tp->sp->templateSelector; char *p; s = s->next; if (s->isTemplate) p = mangleTemplate(nm, s->sym, s->templateParams); else p = getName(nm, s->sym); p[0] =0; if (strlen(nm) > sizeof(nm)) p = mangleTemplate(nm, s->sym, s->templateParams); s = s->next ; while (s) { strcat(nm , "@"); strcat(nm , s->name); s= s->next; } p = nm; while (isdigit(*p)) p++; sprintf(in, "%d%s", strlen(p), p); in += strlen(in); } break; case bt_templatedecltype: // the index is being used to make names unique so two decltypes won't collide when storing them // in a symbol table... declTypeIndex = (declTypeIndex + 1) %1000; *in++ = 'E'; sprintf(in, "%03d", declTypeIndex); in += 3; break; case bt_aggregate: in = getName(in, tp->sp); break; default: diag("mangleType: unknown type"); break; } } *in= 0; return in; }
static char * mangleExpressionInternal (char *buf, EXPRESSION *exp) { while (castvalue(exp)) exp = exp->left; if (isintconst(exp)) { if (exp->type == en_const) { sprintf(buf, "%lld&", exp->v.sp->value.i); } else { sprintf(buf, "%lld&", exp->v.i); } if (buf[0] == '-') buf[0] = '_'; } else { BOOLEAN nonpointer = FALSE; while (lvalue(exp)) { nonpointer = TRUE; exp = exp->left; } switch (exp->type) { case en_nullptr: *buf++ = 'n'; *buf = 0; break; case en_arrayadd: case en_structadd: case en_add: *buf++ = 'p'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_sub: *buf++ = 's'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_mul: case en_umul: case en_arraymul: *buf++ = 'm'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_umod: case en_mod: *buf++ = 'o'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_div: case en_udiv: case en_arraydiv: *buf++ = 'd'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_lsh: case en_arraylsh: *buf++ = 'h'; *buf++ = 'l'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_rsh: case en_ursh: *buf++ = 'h'; *buf++ = 'r'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_cond: *buf++ = 'C'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right->left); buf = mangleExpressionInternal(buf, exp->right->right); *buf = 0; break; case en_assign: *buf++ = 'a'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_eq: *buf++ = 'c'; *buf++ = 'e'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_ne: *buf++ = 'c'; *buf++ = 'n'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_uminus: *buf++ = 'u'; buf = mangleExpressionInternal(buf, exp->left); break; case en_not: *buf++ = 'l'; *buf++ = 'n'; buf = mangleExpressionInternal(buf, exp->left); break; case en_compl: *buf++ = 'b'; *buf++ = 'n'; buf = mangleExpressionInternal(buf, exp->left); *buf = 0; break; case en_ascompl: *buf++ = 'a'; *buf++ = 'n'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_ult: case en_lt: *buf++ = 'c'; *buf++ = 'l'; *buf++ = 't'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_ule: case en_le: *buf++ = 'c'; *buf++ = 'l'; *buf++ = 'e'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_ugt: case en_gt: *buf++ = 'c'; *buf++ = 'g'; *buf++ = 't'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_uge: case en_ge: *buf++ = 'c'; *buf++ = 'g'; *buf++ = 'e'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_and: *buf++ = 'b'; *buf++ = 'a'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_land: *buf++ = 'l'; *buf++ = 'a'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_or: *buf++ = 'b'; *buf++ = 'o'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_lor: *buf++ = 'l'; *buf++ = 'o'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_xor: *buf++ = 'b'; *buf++ = 'x'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_autoinc: *buf++ = 'i'; *buf++ = 'p'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_autodec: *buf++ = 'i'; *buf++ = 's'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_templateselector: { TEMPLATESELECTOR *tsl = exp->v.templateSelector, *find = tsl->next->next; SYMBOL *ts = tsl->next->sym; *buf++ = 't'; *buf++ = 's'; if (tsl->next->isTemplate && tsl->next->templateParams) // may be an empty variadic { buf = mangleTemplate(buf, ts, tsl->next->templateParams); } while (find) { *buf++ = 't'; buf = lookupName(buf, find->name); find = find->next; } *buf = 0; break; } case en_templateparam: *buf++ = 't'; *buf++ = 'p'; buf = lookupName(buf,exp->v.sp->name); *buf = 0; break; case en_funcret: buf = mangleExpressionInternal(buf, exp->left); *buf = 0; break; case en_func: if (exp->v.func->ascall) { INITLIST *args = exp->v.func->arguments; *buf++ = 'f'; buf = lookupName(buf, exp->v.func->sp->name); while(args) { *buf++='f'; buf = mangleExpressionInternal(buf, args->exp); args = args->next; } } else { *buf++ = 'e'; *buf++ = '&'; strcpy(buf, exp->v.func->sp->name); buf += strlen(buf); *buf++ = '$'; buf = mangleType( buf, exp->v.func->sp->tp, TRUE); } break; case en_pc: case en_global: case en_label: case en_const: if (isfunction(exp->v.sp->tp)) { *buf++ = 'e'; *buf++ = '&'; strcpy(buf, exp->v.sp->name); buf += strlen(buf); *buf++ = '$'; buf = mangleType( buf, exp->v.sp->tp, TRUE); } else { *buf++ = 'g'; if (!nonpointer) *buf++ = '&'; strcpy(buf, exp->v.sp->name); *buf++ = '$'; *buf = 0; } break; default: *buf = 0; break; } } buf += strlen(buf); return buf; }
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; }
void link_extendedtype(TYPE *tp1) { TYPE *tp = basetype(tp1); if (tp->type == bt_pointer) { if (tp->vla) { int m = link_puttype(tp->btp); tp1->dbgindex = emit_type_ieee("T7,%X,T%X,T2A",tp->size,m); } else if (tp->array) { int m = link_puttype(tp->btp); tp1->dbgindex = emit_type_ieee("T6,%X,T%X,T2A,%d,%d",tp->size,m,0,tp->size/basetype(tp)->btp->size); } else { int m = link_puttype(tp->btp); tp1->dbgindex = emit_type_ieee("T1,%X,T%X",tp->size,m); } } else if (isfunction(tp)) { tp1->dbgindex = dumpFunction(tp); } else { int n = tp1->dbgindex = typeIndex++; if (tp->hasbits) { int m = link_BasicType(tp); emit_record_ieee("ATT%X,T3,%X,T%X,%d,%d.\r\n",n, tp->size, m, tp->startbit, tp->bits); } else if (isstructured(tp)) { int sel; if (tp->type == bt_union) { sel = 5; } else { sel = 4; } if (tp->syms) dumpStructFields(sel, n, tp->size, tp->syms->table[0]); else dumpStructFields(sel, n, tp->size, NULL); emit_record_ieee("NT%X,%02X%s.\r\n", n, strlen(tp->sp->name), tp->sp->name); } else if (tp->type == bt_ellipse) { // ellipse results in no debug info } else // enum { int m; if (tp->type == bt_enum) if (tp->btp) m = link_BasicType(tp->btp); else m = 42; else m = link_BasicType(tp); if (tp->syms) dumpEnumFields(8, n, m, tp->size, tp->syms->table[0]); else dumpEnumFields(8, n, m, tp->size, NULL); emit_record_ieee("NT%X,%02X%s.\r\n", n, strlen(tp->sp->name), tp->sp->name); } } }
TYPE *typenum(char *buf, TYPE *tp) { SYMBOL *sp; HASHREC *hr; char name[4096]; if (tp == NULL) { diag("typenum - NULL type"); return &stdvoid; } if (tp->type == bt_derivedfromtemplate) tp = tp->btp; tp = enumConst(buf, tp); if (!tp) return NULL; buf += strlen(buf); switch (tp->type) { case bt_typedef: strcpy(buf, tp->sp->name); break; case bt_aggregate: if (!tp->syms) break; hr = tp->syms->table[0]; sp = (SYMBOL *)hr->p; if (hr->next || !strcmp(sp->name, tp->sp->name)) // the tail is to prevent a problem when there are a lot of errors { strcpy(buf," (*)(\?\?\?)"); break; } tp = sp->tp; /* fall through */ case bt_func: case bt_ifunc: typenum(buf, tp->btp); buf = buf + strlen(buf); if (tp->syms) { hr = tp->syms->table[0]; if (hr && hr->p) { if (((SYMBOL *)hr->p)->thisPtr) { SYMBOL *thisptr = (SYMBOL *)hr->p; *buf++ = ' '; *buf++='('; getcls(buf, basetype (basetype(thisptr->tp)->btp)->sp); strcat(buf, "::*)("); buf += strlen(buf); hr = hr->next; } else { strcat(buf," (*)("); buf += strlen(buf); } } else { strcat(buf," (*)("); buf += strlen(buf); } while (hr) { sp = (SYMBOL *)hr->p; *buf = 0; typenum(buf, sp->tp); buf = buf + strlen(buf); hr = hr->next; if (hr) *buf++ = ','; } } else { strcat(buf," (*)("); buf += strlen(buf); } *buf++ = ')'; *buf = 0; break; case bt_float_complex: strcpy(buf, tn_floatcomplex); break; case bt_double_complex: strcpy(buf, tn_doublecomplex); break; case bt_long_double_complex: strcpy(buf, tn_longdoublecomplex); break; case bt_float_imaginary: strcpy(buf, tn_floatimaginary); break; case bt_double_imaginary: strcpy(buf, tn_doubleimaginary); break; case bt_long_double_imaginary: strcpy(buf, tn_longdoubleimaginary); break; case bt_float: strcpy(buf, tn_float); break; case bt_double: strcpy(buf, tn_double); break; case bt_long_double: strcpy(buf, tn_longdouble); break; case bt_unsigned: strcpy(buf, tn_unsigned); buf = buf + strlen(buf); case bt_int: strcpy(buf, tn_int); break; case bt_char16_t: strcpy(buf, tn_char16_t); break; case bt_char32_t: strcpy(buf, tn_char32_t); break; case bt_unsigned_long_long: strcpy(buf, tn_unsigned); buf = buf + strlen(buf); case bt_long_long: strcpy(buf, tn_longlong); break; case bt_unsigned_long: strcpy(buf, tn_unsigned); buf = buf + strlen(buf); case bt_long: strcpy(buf, tn_long); break; case bt_wchar_t: strcpy(buf, tn_wchar_t); break; case bt_unsigned_short: strcpy(buf, tn_unsigned); buf = buf + strlen(buf); case bt_short: strcpy(buf, tn_short); break; case bt_signed_char: strcpy(buf, tn_signed); buf = buf + strlen(buf); strcpy(buf, tn_char); break; case bt_unsigned_char: strcpy(buf, tn_unsigned); buf = buf + strlen(buf); case bt_char: strcpy(buf, tn_char); break; case bt_bool: strcpy(buf, tn_bool); break; case bt_bit: strcpy(buf, "bit"); break; case bt_void: strcpy(buf, tn_void); break; case bt_pointer: if (tp->nullptrType) { strcpy(buf, "nullptr_t"); } else { typenumptr(buf, tp); } break; case bt_memberptr: if (isfunction(basetype(tp)->btp)) { TYPE *func = basetype(tp)->btp; typenum(buf, basetype(func)->btp); strcat(buf, " ("); buf += strlen(buf); getcls(buf, tp->sp); buf += strlen(buf); strcpy(buf, "::*)("); buf += strlen(buf); if (basetype(func)->syms) { hr = basetype(func)->syms->table[0]; while (hr) { sp = (SYMBOL *)hr->p; *buf = 0; typenum(buf, sp->tp); buf = buf + strlen(buf); hr = hr->next; if (hr) *buf++ = ','; } } *buf++ = ')'; *buf = 0; } else { typenum(buf, tp->btp); strcat(buf, " "); buf += strlen(buf); getcls(buf, tp->sp); buf += strlen(buf); strcpy(buf, "::*"); } break; case bt_seg: typenum(buf, tp->btp); buf += strlen(buf); strcpy(buf, " _seg *"); break; case bt_lref: typenum(buf, tp->btp); buf += strlen(buf); *buf++ = ' '; *buf++ = '&'; *buf = 0; break; case bt_rref: typenum(buf, tp->btp); buf += strlen(buf); *buf++ = ' '; *buf++ = '&'; *buf++ = '&'; *buf = 0; break; case bt_ellipse: strcpy(buf, tn_ellipse); break; case bt_any: strcpy(buf, "???"); break; case bt_class: /* strcpy(buf, tn_class); */ unmangle(name, tp->sp->errname ? tp->sp->errname : tp->sp->name); strcpy(buf, name); break; case bt_struct: /* strcpy(buf, tn_struct); */ unmangle(name, tp->sp->errname ? tp->sp->errname : tp->sp->name); strcpy(buf, name); break; case bt_union: /* strcpy(buf, tn_union); */ unmangle(name, tp->sp->errname ? tp->sp->errname : tp->sp->name); strcpy(buf, name); break; case bt_enum: /* strcpy(buf, tn_enum); */ unmangle(name, tp->sp->errname ? tp->sp->errname : tp->sp->name); strcpy(buf, name); break; case bt_templateselector: { TEMPLATESELECTOR *ts = tp->sp->templateSelector->next; if (ts->sym) { strcpy(buf, ts->sym->name); ts = ts->next; while (ts) { strcat(buf, "::"); strcat(buf, ts->name); ts = ts->next; } } break; } case bt_templatedecltype: RenderExpr(buf, tp->templateDeclType); break; case bt_auto: strcpy(buf, "auto "); break; default: strcpy(buf, "\?\?\?"); } return 0; }