Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
/* 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';
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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

	}
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
BOOLEAN ismemberdata(SYMBOL *sp)
{
    return !isfunction(sp->tp) && ismember(sp);
}
Exemplo n.º 11
0
BOOLEAN isfuncptr(TYPE *tp)
{
    tp = basetype(tp);
    return ispointer(tp) && tp->btp && isfunction(tp->btp);
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
0
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);
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
0
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);
        }
    }
}
Exemplo n.º 19
0
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;
}