[pygccxml-commit] SF.net SVN: pygccxml:[1483] pygccxml_dev
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2008-12-21 22:28:20
|
Revision: 1483 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1483&view=rev Author: roman_yakovenko Date: 2008-12-21 22:28:17 +0000 (Sun, 21 Dec 2008) Log Message: ----------- adding ability to dump exported classes Modified Paths: -------------- pygccxml_dev/pygccxml/msvc/mspdb/loader.py pygccxml_dev/unittests/mspdb_playground.py Modified: pygccxml_dev/pygccxml/msvc/mspdb/loader.py =================================================================== --- pygccxml_dev/pygccxml/msvc/mspdb/loader.py 2008-12-21 19:02:08 UTC (rev 1482) +++ pygccxml_dev/pygccxml/msvc/mspdb/loader.py 2008-12-21 22:28:17 UTC (rev 1483) @@ -81,7 +81,14 @@ def symbols(self): self.logger.info( 'loading symbols from the file' ) smbls = {} + useless = ( msdia.SymTagAnnotation + , msdia.SymTagBlock + , msdia.SymTagFuncDebugStart + , msdia.SymTagFuncDebugEnd + , msdia.SymTagManagedType ) for smbl in itertools.imap( as_symbol, as_enum_variant( self.symbols_table._NewEnum ) ): + if smbl.symTag in useless: + continue smbl.uname = msvc_utils.undecorate_name( smbl.name, msvc_utils.UNDECORATE_NAME_OPTIONS.UNDNAME_SCOPES_ONLY ) def smbl_undecorate_name( options=None ): return msvc_utils.undecorate_name( smbl.name, options ) @@ -92,47 +99,64 @@ @utils.cached def public_symbols( self ): - self.logger.info( 'loading public symbols from the file' ) - smbls = {} + """dictionary, where key is reference to public symbol, and value is symbol itself""" + self.logger.info( 'loading public symbols' ) + self.logger.info( 'looking for public symbols' ) + public_smbls = {} + undname_flags = enums.UNDECORATE_NAME_OPTIONS.UNDNAME_SHORT_UNIQUE for smbl in self.symbols.itervalues(): - if not smbl.function: + if not smbl.function or not smbl.name or smbl.name.startswith( '__' ): continue - if not smbl.name: + undecorated_name = smbl.get_undecoratedNameEx( undname_flags ) + if not undecorated_name: continue - undecorated_name = smbl.get_undecoratedNameEx( enums.UNDECORATE_NAME_OPTIONS.UNDNAME_SCOPES_ONLY ) + for prefix in ( '__', '@', 'type_info::' ): + if undecorated_name.startswith( prefix ): + break + else: + assert undecorated_name not in public_smbls + public_smbls[ undecorated_name ] = smbl + self.logger.info( 'looking for public symbols(%d) - done', len(public_smbls) ) + self.logger.info( 'mapping public symbols to real symbols') + smbls = {} + for smbl in self.symbols.itervalues(): + undecorated_name = smbl.get_undecoratedNameEx( undname_flags ) if not undecorated_name: continue - if smbl.name.startswith( '__' ): + undecorated_name = undecorated_name.strip() + if undecorated_name not in public_smbls: continue - if undecorated_name.startswith( '__' ): - continue - if undecorated_name.startswith( '@' ): - continue - if undecorated_name.startswith( 'type_info::' ): - continue - smbls[ smbl.symIndexId ] = smbl - self.logger.info( 'loading public symbols(%d) from the file - done', len( smbls ) ) + smbls[ public_smbls[undecorated_name] ] = smbl + self.logger.info( 'mapping public symbols(%d) to real symbols - done', len( smbls ) ) + self.logger.info( 'loading public symbols(%d) - done', len( smbls ) ) return smbls + @utils.cached + def public_classes( self ): + """returns set of public classes, which derives from the set of public symbols""" + self.logger.info( 'loading public classes' ) + classes = {} + for smbl in self.public_symbols.itervalues(): + parent = smbl.classParent + while parent: + classes[ parent.symIndexId ] = self.symbols[ parent.symIndexId ] + parent = parent.classParent + self.logger.info( 'loading public classes(%d) - done', len(classes) ) + return classes + def __load_nss(self): def ns_filter( smbl ): self.logger.debug( '__load_ns.ns_filter, %s', smbl.uname ) tags = ( msdia.SymTagFunction , msdia.SymTagBlock , msdia.SymTagData - #~ , msdia.SymTagAnnotation - #~ , msdia.SymTagPublicSymbol , msdia.SymTagUDT , msdia.SymTagEnum - #~ , msdia.SymTagFunctionType - #~ , msdia.SymTagPointerType , msdia.SymTagArrayType , msdia.SymTagBaseType , msdia.SymTagTypedef , msdia.SymTagBaseClass , msdia.SymTagFriend - #~ , msdia.SymTagFunctionArgType - #~ , msdia.SymTagUsingNamespace ) if smbl.symTag not in tags: self.logger.debug( 'smbl.symTag not in tags, %s', smbl.uname ) @@ -142,9 +166,6 @@ elif not smbl.name: self.logger.debug( 'not smbl.name, %s', smbl.uname ) return False - #~ elif '-' in smbl.name: - #~ self.logger.debug( '"-" in smbl.name, %s', smbl.uname ) - #~ return False elif smbl.classParent: parent_smbl = self.symbols[ smbl.classParentId ] while parent_smbl: @@ -291,25 +312,6 @@ self.__parent_exist.add( parent_name ) return bool( found ) - def __clear_symbols(self): - self.logger.info( 'clearing symbols' ) - to_be_deleted = [] - useless_tags = ( - msdia.SymTagAnnotation - , msdia.SymTagPublicSymbol - , msdia.SymTagBlock - , msdia.SymTagFuncDebugStart - , msdia.SymTagFuncDebugEnd - ) - for smbl_id, smbl in self.symbols.iteritems(): - if smbl.symTag in useless_tags \ - or ( smbl.symTag == msdia.SymTagData and not self.__is_my_var( smbl ) ): - to_be_deleted.append( smbl_id ) - - map( lambda smbl_id: self.symbols.pop( smbl_id ), to_be_deleted ) - self.logger.info( 'clearing symbols(%d) - done', len( to_be_deleted ) ) - - def __normalize_name( self, decl ): if decl.name == '<unnamed-tag>': decl.name = '' @@ -333,18 +335,23 @@ map( self.__join_unnamed_nss , ns_parent.namespaces( recursive=False, allow_empty=True ) ) + def __remove_empty_nss( self, ns_parent ): + for ns in ns_parent.namespaces( recursive=False, allow_empty=True ): + self.__remove_empty_nss( ns ) + if 0 == len( ns.decls( recursive=False, allow_empty=True ) ): + ns_parent.remove_declaration( ns ) def read(self): - self.__clear_symbols() self.__load_nss() self.__load_classes() self.__load_base_classes() - self.__load_enums() - self.__load_vars() - self.__load_typedefs() - self.__load_calldefs() + #~ self.__load_enums() + #~ self.__load_vars() + #~ self.__load_typedefs() + #~ self.__load_calldefs() map( self.__normalize_name, self.global_ns.decls(recursive=True) ) self.__join_unnamed_nss( self.global_ns ) + self.__remove_empty_nss( self.global_ns ) #join unnamed namespaces @property @@ -400,14 +407,15 @@ def __load_classes( self ): - classes = {}#unique symbol id : class decl - is_udt = lambda smbl: smbl.symTag == msdia.SymTagUDT + classes = {} + #~ is_udt = lambda smbl: smbl.symTag == msdia.SymTagUDT self.logger.info( 'building udt objects' ) - for udt_smbl in itertools.ifilter( is_udt, self.symbols.itervalues() ): + #for udt_smbl in itertools.ifilter( is_udt, self.symbols.itervalues() ): + for udt_smbl in self.public_classes.itervalues(): classes[udt_smbl.symIndexId] = self.__create_class(udt_smbl) self.logger.info( 'building udt objects(%d) - done', len(classes) ) - self.logger.info( 'integrating udt objects with namespaces' ) + self.logger.info( 'integrating class objects with namespaces' ) does_parent_exists = self.parent_exists_t( self.global_ns, classes, self.__id2decl ) while classes: to_be_integrated = len( classes ) @@ -431,6 +439,9 @@ base_id = smbl.type.symIndexId derived_id = smbl.classParentId + if base_id not in self.public_classes or derived_id not in self.public_classes: + continue + hi_base = make_hi( self.__id2decl[base_id] , self.__guess_access_type( smbl ) , bool( smbl.virtualBaseClass ) ) @@ -530,6 +541,8 @@ self.logger.info( 'building function objects' ) is_function = lambda smbl: smbl.symTag == msdia.SymTagFunction for functions_count, function_smbl in enumerate( itertools.ifilter( is_function, self.symbols.itervalues() ) ): + if function_smbl.classParent and function_smbl.classParentId not in self.public_classes: #what about base classes + continue function_decl = self.__create_calldef(function_smbl) if function_decl: self.__update_decls_tree( function_decl ) @@ -562,15 +575,13 @@ def __create_calldef( self, smbl ): self.logger.debug( 'creating calldef "%s"', smbl.uname ) - #~ if smbl.uname == 'some_function': - #~ pdb.set_trace() name_splitter = impl_details.get_name_splitter( smbl.uname ) calldef_type = self.create_type( smbl.type ) #what does happen with constructor? decl = None if isinstance( calldef_type, declarations.member_function_type_t ): could_be_static = False could_be_const = False - if smbl.uname.startswith( '~' ): + if '~' in smbl.uname: decl = declarations.destructor_t() if not decl: #may be operator decl = self.__guess_operator_type(smbl, calldef_type) Modified: pygccxml_dev/unittests/mspdb_playground.py =================================================================== --- pygccxml_dev/unittests/mspdb_playground.py 2008-12-21 19:02:08 UTC (rev 1482) +++ pygccxml_dev/unittests/mspdb_playground.py 2008-12-21 22:28:17 UTC (rev 1483) @@ -12,21 +12,37 @@ reader = mspdb.decl_loader_t( pdb_file ) opt = mspdb.enums.UNDECORATE_NAME_OPTIONS.UNDNAME_SHORT_UNIQUE -d = {} -for smbl in reader.public_symbols.itervalues(): +public_smbls = {} +for smbl in reader.public_symbols.iterkeys(): name = smbl.name undecorated_name = smbl.get_undecoratedNameEx(opt).strip() if undecorated_name.endswith( ')const' ): undecorated_name = undecorated_name[ : -len('const')] - d[ name ] = undecorated_name - d[ undecorated_name ] = name + public_smbls[ name ] = undecorated_name + public_smbls[ undecorated_name ] = name -pprint.pprint( d ) +pprint.pprint( public_smbls ) -#~ reader.read() -#~ f = file( 'decls.cpp', 'w+' ) -#~ declarations.print_declarations( reader.global_ns, writer=lambda line: f.write(line+'\n') ) -#~ f.close() +#~ for smbl in reader.symbols.itervalues(): + #~ if not smbl.classParent: + #~ continue + #~ undecorated_name = smbl.get_undecoratedNameEx(opt) + #~ if not undecorated_name: + #~ continue + #~ undecorated_name = undecorated_name.strip() + #~ if undecorated_name not in public_smbls: + #~ continue + #~ print '--------------------------------------' + #~ print 'mem fun: ', undecorated_name + #~ if smbl.classParent: + #~ print 'parent class: ', smbl.classParent.name + #~ else: + #~ print 'no parent' + #~ print '======================================' +reader.read() +f = file( 'decls.cpp', 'w+' ) +declarations.print_declarations( reader.global_ns, writer=lambda line: f.write(line+'\n') ) +f.close() #~ f = file( 'symbols.txt', 'w+') #~ for smbl in reader.symbols.itervalues(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |