static void DoDumpType( TYPEPTR realtype, const char *symname, STRCHUNK *pch ) { type_modifiers pointer_flags; TYPEPTR typ; realtype = TrueType( realtype ); DumpBaseType( realtype, pch ); DumpDecl( realtype, NULL, pch ); if( symname ) ChunkSaveStr( pch, symname ); if( realtype->decl_type == TYPE_POINTER ) { if( realtype->u.p.decl_flags & FLAG_WAS_ARRAY ) { typ = Object( realtype ); if( typ->decl_type != TYPE_ARRAY ) { ChunkSaveStr( pch, "[]" ); } } } for( typ = realtype; typ != NULL; typ = Object( typ ) ) { if( typ->decl_type == TYPE_TYPEDEF ) break; pointer_flags = 0; while( typ->decl_type == TYPE_POINTER ) { pointer_flags = typ->u.p.decl_flags; typ = Object( typ ); } if( typ->decl_type == TYPE_ARRAY || typ->decl_type == TYPE_FUNCTION ) { DumpTail( realtype, NULL, pointer_flags, pch ); break; } } }
static void DumpArray( TYPEPTR typ, STRCHUNK *pch ) { target_size size; char tempbuf[20]; while( typ->decl_type == TYPE_ARRAY ) { size = typ->u.array->dimension; if( size != 0 ) { sprintf( tempbuf, "[%u]", (unsigned)size ); ChunkSaveStr( pch, tempbuf ); } else { ChunkSaveStr( pch, "[]" ); } typ = Object( typ ); } }
static void DumpParmList( TYPEPTR *parm, SYMPTR funcsym, STRCHUNK *pch ) { TYPEPTR typ; int parm_num; SYM_HANDLE sym_handle; SYM_ENTRY sym; char *sym_name; char temp_name[20]; if( parm == NULL ) { ChunkSaveStr( pch, "void" ); } else { parm_num = 1; if( funcsym != NULL ) { sym_handle = funcsym->u.func.parms; } else { sym_handle = 0; } for( ;; ) { typ = *parm; if( typ == NULL ) break; typ = TrueType( typ ); if( funcsym != NULL ) { if( funcsym->flags & SYM_OLD_STYLE_FUNC ) { typ = DefArgPromotion( typ ); } } sym_name = NULL; if( sym_handle != 0 ) { SymGet( &sym, sym_handle ); sym_handle = sym.handle; sym_name = sym.name; } else { if( typ->decl_type != TYPE_VOID && typ->decl_type != TYPE_DOT_DOT_DOT ) { sym_name = temp_name; sprintf( temp_name, "__p%d", parm_num ); } } DoDumpType( typ, sym_name, pch ); ++parm; if( *parm != NULL ) { ChunkSaveChar( pch, ',' ); } ++parm_num; } } }
static void DumpDecl( TYPEPTR typ, SYMPTR funcsym, STRCHUNK *pch ) { TYPEPTR obj; type_modifiers flags; switch( typ->decl_type ) { case TYPE_FUNCTION: DumpDecl( Object( typ ), NULL, pch ); if ( funcsym ) { flags = funcsym->mods; if( flags & FLAG_LOADDS ) put_keyword( T___LOADDS, pch ); if( flags & FLAG_EXPORT ) put_keyword( T___EXPORT, pch ); if( flags & FLAG_SAVEREGS) put_keyword( T___SAVEREGS, pch ); flags &= ~(FLAG_LOADDS | FLAG_EXPORT | FLAG_SAVEREGS); DumpFlags( flags, typ, pch ); ChunkSaveStr( pch, funcsym->name ); } case TYPE_ARRAY: DumpTail( typ, funcsym, FLAG_NONE, pch ); break; case TYPE_POINTER: obj = Object( typ ); while( obj->decl_type == TYPE_POINTER ) obj = Object( obj ); switch( obj->decl_type ) { case TYPE_FUNCTION: DumpDecl( Object( obj ), NULL, pch ); ChunkSaveChar( pch, '(' ); break; case TYPE_ARRAY: while( obj->decl_type == TYPE_ARRAY ) obj = Object( obj ); DumpDecl( obj, NULL, pch ); ChunkSaveChar( pch, '(' ); break; default: break; } DumpPointer( typ, pch ); break; default: break; } }
static void DumpTail( TYPEPTR typ, SYMPTR funcsym, type_modifiers pointer_flags, STRCHUNK *pch ) { TYPEPTR top_typ; TYPEPTR obj; top_typ = typ; for( ;; ) { if( typ->decl_type == TYPE_FUNCTION ) { ChunkSaveChar( pch, '(' ); if( typ == top_typ || typ->u.fn.parms != NULL ) { DumpParmList( typ->u.fn.parms, funcsym, pch); funcsym = NULL; } ChunkSaveChar( pch, ')' ); } typ = Object( typ ); while( typ->decl_type == TYPE_POINTER ) { typ = Object( typ ); } if( typ->decl_type == TYPE_ARRAY ) { ChunkSaveChar( pch, ')' ); if( pointer_flags & FLAG_WAS_ARRAY ) { /* we don't know the dimension anymore. just put out [1] */ ChunkSaveStr( pch, "[1]" ); pointer_flags = 0; } DumpArray( typ, pch) ; for( ;; ) { obj = Object( typ ); if( obj->decl_type != TYPE_ARRAY ) break; typ = obj; } } else { if( typ->decl_type != TYPE_FUNCTION ) break; ChunkSaveChar( pch, ')' ); } } }
static void DumpFlags( type_modifiers flags, TYPEPTR typ, STRCHUNK *fp ) { SYM_NAMEPTR p; SYM_ENTRY sym; if( flags & FLAG_VOLATILE ) put_keyword( T_VOLATILE, fp ); if( flags & FLAG_CONST ) put_keyword( T_CONST, fp ); if( flags & FLAG_UNALIGNED ) put_keyword( T___UNALIGNED, fp ); if( flags & FLAG_RESTRICT ) put_keyword( T_RESTRICT, fp ); if( flags & FLAG_LOADDS ) put_keyword( T___LOADDS, fp ); if( flags & FLAG_EXPORT ) put_keyword( T___EXPORT, fp ); if( flags & FLAG_SAVEREGS ) put_keyword( T___SAVEREGS, fp ); if( ( flags & FLAG_INTERRUPT ) == FLAG_INTERRUPT ) { put_keyword( T___INTERRUPT, fp ); } else if( flags & FLAG_NEAR ) { if( flags & FLAG_BASED ) { ChunkSaveStr( fp, "__based(" ); if( typ->u.p.based_sym == SYM_NULL ) { ChunkSaveStr( fp, "void" ); } else { SymGet( &sym, typ->u.p.based_sym ); p = SymName( &sym, typ->u.p.based_sym ); ChunkSaveStr( fp, p ); } ChunkSaveStr( fp, ") " ); } else { put_keyword( T___NEAR, fp ); } } else if( flags & FLAG_FAR ) { put_keyword( T___FAR, fp ); } else if( flags & FLAG_HUGE ) { put_keyword( T___HUGE, fp ); } else if( flags & FLAG_FAR16 ) { put_keyword( T___FAR16, fp ); } switch( flags & MASK_LANGUAGES ) { case LANG_WATCALL: put_keyword( T___WATCALL, fp ); break; case LANG_CDECL: put_keyword( T___CDECL, fp ); break; case LANG_PASCAL: put_keyword( T___PASCAL, fp ); break; case LANG_FORTRAN: put_keyword( T___FORTRAN, fp ); break; case LANG_SYSCALL: put_keyword( T__SYSCALL, fp ); break; case LANG_STDCALL: put_keyword( T___STDCALL, fp ); break; case LANG_OPTLINK: put_keyword( T__OPTLINK, fp ); break; case LANG_FASTCALL: put_keyword( T___FASTCALL, fp ); break; } }
static void ChunkSaveStrWord( STRCHUNK *pch, const char *str ) { ChunkSaveStr( pch, str ); ChunkSaveChar( pch, ' ' ); }