[pygccxml-commit] SF.net SVN: pygccxml: [1288] pygccxml_dev/pygccxml/msvc/pdb
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2008-03-24 21:17:19
|
Revision: 1288 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1288&view=rev Author: roman_yakovenko Date: 2008-03-24 14:17:24 -0700 (Mon, 24 Mar 2008) Log Message: ----------- adding demangle name functionality Modified Paths: -------------- pygccxml_dev/pygccxml/msvc/pdb/enums.py pygccxml_dev/pygccxml/msvc/pdb/impl_details.py pygccxml_dev/pygccxml/msvc/pdb/loader.py Modified: pygccxml_dev/pygccxml/msvc/pdb/enums.py =================================================================== --- pygccxml_dev/pygccxml/msvc/pdb/enums.py 2008-03-24 21:15:05 UTC (rev 1287) +++ pygccxml_dev/pygccxml/msvc/pdb/enums.py 2008-03-24 21:17:24 UTC (rev 1288) @@ -19,3 +19,28 @@ nsFNameExt = nsfFNameExt nsRegularExpression = nsfRegularExpression | nsfCaseSensitive nsCaseInRegularExpression = nsfRegularExpression | nsfCaseInsensitive + + +class UndecorateNameOptions: + UNDNAME_COMPLETE = 0x0000 #Enables full undecoration. + UNDNAME_NO_LEADING_UNDERSCORES = 0x0001 #Removes leading underscores from Microsoft extended keywords. + UNDNAME_NO_MS_KEYWORDS = 0x0002 #Disables expansion of Microsoft extended keywords. + UNDNAME_NO_FUNCTION_RETURNS = 0x0004 #Disables expansion of return type for primary declaration. + UNDNAME_NO_ALLOCATION_MODEL = 0x0008 #Disables expansion of the declaration model. + UNDNAME_NO_ALLOCATION_LANGUAGE = 0x0010 #Disables expansion of the declaration language specifier. + UNDNAME_RESERVED1 = 0x0020 #RESERVED. + UNDNAME_RESERVED2 = 0x0040 #RESERVED. + UNDNAME_NO_THISTYPE = 0x0060 #Disables all modifiers on the this type. + UNDNAME_NO_ACCESS_SPECIFIERS = 0x0080 #Disables expansion of access specifiers for members. + UNDNAME_NO_THROW_SIGNATURES = 0x0100 #Disables expansion of "throw-signatures" for functions and pointers to functions. + UNDNAME_NO_MEMBER_TYPE = 0x0200 #Disables expansion of static or virtual members. + UNDNAME_NO_RETURN_UDT_MODEL = 0x0400 #Disables expansion of the Microsoft model for UDT returns. + UNDNAME_32_BIT_DECODE = 0x0800 #Undecorates 32-bit decorated names. + UNDNAME_NAME_ONLY = 0x1000 #Gets only the name for primary declaration; returns just [scope::]name. Expands template params. + UNDNAME_TYPE_ONLY = 0x2000 #Input is just a type encoding; composes an abstract declarator. + UNDNAME_HAVE_PARAMETERS = 0x4000 #The real template parameters are available. + UNDNAME_NO_ECSU = 0x8000 #Suppresses enum/class/struct/union. + UNDNAME_NO_IDENT_CHAR_CHECK = 0x10000 #Suppresses check for valid identifier characters. + UNDNAME_NO_PTR64 = 0x20000 #Does not include ptr64 in output. + + Modified: pygccxml_dev/pygccxml/msvc/pdb/impl_details.py =================================================================== --- pygccxml_dev/pygccxml/msvc/pdb/impl_details.py 2008-03-24 21:15:05 UTC (rev 1287) +++ pygccxml_dev/pygccxml/msvc/pdb/impl_details.py 2008-03-24 21:17:24 UTC (rev 1288) @@ -1,5 +1,7 @@ - +import ctypes from . import enums +import ctypes.wintypes +from .. import config as msvc_cfg from pygccxml import declarations def guess_class_type( udt_kind ): @@ -17,7 +19,7 @@ return declarations.ACCESS_TYPES.PROTECTED else: return declarations.ACCESS_TYPES.PUBLIC - + class full_name_splitter_t( object ): def __init__( self, full_name ): self.__full_name = full_name @@ -27,7 +29,7 @@ @property def name( self ): return self.__identifiers[-1] - + @property def scope_names( self ): if None is self.__scope_identifiers: @@ -54,14 +56,14 @@ next_token = tmp.pop() token = token + '::' + next_token less_count += next_token.count( '<' ) - greater_count += next_token.count( '>' ) - result.append( token ) + greater_count += next_token.count( '>' ) + result.append( token ) return result except Exception, err: msg = 'Unable to split scope for identifiers. The full scope name is: "%s". Error: %s' msg = msg % ( self.__full_name, str(err) ) raise RuntimeError( msg ) - + __name_splitters = {} def get_name_splitter( full_name ): try: @@ -72,6 +74,39 @@ return splitter +#__unDName definition was taken from: +#http://www.tech-archive.net/Archive/VC/microsoft.public.vc.language/2006-02/msg00754.html +msvcrxx = ctypes.CDLL( msvc_cfg.msvcr_path, mode=ctypes.RTLD_GLOBAL) + +free_type = ctypes.CFUNCTYPE( None, ctypes.c_void_p ) #free type +malloc_type = ctypes.CFUNCTYPE( ctypes.c_void_p, ctypes.c_uint ) #malloc type + + +__unDName = msvcrxx.__unDName +__unDName.argtypes = [ ctypes.c_char_p #undecorated name + , ctypes.c_char_p #decorated name + , ctypes.c_int #sizeof undecorated name + , malloc_type + , free_type + , ctypes.c_ushort #flags + ] +__unDName.restype = ctypes.c_char_p + + +def undecorate_name( name, options=None ): + if options is None: + options = enums.UndecorateNameOptions.UNDNAME_NO_ECSU + buffer_size = 1024 * 32 + undecorated_name = ctypes.create_string_buffer('\0' * buffer_size) #should be enouph for any symbol + __unDName( undecorated_name + , name + , buffer_size + , malloc_type( msvcrxx.malloc ) + , free_type( msvcrxx.free ) + , options ) + return undecorated_name.value + + if '__main__' == __name__: name = "boost::detail::is_base_and_derived_impl2<engine_objects::universal_base_t,engine_objects::erroneous_transactions_file_configuration_t>::Host" fnsp = full_name_splitter_t( name ) Modified: pygccxml_dev/pygccxml/msvc/pdb/loader.py =================================================================== --- pygccxml_dev/pygccxml/msvc/pdb/loader.py 2008-03-24 21:15:05 UTC (rev 1287) +++ pygccxml_dev/pygccxml/msvc/pdb/loader.py 2008-03-24 21:17:24 UTC (rev 1288) @@ -40,7 +40,7 @@ class decl_loader_t(object): def __init__(self, pdb_file_path ): self.logger = utils.loggers.pdb_reader - self.logger.setLevel(logging.DEBUG) + self.logger.setLevel(logging.INFO) self.logger.debug( 'creating DiaSource object' ) self.__dia_source = comtypes.client.CreateObject( msdia.DiaSource ) self.logger.debug( 'loading pdb file: %s' % pdb_file_path ) @@ -70,8 +70,18 @@ @utils.cached def symbols(self): + def get_name( smbl ): + if not smbl.name: + return + for ch in '@?$': + if ch in smbl.name and smbl.undecoratedName: + return smbl.undecoratedName + else: + return smbl.name + smbls = {} for smbl in itertools.imap( as_symbol, as_enum_variant( self.symbols_table._NewEnum ) ): + smbl.uname = get_name( smbl ) smbls[ smbl.symIndexId ] = smbl return smbls @@ -166,10 +176,11 @@ if not parent: self.logger.debug( 'unable to find parent for class %s', udt_smbl.name ) continue - if isinstance( parent[0], declarations.namespace_t ): + parent = parent[0] + if isinstance( parent, declarations.namespace_t ): parent.adopt_declaration( ns_class ) else: - parent[0].adopt_declaration( ns_class, declarations.ACCESS_TYPES.PUBLIC ) + parent.adopt_declaration( ns_class, declarations.ACCESS_TYPES.PUBLIC ) del classes[ ns_class.dia_symbols[0].symIndexId ] self.logger.info( 'integrating udt objects with namespaces - done' ) @@ -234,7 +245,6 @@ #between those cases return None - def __create_typedef( self, typedef_smbl ): name_splitter = impl_details.get_name_splitter( typedef_smbl.name ) typedef_decl = declarations.typedef_t( name_splitter.name ) @@ -242,7 +252,7 @@ return typedef_decl def __create_class( self, class_smbl ): - name_splitter = impl_details.get_name_splitter( class_smbl.name ) + name_splitter = impl_details.get_name_splitter( class_smbl.uname ) class_decl = declarations.class_t( name_splitter.name ) class_decl.class_type = impl_details.guess_class_type(class_smbl.udtKind) class_decl.dia_symbols = [class_smbl] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |