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.
|