[pygccxml-commit] SF.net SVN: pygccxml: [1310] pygccxml_dev
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2008-04-21 20:14:13
|
Revision: 1310 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1310&view=rev Author: roman_yakovenko Date: 2008-04-21 13:14:17 -0700 (Mon, 21 Apr 2008) Log Message: ----------- adding another set of changes related to PDB parser Modified Paths: -------------- pygccxml_dev/pygccxml/declarations/__init__.py pygccxml_dev/pygccxml/declarations/class_declaration.py pygccxml_dev/pygccxml/declarations/cpptypes.py pygccxml_dev/pygccxml/declarations/decl_printer.py pygccxml_dev/pygccxml/declarations/enumeration.py pygccxml_dev/pygccxml/msvc/pdb/loader.py pygccxml_dev/pygccxml/parser/scanner.py pygccxml_dev/unittests/core_tester.py pygccxml_dev/unittests/data/core_types.hpp pygccxml_dev/unittests/data/declarations_enums.hpp pygccxml_dev/unittests/data/declarations_variables.hpp pygccxml_dev/unittests/data/msvc_build/all.cpp pygccxml_dev/unittests/data/msvc_build/msvc_build.vcproj pygccxml_dev/unittests/data/typedefs1.hpp pygccxml_dev/unittests/declarations_tester.py pygccxml_dev/unittests/pdb_tester.py Modified: pygccxml_dev/pygccxml/declarations/__init__.py =================================================================== --- pygccxml_dev/pygccxml/declarations/__init__.py 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/pygccxml/declarations/__init__.py 2008-04-21 20:14:17 UTC (rev 1310) @@ -6,6 +6,9 @@ """ contains classes that describe different C++ declarations """ + +import compilers + from dependencies import dependency_info_t from declaration import location_t from declaration import declaration_t @@ -189,7 +192,7 @@ from function_traits import is_same_function all_container_traits = container_traits.container_traits -"""tuple of all STD container traits classes""" +"""tuple of all STD container traits classes""" sequential_container_traits = \ [ Modified: pygccxml_dev/pygccxml/declarations/class_declaration.py =================================================================== --- pygccxml_dev/pygccxml/declarations/class_declaration.py 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/pygccxml/declarations/class_declaration.py 2008-04-21 20:14:17 UTC (rev 1310) @@ -13,6 +13,7 @@ """ import scopedef +import compilers import algorithm import declaration import dependencies @@ -48,7 +49,7 @@ class hierarchy_info_t( object ): """describes class relationship""" - def __init__(self, related_class=None, access=None ): + def __init__(self, related_class=None, access=None, is_virtual=None ): """creates class that contains partial information about class relationship""" if related_class: assert( isinstance( related_class, class_t ) ) @@ -56,12 +57,14 @@ if access: assert( access in ACCESS_TYPES.ALL) self._access=access + self._is_virtual = is_virtual def __eq__(self, other): if not isinstance( other, hierarchy_info_t ): return False return algorithm.declaration_path( self.related_class ) == algorithm.declaration_path( other.related_class ) \ - and self.access == other.access + and self.access == other.access \ + and self.is_virtual == other.is_virtual def __ne__( self, other): return not self.__eq__( other ) @@ -69,8 +72,8 @@ def __lt__(self, other): if not isinstance( other, self.__class__ ): return self.__class__.__name__ < other.__class__.__name__ - return ( algorithm.declaration_path( self.related_class ), self.access ) \ - < ( algorithm.declaration_path( other.related_class ), other.access ) + return ( algorithm.declaration_path( self.related_class ), self.access, self.is_virtual ) \ + < ( algorithm.declaration_path( other.related_class ), other.access, self.is_virtual ) def _get_related_class(self): return self._related_class @@ -90,6 +93,15 @@ access_type = property( _get_access, _set_access , doc="describes L{hierarchy type<ACCESS_TYPES>}") + #TODO: check whether GCC XML support this and if so parser this information + def _get_is_virtual(self): + return self._is_virtual + def _set_is_virtual(self, new_is_virtual): + self._is_virtual = new_is_virtual + is_virtual = property( _get_is_virtual, _set_is_virtual + , doc="indicates whether the inheritance is virtual or not") + + class class_declaration_t( declaration.declaration_t ): """describes class declaration""" def __init__( self, name='' ): @@ -162,9 +174,9 @@ if tmp.startswith( '::' ): tmp = tmp[2:] if '<' not in tmp and '<' in self._name: - #we have template class, but for some reason demangled + #we have template class, but for some reason demangled #name doesn't contain any template - #This happens for std::string class, but this breaks + #This happens for std::string class, but this breaks #other cases, because this behaviour is not consistent self.cache.demangled_name = self._name return self.cache.demangled_name @@ -305,6 +317,8 @@ , doc="Size of this class in bytes @type: int") def _get_byte_align(self): + if self.compiler == compilers.MSVC_PDB_9: + compilers.on_missing_functionality( self.compiler, "byte align" ) return self._byte_align def _set_byte_align( self, new_byte_align ): self._byte_align = new_byte_align @@ -450,7 +464,7 @@ return None def _get_partial_name_impl( self ): - import type_traits #prevent cyclic dependencies + import type_traits #prevent cyclic dependencies if type_traits.is_std_string( self ): return 'string' elif type_traits.is_std_wstring( self ): Modified: pygccxml_dev/pygccxml/declarations/cpptypes.py =================================================================== --- pygccxml_dev/pygccxml/declarations/cpptypes.py 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/pygccxml/declarations/cpptypes.py 2008-04-21 20:14:17 UTC (rev 1310) @@ -7,6 +7,7 @@ defines classes, that describe C++ types """ +import compilers import algorithms_cache class type_t(object): @@ -42,7 +43,7 @@ @property def decl_string( self ): return self.build_decl_string() - + @property def partial_decl_string( self ): return self.build_decl_string( False ) @@ -63,6 +64,8 @@ , doc="Size of this type in bytes @type: int") def _get_byte_align(self): + if self.compiler == compilers.MSVC_PDB_9: + compilers.on_missing_functionality( self.compiler, "byte align" ) return self._byte_align def _set_byte_align( self, new_byte_align ): self._byte_align = new_byte_align @@ -376,21 +379,21 @@ class restrict_t( compound_t ): """represents C{restrict whatever} type""" - - #The restrict keyword can be considered an extension to the strict aliasing - #rule. It allows the programmer to declare that pointers which share the same - #type (or were otherwise validly created) do not alias eachother. By using - #restrict the programmer can declare that any loads and stores through the - #qualified pointer (or through another pointer copied either directly or - #indirectly from the restricted pointer) are the only loads and stores to - #the same address during the lifetime of the pointer. In other words, the + + #The restrict keyword can be considered an extension to the strict aliasing + #rule. It allows the programmer to declare that pointers which share the same + #type (or were otherwise validly created) do not alias eachother. By using + #restrict the programmer can declare that any loads and stores through the + #qualified pointer (or through another pointer copied either directly or + #indirectly from the restricted pointer) are the only loads and stores to + #the same address during the lifetime of the pointer. In other words, the #pointer is not aliased by any pointers other than its own copies. def __init__( self, base ): compound_t.__init__( self, base) def build_decl_string(self, with_defaults=True): - return '__restrict__ ' + self.base.build_decl_string( with_defaults ) + return '__restrict__ ' + self.base.build_decl_string( with_defaults ) def _clone_impl( self ): return restrict_t( self.base.clone() ) @@ -471,12 +474,12 @@ self._arguments_types = new_arguments_types arguments_types = property( _get_arguments_types, _set_arguments_types , doc="list of argument L{types<type_t>}") - + @property def has_ellipsis( self ): return self.arguments_types and isinstance( self.arguments_types[-1], ellipsis_t ) - + class free_function_type_t( type_t, calldef_type_t ): """describes free function type""" NAME_TEMPLATE = '%(return_type)s (*)( %(arguments)s )' @@ -599,7 +602,7 @@ return self.create_decl_string( self.return_type , self.class_inst.decl_string , self.arguments_types - , self.has_const + , self.has_const , with_defaults) def _clone_impl( self ): Modified: pygccxml_dev/pygccxml/declarations/decl_printer.py =================================================================== --- pygccxml_dev/pygccxml/declarations/decl_printer.py 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/pygccxml/declarations/decl_printer.py 2008-04-21 20:14:17 UTC (rev 1310) @@ -115,9 +115,9 @@ self.print_decl_header() if self.__print_details: self.writer( ' ' * ( self.level + 1 ) * self.INDENT_SIZE - + 'copy constructor: ' + str(self.__inst.is_copy_constructor) + + 'copy constructor: ' + str(self.__inst.is_copy_constructor) + os.linesep ) - + def visit_destructor( self ): self.print_decl_header() @@ -144,8 +144,11 @@ if self.__print_details: byte_size = 'size: %d'%(self.__inst.byte_size) self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_size.ljust( self.JUSTIFY ) + os.linesep ) - byte_align = 'align: %d'%(self.__inst.byte_align) - self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_align.ljust( self.JUSTIFY ) + os.linesep ) + try: + byte_align = 'align: %d'%(self.__inst.byte_align) + self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_align.ljust( self.JUSTIFY ) + os.linesep ) + except NotImplementedError: + self.writer( ' ' * curr_level * self.INDENT_SIZE + "not implemented".ljust( self.JUSTIFY ) + os.linesep ) if self.__inst.aliases: aliases = map( lambda typedef: typedef.name, self.__inst.aliases ) @@ -158,8 +161,11 @@ for class_ in classes: class_str = 'class: ' + "'%s'" % str(class_.related_class.decl_string) self.writer( ' ' * curr_level * self.INDENT_SIZE + class_str.ljust( self.JUSTIFY ) + os.linesep ) - access = 'access: ' + "'%s'" % str(class_.access) + access = 'access type: ' + "'%s'" % str(class_.access) self.writer( ' ' * (curr_level + 1)* self.INDENT_SIZE + access.ljust( self.JUSTIFY ) + os.linesep ) + if not ( None is class_.is_virtual ): + is_virtual = 'virtual inheritance: ' + "'%s'" % str(class_.is_virtual) + self.writer( ' ' * (curr_level + 1)* self.INDENT_SIZE + is_virtual.ljust( self.JUSTIFY ) + os.linesep ) def print_members(members_type, members, curr_level): self.writer( ' ' * curr_level * self.INDENT_SIZE + members_type.ljust( self.JUSTIFY ) + os.linesep ) @@ -209,8 +215,11 @@ if self.__print_details: byte_size = 'size: %d'%(self.__inst.type.byte_size) self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_size.ljust( self.JUSTIFY ) + os.linesep ) - byte_align = 'align: %d'%(self.__inst.type.byte_align) - self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_align.ljust( self.JUSTIFY ) + os.linesep ) + try: + byte_align = 'align: %d'%(self.__inst.type.byte_align) + self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_align.ljust( self.JUSTIFY ) + os.linesep ) + except NotImplementedError: + self.writer( ' ' * curr_level * self.INDENT_SIZE + "not implemented".ljust( self.JUSTIFY ) + os.linesep ) byte_offset = 'offset: %d'%(self.__inst.byte_offset) self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_offset + os.linesep) Modified: pygccxml_dev/pygccxml/declarations/enumeration.py =================================================================== --- pygccxml_dev/pygccxml/declarations/enumeration.py 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/pygccxml/declarations/enumeration.py 2008-04-21 20:14:17 UTC (rev 1310) @@ -7,9 +7,10 @@ defines class, that describes C++ enum """ -import declaration import copy import types +import compilers +import declaration class enumeration_t( declaration.declaration_t ): """ @@ -37,7 +38,7 @@ # Initialize values via property access self.values = values self._byte_size = 0 - self._byte_align = 0 + self._byte_align = 0 def __eq__(self, other): if not declaration.declaration_t.__eq__( self, other ): @@ -127,6 +128,8 @@ , doc="Size of this class in bytes @type: int") def _get_byte_align(self): + if self.compiler == compilers.MSVC_PDB_9: + compilers.on_missing_functionality( self.compiler, "byte align" ) return self._byte_align def _set_byte_align( self, new_byte_align ): self._byte_align = new_byte_align Modified: pygccxml_dev/pygccxml/msvc/pdb/loader.py =================================================================== --- pygccxml_dev/pygccxml/msvc/pdb/loader.py 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/pygccxml/msvc/pdb/loader.py 2008-04-21 20:14:17 UTC (rev 1310) @@ -46,7 +46,7 @@ print 'File: ', f.fileName class decl_loader_t(object): - COMPILER = 'MSVC PDB' + COMPILER = declarations.compilers.MSVC_PDB_9 def __init__(self, pdb_file_path ): self.logger = utils.loggers.pdb_reader self.logger.setLevel(logging.INFO) @@ -59,6 +59,8 @@ self.logger.debug( 'opening session - done' ) self.__global_ns = declarations.namespace_t( '::' ) self.__global_ns.compiler = self.COMPILER + self.__id2decl = {} #cache symIndexId : decl + self.__types_cache = {} #smbl id : type def __find_table(self, name): valid_names = ( 'Symbols', 'SourceFiles', 'Sections' @@ -164,6 +166,7 @@ if not parent_ns: continue #in this case the parent scope is UDT ns_decl = declarations.namespace_t( name_splitter.name ) + ns_decl.compiler = self.COMPILER parent_ns.adopt_declaration( ns_decl ) nss[ ns_name ] = ns_decl self.logger.debug( 'inserting ns "%s" into declarations tree - done', ns_name ) @@ -173,20 +176,23 @@ def __update_decls_tree( self, decl ): smbl = decl.dia_symbols[0] - name_splitter = impl_details.get_name_splitter( smbl.uname ) - if not name_splitter.scope_names: - self.__adopt_declaration( self.global_ns, decl ) + if smbl.classParentId in self.__id2decl: + self.__adopt_declaration( self.__id2decl[smbl.classParentId], decl ) else: - parent_name = '::' + name_splitter.scope_names[-1] - try: - parent = self.global_ns.decl( parent_name ) - except: - declarations.print_declarations( self.global_ns ) - print 'identifiers:' - for index, identifier in enumerate(name_splitter.identifiers): - print index, ':', identifier - raise - self.__adopt_declaration( parent, decl ) + name_splitter = impl_details.get_name_splitter( smbl.uname ) + if not name_splitter.scope_names: + self.__adopt_declaration( self.global_ns, decl ) + else: + parent_name = '::' + name_splitter.scope_names[-1] + try: + parent = self.global_ns.decl( parent_name ) + except: + declarations.print_declarations( self.global_ns ) + print 'identifiers:' + for index, identifier in enumerate(name_splitter.identifiers): + print index, ':', identifier + raise + self.__adopt_declaration( parent, decl ) def __adopt_declaration( self, parent, decl ): smbl = decl.dia_symbols[0] @@ -196,11 +202,13 @@ parent.adopt_declaration( decl ) else: parent.adopt_declaration( decl, self.__guess_access_type( smbl ) ) + self.__id2decl[ smbl.symIndexId ] = decl else: for other_decl in already_added: for other_smbl in other_decl.dia_symbols: if self.__are_symbols_equivalent( other_smbl, smbl ): other_decl.dia_symbols.append( smbl ) + self.__id2decl[ smbl.symIndexId ] = other_decl return else: if isinstance( parent, declarations.namespace_t ): @@ -222,41 +230,37 @@ else: return declarations.ACCESS_TYPES.PUBLIC - def __load_classes( self ): - classes = {}#unique symbol id : class decl - 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() ): - classes[udt_smbl.symIndexId] = self.__create_class(udt_smbl) - self.logger.info( 'building udt objects(%d) - done', len(classes) ) + class parent_exists_t: + def __init__( self, global_ns, classes, id2decl ): + self.global_ns = global_ns + self.classes = classes + self.id2decl = id2decl + self.__parent_exist = set() - def does_parent_exist_in_decls_tree( class_decl ): - class_smbl = class_decl.dia_symbols[0] - if classes.has_key( class_smbl.classParentId ): + def __call__( self, decl ): + smbl = decl.dia_symbols[0] + if smbl.classParent: + if smbl.classParentId in self.id2decl: + return True + else: + return False + if self.classes.has_key( smbl.classParentId ): return False - name_splitter = impl_details.get_name_splitter( class_smbl.uname ) + name_splitter = impl_details.get_name_splitter( smbl.uname ) if not name_splitter.scope_names: return True #global namespace else: + #print "I am here " + '::' + name_splitter.scope_names[-1] parent_name = '::' + name_splitter.scope_names[-1] + if parent_name in self.__parent_exist: + return True found = self.global_ns.decls( parent_name , decl_type=declarations.scopedef_t , allow_empty=True , recursive=True ) + if found: + self.__parent_exist.add( parent_name ) return bool( found ) - self.logger.info( 'integrating udt objects with namespaces' ) - while classes: - to_be_integrated = len( classes ) - self.logger.info( 'there are %d classes to go', len( classes ) ) - to_be_deleted = filter( does_parent_exist_in_decls_tree, classes.itervalues() ) - map( self.__update_decls_tree, to_be_deleted ) - map( lambda decl: classes.pop( decl.dia_symbols[0].symIndexId ) - , to_be_deleted ) - if not ( to_be_integrated - len( classes ) ): - for cls in classes.itervalues(): - self.logger.warning( 'unable to integrate class "%s" into declarations tree', cls.dia_symbols[0].uname ) - break - self.logger.info( 'integrating udt objects with namespaces - done' ) def __clear_symbols(self): self.logger.info( 'clearing symbols' ) @@ -270,11 +274,13 @@ self.logger.info( 'clearing symbols(%d) - done', len( to_be_deleted ) ) def read(self): - self.__clear_symbols() + #self.__clear_symbols() self.__load_nss() self.__load_classes() + self.__load_base_classes() self.__load_enums() self.__load_vars() + self.__load_typedefs() @property def dia_global_scope(self): @@ -317,20 +323,65 @@ def __update_decl( self, decl, smbl ): decl.dia_symbols = [smbl] decl.compiler = self.COMPILER - decl.byte_size = smbl.length + if not isinstance( decl, declarations.typedef_t ): + decl.byte_size = smbl.length + decl.byte_offset = smbl.offset decl.mangled = iif( smbl.name, smbl.name, '' ) decl.demangled = iif( smbl.uname, smbl.uname, '' ) decl.is_artificial = bool( smbl.compilerGenerated ) + + def __load_classes( self ): + classes = {}#unique symbol id : class decl + 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() ): + 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' ) + does_parent_exists = self.parent_exists_t( self.global_ns, classes, self.__id2decl ) + while classes: + to_be_integrated = len( classes ) + self.logger.info( 'there are %d classes to go', len( classes ) ) + to_be_deleted = filter( does_parent_exists, classes.itervalues() ) + map( self.__update_decls_tree, to_be_deleted ) + map( lambda decl: classes.pop( decl.dia_symbols[0].symIndexId ) + , to_be_deleted ) + if not ( to_be_integrated - len( classes ) ): + for cls in classes.itervalues(): + self.logger.warning( 'unable to integrate class "%s" into declarations tree', cls.dia_symbols[0].uname ) + break + self.logger.info( 'integrating udt objects with namespaces - done' ) + + def __load_base_classes( self ): + make_hi = declarations.hierarchy_info_t + is_base_class = lambda smbl: smbl.symTag == msdia.SymTagBaseClass \ + and False == smbl.indirectVirtualBaseClass + self.logger.info( 'building class hierarchies' ) + for count, smbl in enumerate( itertools.ifilter( is_base_class, self.symbols.itervalues() ) ): + base_id = smbl.type.symIndexId + derived_id = smbl.classParentId + + hi_base = make_hi( self.__id2decl[base_id] + , self.__guess_access_type( smbl ) + , bool( smbl.virtualBaseClass ) ) + self.__id2decl[ derived_id ].bases.append( hi_base ) + + hi_derived = make_hi( self.__id2decl[derived_id] + , self.__guess_access_type( smbl ) + , bool( smbl.virtualBaseClass ) ) + self.__id2decl[ base_id ].derived.append( hi_derived ) + + self.logger.info( 'building class hierarchies(%d) - done', count ) + def __load_enums( self ): is_enum = lambda smbl: smbl.symTag == msdia.SymTagEnum self.logger.info( 'building enum objects' ) - enums_count = 0 - for enum_smbl in itertools.ifilter( is_enum, self.symbols.itervalues() ): + for enums_count, enum_smbl in enumerate( itertools.ifilter( is_enum, self.symbols.itervalues() ) ): enum_decl = self.__create_enum(enum_smbl) if not enum_decl: continue - enums_count += 1 self.__update_decls_tree( enum_decl ) self.logger.info( 'building enum objects(%d) - done', enums_count ) @@ -373,13 +424,11 @@ def __load_vars( self ): self.logger.info( 'building variable objects' ) - vars_count = 0 - for var_smbl in itertools.ifilter( self.__is_my_var, self.symbols.itervalues() ): + + for vars_count, var_smbl in enumerate( itertools.ifilter( self.__is_my_var, self.symbols.itervalues() ) ): var_decl = self.__create_var(var_smbl) - if not var_decl: - continue - vars_count += 1 - self.__update_decls_tree( var_decl ) + if var_decl: + self.__update_decls_tree( var_decl ) self.logger.info( 'building variable objects(%d) - done', vars_count ) def __create_var( self, smbl ): @@ -387,14 +436,34 @@ name_splitter = impl_details.get_name_splitter( smbl.uname ) decl = declarations.variable_t( name_splitter.name ) self.__update_decl( decl, smbl ) - #~ if decl.name == 'initialized': - #~ pdb.set_trace() decl.type = self.create_type( smbl.type ) decl.value = str(smbl.value) self.logger.debug( 'creating variable "%s" - done', smbl.uname ) return decl + def __load_typedefs( self ): + self.logger.info( 'building typedef objects' ) + is_typedef = lambda smbl: smbl.symTag == msdia.SymTagTypedef + for typedefs_count, typedef_smbl in enumerate( itertools.ifilter( is_typedef, self.symbols.itervalues() ) ): + typedef_decl = self.__create_typedef(typedef_smbl) + self.__update_decls_tree( typedef_decl ) + self.logger.info( 'building typedef objects(%d) - done', typedefs_count ) + + def __create_typedef( self, smbl ): + self.logger.debug( 'creating typedef "%s"', smbl.uname ) + name_splitter = impl_details.get_name_splitter( smbl.uname ) + #~ if decl.name == 'initialized': + #~ pdb.set_trace() + decl = declarations.typedef_t( name_splitter.name + , self.create_type( smbl.type ) ) + self.__update_decl( decl, smbl ) + self.logger.debug( 'creating typedef "%s" - done', smbl.uname ) + return decl + + def create_type( self, smbl ): + if smbl.symIndexId in self.__types_cache: + return self.__types_cache[smbl.symIndexId] my_type = None if msdia.SymTagBaseType == smbl.symTag: if enums.BasicType.btNoType == smbl.baseType: @@ -442,9 +511,18 @@ if bytes and element_type.byte_size: size = bytes / element_type.byte_size my_type = declarations.array_t( element_type, size ) + elif smbl.symTag in ( msdia.SymTagUDT, msdia.SymTagTypedef, msdia.SymTagEnum ): + if smbl.symIndexId in self.__id2decl: + decl = self.__id2decl[ smbl.symIndexId ] + my_type = declarations.declarated_t( decl ) + else: + my_type = declarations.unknown_t() else: my_type = declarations.unknown_t() - my_type.byte_size = smbl.length + try: + my_type.byte_size = smbl.length + except AttributeError: + pass if smbl.constType: my_type = declarations.const_t( my_type ) if smbl.volatileType: Modified: pygccxml_dev/pygccxml/parser/scanner.py =================================================================== --- pygccxml_dev/pygccxml/parser/scanner.py 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/pygccxml/parser/scanner.py 2008-04-21 20:14:17 UTC (rev 1310) @@ -92,12 +92,12 @@ , XML_NN_ENUMERATION : self.__read_enumeration , XML_NN_ENUMERATION_VALUE : self.__read_enumeration_value , XML_NN_ARRAY_TYPE : self.__read_array_type - , XML_NN_CV_QUALIFIED_TYPE : self.__read_cv_qualified_type + , XML_NN_CV_QUALIFIED_TYPE : self.__read_cv_qualified_type , XML_NN_POINTER_TYPE : self.__read_pointer_type , XML_NN_REFERENCE_TYPE : self.__read_reference_type - , XML_NN_FUNDAMENTAL_TYPE : self.__read_fundamental_type + , XML_NN_FUNDAMENTAL_TYPE : self.__read_fundamental_type , XML_NN_ARGUMENT : self.__read_argument - , XML_NN_FUNCTION_TYPE : self.__read_function_type + , XML_NN_FUNCTION_TYPE : self.__read_function_type , XML_NN_METHOD_TYPE : self.__read_method_type , XML_NN_OFFSET_TYPE : self.__read_offset_type , XML_NN_TYPEDEF : self.__read_typedef @@ -132,7 +132,7 @@ assert isinstance( decl_factory, decl_factory_t ) self.__decl_factory = decl_factory - + #mapping from id -> decl self.__declarations = {} #list of all read declarations @@ -141,7 +141,7 @@ self.__enums = [] #mapping from id -> type self.__types = {} - #mapping from id -> file + #mapping from id -> file self.__files = {} #mapping between decl id -> access self.__access = {} @@ -149,12 +149,12 @@ self.__inst = None #mapping from id to members self.__members = {} - + self.__compiler = None - + def read( self ): xml.sax.parse( self.gccxml_file, self ) - + def endDocument( self ): #updating membership members_mapping = {} @@ -164,34 +164,34 @@ continue members_mapping[ id( decl ) ] = members self.__members = members_mapping - + def declarations(self): return self.__declarations - + def calldefs( self ): return self.__calldefs def enums(self): return self.__enums - + def types(self): return self.__types - + def files(self): return self.__files def access(self): return self.__access - + def members(self): return self.__members def startElementNS(self, name, qname, attrs): return self.startElement( name[1], attrs ) - + def endElementNS(self, name, qname): return self.endElement( name[1] ) - + def startElement(self, name, attrs): try: if name not in self.__readers: @@ -216,7 +216,7 @@ self.__read_mangled( obj, attrs) self.__read_demangled( obj, attrs) self.__read_attributes(obj, attrs) - + elif isinstance( obj, type_t ): self.__types[ element_id ] = obj self.__read_byte_size(obj, attrs) @@ -231,7 +231,7 @@ msg = msg + os.linesep + 'Error: %s.' % str( error ) self.logger.error( msg % ( name, pprint.pformat( attrs.keys() ) ) ) raise - + def endElement(self, name): if name in self.deep_declarations: self.__inst = None @@ -242,7 +242,7 @@ def __update_membership(self, attrs): parent = attrs.get( XML_AN_CONTEXT, None ) if not parent: - return + return if not self.__members.has_key( parent ): self.__members[ parent ] = [] self.__members[parent].append( attrs[XML_AN_ID] ) @@ -261,7 +261,7 @@ def __read_demangled( self, decl, attrs ): decl.demangled = attrs.get( XML_AN_DEMANGLED, None ) - + def __read_attributes( self, decl, attrs ): decl.attributes = attrs.get( XML_AN_ATTRIBUTES, None ) @@ -285,7 +285,7 @@ def __read_root(self, attrs): pass - + def __read_file( self, attrs ): return attrs.get( XML_AN_NAME, '' ) @@ -336,7 +336,7 @@ msg = 'unable to find out array size from expression "%s"' % attrs[ XML_AN_MAX ] warnings.warn( msg ) return array_t( type_, size + 1 ) - + def __read_cv_qualified_type( self, attrs ): if attrs.has_key( XML_AN_CONST ): return const_t( attrs[XML_AN_TYPE] ) @@ -344,12 +344,12 @@ return volatile_t( attrs[XML_AN_TYPE] ) elif attrs.has_key( XML_AN_RESTRICT ): return restrict_t( attrs[XML_AN_TYPE] ) - else: - assert 0 + else: + assert 0 def __read_pointer_type( self, attrs ): return pointer_t( attrs[XML_AN_TYPE] ) - + def __read_reference_type( self, attrs ): return reference_t( attrs[XML_AN_TYPE] ) @@ -374,13 +374,13 @@ else: argument = argument_t() argument.name = attrs.get( XML_AN_NAME, 'arg%d' % len(self.__inst.arguments) ) - argument.type = attrs[XML_AN_TYPE] + argument.type = attrs[XML_AN_TYPE] argument.default_value = attrs.get( XML_AN_DEFAULT, None ) self.__read_attributes( argument, attrs ) if argument.default_value == '<gccxml-cast-expr>': argument.default_value = None self.__inst.arguments.append( argument ) - + def __read_ellipsis( self, attrs ): if isinstance( self.__inst, calldef_type_t ): self.__inst.arguments_types.append( '...' ) @@ -405,10 +405,10 @@ else: calldef.does_throw = True calldef.exceptions = throw_stmt.split() - - def __read_member_function( self, calldef, attrs, is_declaration ): + + def __read_member_function( self, calldef, attrs, is_declaration ): self.__read_calldef( calldef, attrs, is_declaration ) - calldef.has_const = attrs.get( XML_AN_CONST, False ) + calldef.has_const = attrs.get( XML_AN_CONST, False ) if is_declaration: calldef.has_static = attrs.get( XML_AN_STATIC, False ) if attrs.has_key( XML_AN_PURE_VIRTUAL ): @@ -418,13 +418,13 @@ else: calldef.virtuality = VIRTUALITY_TYPES.NOT_VIRTUAL else: - calldef.class_inst = attrs[XML_AN_BASE_TYPE] - + calldef.class_inst = attrs[XML_AN_BASE_TYPE] + def __read_function_type(self, attrs): answer = free_function_type_t() self.__read_calldef( answer, attrs, False ) return answer - + def __read_method_type(self, attrs): answer = member_function_type_t() self.__read_member_function( answer, attrs, False ) @@ -434,7 +434,7 @@ return self.__decl_factory.create_typedef( name=attrs.get( XML_AN_NAME, '' ), type=attrs[XML_AN_TYPE]) def __read_variable(self, attrs ): - type_qualifiers = type_qualifiers_t() + type_qualifiers = type_qualifiers_t() type_qualifiers.has_mutable = attrs.get(XML_AN_MUTABLE, False) type_qualifiers.has_static = attrs.get(XML_AN_EXTERN, False) bits = attrs.get( XML_AN_BITS, None ) @@ -466,7 +466,7 @@ self.__read_byte_size(decl, attrs) self.__read_byte_align(decl, attrs) return decl - + def __read_class( self, attrs ): return self.__read_class_impl( CLASS_TYPES.CLASS, attrs ) @@ -480,7 +480,7 @@ operator = self.__decl_factory.create_casting_operator() self.__read_member_function( operator, attrs, True ) return operator - + def __read_constructor( self, attrs ): constructor = self.__decl_factory.create_constructor() self.__read_member_function( constructor, attrs, True ) @@ -490,18 +490,18 @@ gfunction = self.__decl_factory.create_free_function() self.__read_calldef( gfunction, attrs, True ) return gfunction - + def __read_method(self, attrs): mfunction = self.__decl_factory.create_member_function() self.__read_member_function( mfunction, attrs, True ) return mfunction - + def __read_destructor(self, attrs): destructor = self.__decl_factory.create_destructor() self.__read_member_function( destructor, attrs, True ) destructor.name = '~' + destructor.name return destructor - + def __read_free_operator(self, attrs ): operator = self.__decl_factory.create_free_operator() self.__read_member_function( operator, attrs, True ) @@ -510,7 +510,7 @@ else: operator.name = 'operator' + operator.name return operator - + def __read_member_operator(self, attrs): operator = self.__decl_factory.create_member_operator() self.__read_member_function( operator, attrs, True ) @@ -522,18 +522,18 @@ def __read_version(self, attrs): logger = utils.loggers.cxx_parser - + version = float( attrs.get(XML_AN_CVS_REVISION, 0.6) ) if version is None: logger.info ( 'GCCXML version - 0.6' ) - version = "0.6" + self.__compiler = compilers.GCC_XML_06 elif version <= 1.114: logger.info ( 'GCCXML version - 0.7' ) - version = "0.7" + self.__compiler = compilers.GCC_XML_07 elif version in ( 1.115, 1.116, 1.117 ): logger.info ( 'GCCXML version - 0.9 BUGGY' ) - version = "0.9" + self.__compiler = compilers.GCC_XML_09_BUGGY else: logger.info ( 'GCCXML version - 0.9' ) - version = "0.9" - self.__compiler = "GCC-XML " + version + self.__compiler = compilers.GCC_XML_09 + Modified: pygccxml_dev/unittests/core_tester.py =================================================================== --- pygccxml_dev/unittests/core_tester.py 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/unittests/core_tester.py 2008-04-21 20:14:17 UTC (rev 1310) @@ -23,30 +23,8 @@ global_ns = None def __init__(self, *args ): parser_test_case.parser_test_case_t.__init__( self, *args ) - self.test_files = [ 'core_ns_join_1.hpp' - , 'core_ns_join_2.hpp' - , 'core_ns_join_3.hpp' - , 'core_membership.hpp' - , 'core_class_hierarchy.hpp' - , 'core_types.hpp' - , 'core_diamand_hierarchy_base.hpp' - , 'core_diamand_hierarchy_derived1.hpp' - , 'core_diamand_hierarchy_derived2.hpp' - , 'core_diamand_hierarchy_final_derived.hpp' - , 'core_overloads_1.hpp' - , 'core_overloads_2.hpp' - , 'abstract_classes.hpp' - ] self.global_ns = None - def setUp(self): - if not core_t.global_ns: - decls = parse( self.test_files, self.config, self.COMPILATION_MODE ) - core_t.global_ns = pygccxml.declarations.get_global_namespace( decls ) - if self.INIT_OPTIMIZER: - core_t.global_ns.init_optimizer() - self.global_ns = core_t.global_ns - def test_top_parent(self): enum = self.global_ns.enum( '::ns::ns32::E33' ) self.failUnless( self.global_ns is enum.top_parent ) @@ -289,9 +267,9 @@ print '\nexpected: ' for x in others: print str(x) - + self.failUnless( set( do_nothing.overloads ) == set( others ) - , "there is a difference between expected function overloads and existing ones." ) + , "there is a difference between expected function overloads and existing ones." ) def test_abstract_classes(self): ns = self.global_ns.namespace( 'abstract_classes' ) @@ -305,50 +283,89 @@ def test_versioning(self): for d in self.global_ns.decls(): self.failUnless( d.compiler ) - + def test_byte_size( self ): mptrs = self.global_ns.class_( 'members_pointers_t' ) self.failUnless( mptrs.byte_size != 0 ) - + def test_byte_align( self ): mptrs = self.global_ns.class_( 'members_pointers_t' ) - self.failUnless( mptrs.byte_align != 0 ) + if mptrs.compiler != compilers.MSVC_PDB_9: + self.failUnless( mptrs.byte_align != 0 ) def test_byte_offset( self ): mptrs = self.global_ns.class_( 'members_pointers_t' ) self.failUnless( mptrs.var( 'xxx' ).byte_offset != 0 ) +class pdb_based_core_tester_t( core_t ): + def __init__(self, *args ): + core_t.__init__( self, *args ) + self.global_ns = autoconfig.get_pdb_global_ns() -class core_all_at_once_t( core_t ): +class core_gccxml_t( core_t ): + """Tests core algorithms of GCC-XML and GCC-XML file reader. + Those most white-box testing. + """ + global_ns = None + def __init__(self, *args ): + core_t.__init__( self, *args ) + self.test_files = [ 'core_ns_join_1.hpp' + , 'core_ns_join_2.hpp' + , 'core_ns_join_3.hpp' + , 'core_membership.hpp' + , 'core_class_hierarchy.hpp' + , 'core_types.hpp' + , 'core_diamand_hierarchy_base.hpp' + , 'core_diamand_hierarchy_derived1.hpp' + , 'core_diamand_hierarchy_derived2.hpp' + , 'core_diamand_hierarchy_final_derived.hpp' + , 'core_overloads_1.hpp' + , 'core_overloads_2.hpp' + , 'abstract_classes.hpp' + ] + self.global_ns = None + + def setUp(self): + if not core_t.global_ns: + decls = parse( self.test_files, self.config, self.COMPILATION_MODE ) + core_t.global_ns = pygccxml.declarations.get_global_namespace( decls ) + if self.INIT_OPTIMIZER: + core_t.global_ns.init_optimizer() + self.global_ns = core_t.global_ns + +class core_all_at_once_t( core_gccxml_t ): COMPILATION_MODE = COMPILATION_MODE.ALL_AT_ONCE INIT_OPTIMIZER = True def __init__(self, *args): - core_t.__init__(self, *args) + core_gccxml_t.__init__(self, *args) -class core_all_at_once_no_opt_t( core_t ): +class core_all_at_once_no_opt_t( core_gccxml_t ): COMPILATION_MODE = COMPILATION_MODE.ALL_AT_ONCE INIT_OPTIMIZER = False def __init__(self, *args): - core_t.__init__(self, *args) + core_gccxml_t.__init__(self, *args) -class core_file_by_file_t( core_t ): +class core_file_by_file_t( core_gccxml_t ): COMPILATION_MODE = COMPILATION_MODE.FILE_BY_FILE INIT_OPTIMIZER = True def __init__(self, *args): - core_t.__init__(self, *args) + core_gccxml_t.__init__(self, *args) -class core_file_by_file_no_opt_t( core_t ): +class core_file_by_file_no_opt_t( core_gccxml_t ): COMPILATION_MODE = COMPILATION_MODE.FILE_BY_FILE INIT_OPTIMIZER = False def __init__(self, *args): - core_t.__init__(self, *args) + core_gccxml_t.__init__(self, *args) def create_suite(): suite = unittest.TestSuite() - suite.addTest( unittest.makeSuite(core_all_at_once_t)) - suite.addTest( unittest.makeSuite(core_all_at_once_no_opt_t)) - suite.addTest( unittest.makeSuite(core_file_by_file_t)) - suite.addTest( unittest.makeSuite(core_file_by_file_no_opt_t)) + #~ suite.addTest( unittest.makeSuite(core_all_at_once_t)) + #~ suite.addTest( unittest.makeSuite(core_all_at_once_no_opt_t)) + #~ suite.addTest( unittest.makeSuite(core_file_by_file_t)) + #~ suite.addTest( unittest.makeSuite(core_file_by_file_no_opt_t)) + if sys.platform == 'win32': + suite.addTest( unittest.makeSuite(pdb_based_core_tester_t)) + return suite def run_suite(): Modified: pygccxml_dev/unittests/data/core_types.hpp =================================================================== --- pygccxml_dev/unittests/data/core_types.hpp 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/unittests/data/core_types.hpp 2008-04-21 20:14:17 UTC (rev 1310) @@ -6,6 +6,11 @@ #ifndef __core_types_hpp__ #define __core_types_hpp__ +#include <iostream> + +#define USE_SYMBOL( X ) enum{ x##__LINE__ = sizeof(X) }; + + namespace core{ namespace types{ typedef void typedef_void; @@ -29,6 +34,8 @@ typedef long double typedef_long_double; typedef const int typedef_const_int; +USE_SYMBOL( typedef_const_int ); + typedef int * typedef_pointer_int; typedef int& typedef_reference_int; typedef const unsigned int * const typedef_const_unsigned_int_const_pointer; Modified: pygccxml_dev/unittests/data/declarations_enums.hpp =================================================================== --- pygccxml_dev/unittests/data/declarations_enums.hpp 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/unittests/data/declarations_enums.hpp 2008-04-21 20:14:17 UTC (rev 1310) @@ -17,6 +17,7 @@ enum EPrivColor{ priv_red, priv_green, priv_blue, priv_black, priv_white }; void do_smth(EPrivColor x){} + EColor favorite_color; }; } } Modified: pygccxml_dev/unittests/data/declarations_variables.hpp =================================================================== --- pygccxml_dev/unittests/data/declarations_variables.hpp 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/unittests/data/declarations_variables.hpp 2008-04-21 20:14:17 UTC (rev 1310) @@ -18,6 +18,10 @@ mutable int m_mutable; }; +struct struct_variables_holder_t{ + struct_variables_t m_struct_variables; +}; + } } #endif//__declarations_variables_hpp__ Modified: pygccxml_dev/unittests/data/msvc_build/all.cpp =================================================================== --- pygccxml_dev/unittests/data/msvc_build/all.cpp 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/unittests/data/msvc_build/all.cpp 2008-04-21 20:14:17 UTC (rev 1310) @@ -3,6 +3,7 @@ #include "bit_fields.hpp" #include "complex_types.hpp" #include "core_cache.hpp" +#include "core_types.hpp" #include "core_class_hierarchy.hpp" #include "core_diamand_hierarchy_base.hpp" #include "core_diamand_hierarchy_derived1.hpp" @@ -40,13 +41,22 @@ #include "unnamed_enums_bug2.hpp" #include "unnamed_ns_bug.hpp" #include "vector_traits.hpp" +#include "core_types.hpp" -namespace declarations{ namespace variables{ - -int static_var = 0; +namespace declarations{ namespace variables{ + +int static_var = 0; }} void use_decls(){ declarations::enums::ENumbers enumbers; declarations::enums::data::EColor ecolor; + + sizeof(core::types::exception ); +} + + +void use_core_types(){ + core::types::members_pointers_t mem_ptrs; + core::types::typedef_const_int typedef_const_int_ = 0; } \ No newline at end of file Modified: pygccxml_dev/unittests/data/msvc_build/msvc_build.vcproj =================================================================== --- pygccxml_dev/unittests/data/msvc_build/msvc_build.vcproj 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/unittests/data/msvc_build/msvc_build.vcproj 2008-04-21 20:14:17 UTC (rev 1310) @@ -53,6 +53,7 @@ BrowseInformation="1" WarningLevel="3" DebugInformationFormat="4" + DisableSpecificWarnings="4290;4584;4293;4244;4101" /> <Tool Name="VCManagedResourceCompilerTool" @@ -77,7 +78,8 @@ /> <Tool Name="VCXDCMakeTool" - ValidateIntelliSense="true" + ValidateIntelliSense="false" + OutputDocumentFile="" /> <Tool Name="VCBscMakeTool" Modified: pygccxml_dev/unittests/data/typedefs1.hpp =================================================================== --- pygccxml_dev/unittests/data/typedefs1.hpp 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/unittests/data/typedefs1.hpp 2008-04-21 20:14:17 UTC (rev 1310) @@ -12,6 +12,8 @@ typedef item_t Item1; +typedef int my_int_t; + } -#endif//__typedefs1_hpp__ \ No newline at end of file +#endif//__typedefs1_hpp__ Modified: pygccxml_dev/unittests/declarations_tester.py =================================================================== --- pygccxml_dev/unittests/declarations_tester.py 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/unittests/declarations_tester.py 2008-04-21 20:14:17 UTC (rev 1310) @@ -49,14 +49,15 @@ % ( expected_value, initialized.value ) ) self._test_type_composition( initialized.type, const_t, long_unsigned_int_t ) - if 'PDB' in self.global_ns.compiler: - return #TODO find out work around static_var = initialized = self.global_ns.variable( name='static_var' ) self.failUnless( static_var.type_qualifiers.has_static , "static_var must have static type qualifier" ) self.failUnless( not static_var.type_qualifiers.has_mutable , "static_var must not have mutable type qualifier" ) + if 'PDB' in self.global_ns.compiler: + return #TODO find out work around + m_mutable = initialized = self.global_ns.variable( name='m_mutable' ) self.failUnless( not m_mutable.type_qualifiers.has_static , "m_mutable must not have static type qualifier" ) Modified: pygccxml_dev/unittests/pdb_tester.py =================================================================== --- pygccxml_dev/unittests/pdb_tester.py 2008-04-12 07:52:34 UTC (rev 1309) +++ pygccxml_dev/unittests/pdb_tester.py 2008-04-21 20:14:17 UTC (rev 1310) @@ -14,25 +14,25 @@ , 'Debug' , 'msvc_build.pdb' ) - def __test_splitter_impl( self, name, expected_result ): + def __splitter_tester_impl( self, name, expected_result ): splitter = pdb.impl_details.full_name_splitter_t( name ) self.failUnless( len(splitter.scope_names) == len(expected_result) ) self.failUnless( splitter.scope_names == expected_result ) - def __test_name_splitter(self): + def test_name_splitter(self): name = "std::_Tree<std::_Tmap_traits<engine_objects::ouuid_t,engine_objects::sql_query::parameterized_query::sql_fragment_t,std::less<engine_objects::ouuid_t>,std::allocator<std::pair<engine_objects::ouuid_t const ,engine_objects::sql_query::parameterized_query::sql_fragment_t> >,0> >::const_iterator::operator->" expected_result = [ 'std' , 'std::_Tree<std::_Tmap_traits<engine_objects::ouuid_t,engine_objects::sql_query::parameterized_query::sql_fragment_t,std::less<engine_objects::ouuid_t>,std::allocator<std::pair<engine_objects::ouuid_t const ,engine_objects::sql_query::parameterized_query::sql_fragment_t> >,0> >', 'std::_Tree<std::_Tmap_traits<engine_objects::ouuid_t,engine_objects::sql_query::parameterized_query::sql_fragment_t,std::less<engine_objects::ouuid_t>,std::allocator<std::pair<engine_objects::ouuid_t const ,engine_objects::sql_query::parameterized_query::sql_fragment_t> >,0> >::const_iterator' ] - self.__test_splitter_impl( name, expected_result ) + self.__splitter_tester_impl( name, expected_result ) name = 'boost::reference_wrapper<engine_objects::ops::pathable_t const >::operator engine_objects::ops::pathable_t const &' expected_result = [ 'boost' , 'boost::reference_wrapper<engine_objects::ops::pathable_t const >' ] - self.__test_splitter_impl( name, expected_result ) + self.__splitter_tester_impl( name, expected_result ) def test_create_nss(self): reader = pdb.decl_loader_t( self.pdb_file ) @@ -45,6 +45,12 @@ f.write( os.linesep.join( x ) ) f.close() + f = file( 'symbols.txt', 'w+') + for smbl in reader.symbols.itervalues(): + f.write( smbl.uname ) + f.write( os.linesep ) + f.write( '\t' + str(smbl.name) ) + f.close() #~ names = [] #~ for d in reader.global_ns.classes(): #~ names.append( '{%s}<=====>{%s}' %( d.demangled, d.mangled ) ) @@ -70,6 +76,7 @@ #~ print undecorated self.failUnless( msvc_utils.undecorate_name( decorated ) == undecorated ) + def create_suite(): suite = unittest.TestSuite() suite.addTest( unittest.makeSuite(tester_t)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |