Skip to content

Commit b4d32f3

Browse files
author
roman_yakovenko
committed
another set of changes to PDB reader
1 parent d0854f7 commit b4d32f3

File tree

5 files changed

+92
-55
lines changed

5 files changed

+92
-55
lines changed

pygccxml/declarations/class_declaration.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,18 @@ def recursive_derived(self):
275275
return self._recursive_derived
276276

277277
def _get_is_abstract(self):
278-
return self._is_abstract
278+
if self.compiler == compilers.MSVC_PDB_9:
279+
import calldef
280+
import matchers #prevent cyclic dependencies
281+
m = matchers.virtuality_type_matcher_t( calldef.VIRTUALITY_TYPES.PURE_VIRTUAL )
282+
if self.calldefs( m, recursive=False, allow_empty=True ):
283+
return True
284+
for base in self.recursive_bases:
285+
if base.related_class.calldefs( m, recursive=False, allow_empty=True ):
286+
return True
287+
return False
288+
else:
289+
return self._is_abstract
279290
def _set_is_abstract( self, is_abstract ):
280291
self._is_abstract = is_abstract
281292
is_abstract = property( _get_is_abstract, _set_is_abstract

pygccxml/declarations/decl_printer.py

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99

1010
import os
1111
import sys
12-
import decl_visitor
12+
import calldef
1313
import algorithm
14+
import decl_visitor
1415

1516

1617
class decl_printer_t( decl_visitor.decl_visitor_t ):
@@ -33,7 +34,7 @@ def __init__( self, level=0, print_details=True, recursive=True, writer=None ):
3334
self.__recursive = recursive
3435
self.__writer = writer
3536
if not self.__writer:
36-
self.__writer = sys.stdout.write
37+
self.__writer = lambda x: sys.stdout.write( x + os.linesep )
3738

3839
def clone(self, increment_level=True):
3940
level = self.__level
@@ -83,20 +84,27 @@ def __nice_decl_name( self, inst ):
8384

8485
def print_decl_header(self):
8586
header = self.__nice_decl_name( self.__inst ) + ": '%s'" % self.__inst.name
86-
self.writer( ' ' * self.level * self.INDENT_SIZE + header.ljust( self.JUSTIFY ) + os.linesep )
87+
self.writer( ' ' * self.level * self.INDENT_SIZE + header.ljust( self.JUSTIFY ))
8788
if self.__print_details:
8889
curr_level = self.level + 1
8990
if self.__inst.location:
9091
location = 'location: [%s]:%s'%(self.__inst.location.file_name, self.__inst.location.line)
91-
self.writer( ' ' * curr_level * self.INDENT_SIZE + location + os.linesep )
92+
self.writer( ' ' * curr_level * self.INDENT_SIZE + location)
9293
artificial = 'artificial: ' + "'%s'" % str(self.__inst.is_artificial)
93-
self.writer( ' ' * curr_level * self.INDENT_SIZE + artificial.ljust( self.JUSTIFY ) + os.linesep )
94+
self.writer( ' ' * curr_level * self.INDENT_SIZE + artificial.ljust( self.JUSTIFY ))
9495
if self.__inst.attributes:
9596
attributes = 'attributes: %s'%(self.__inst.attributes)
96-
self.writer( ' ' * curr_level * self.INDENT_SIZE + attributes + os.linesep )
97+
self.writer( ' ' * curr_level * self.INDENT_SIZE + attributes)
98+
if self.__inst.demangled:
99+
demangled = 'demangled: %s'%(self.__inst.demangled)
100+
self.writer( ' ' * curr_level * self.INDENT_SIZE + demangled)
101+
if self.__inst.mangled:
102+
mangled = 'mangled: %s'%(self.__inst.mangled)
103+
self.writer( ' ' * curr_level * self.INDENT_SIZE + mangled)
104+
97105

98106

99-
def __get_method_signature(self, decl=None):
107+
def print_calldef_info(self, decl=None):
100108
""" Returns function signature: [retval, [arg1, ..., argN]]. """
101109
if None is decl:
102110
decl = self.__inst
@@ -106,46 +114,45 @@ def __get_method_signature(self, decl=None):
106114
retval = decl.return_type.decl_string
107115
args = []
108116
for arg in decl.arguments:
109-
args.append(arg.type.decl_string)
110-
return [retval, args]
117+
args.append(arg.type.decl_string + ' ' + arg.name)
118+
indent = ' ' * (self.level+1) * self.INDENT_SIZE
119+
self.writer( indent + "return type: " + str(retval) )
120+
self.writer( indent + "arguments type: " + ', '.join(args))
121+
if isinstance( decl, calldef.member_calldef_t ):
122+
self.writer( indent + "virtual: " + str(decl.virtuality))
123+
self.writer( indent + "is const: " + str(decl.has_const))
124+
self.writer( indent + "is static: " + str(decl.has_static))
111125

112126
def visit_member_function( self ):
113127
self.print_decl_header()
114-
self.writer( ' ' * (self.level+1) * self.INDENT_SIZE
115-
+ "Signature: " + str( self.__get_method_signature() ) + os.linesep )
128+
self.print_calldef_info()
116129

117130
def visit_constructor( self ):
118131
self.print_decl_header()
119-
self.writer( ' ' * (self.level+1) * self.INDENT_SIZE
120-
+ "Signature: " + str( self.__get_method_signature() ) + os.linesep )
132+
self.print_calldef_info()
121133

122134
if self.__print_details:
123135
self.writer( ' ' * ( self.level + 1 ) * self.INDENT_SIZE
124-
+ 'copy constructor: ' + str(self.__inst.is_copy_constructor)
125-
+ os.linesep )
136+
+ 'copy constructor: ' + str(self.__inst.is_copy_constructor) )
126137

127138
def visit_destructor( self ):
128139
self.print_decl_header()
129140

130141
def visit_member_operator( self ):
131142
self.print_decl_header()
132-
self.writer( ' ' * (self.level+1) * self.INDENT_SIZE
133-
+ "Signature: " + str( self.__get_method_signature() ) + os.linesep )
143+
self.print_calldef_info()
134144

135145
def visit_casting_operator( self ):
136146
self.print_decl_header()
137-
self.writer( ' ' * (self.level+1) * self.INDENT_SIZE
138-
+ "Signature: " + str( self.__get_method_signature() ) + os.linesep )
147+
self.print_calldef_info()
139148

140149
def visit_free_function( self ):
141150
self.print_decl_header()
142-
self.writer( ' ' * (self.level+1) * self.INDENT_SIZE
143-
+ "Signature: " + str( self.__get_method_signature() ) + os.linesep )
151+
self.print_calldef_info()
144152

145153
def visit_free_operator( self ):
146154
self.print_decl_header()
147-
self.writer( ' ' * (self.level+1) * self.INDENT_SIZE
148-
+ "Signature: " + str( self.__get_method_signature() ) + os.linesep )
155+
self.print_calldef_info()
149156

150157
def visit_class_declaration(self ):
151158
self.print_decl_header()
@@ -154,35 +161,35 @@ def visit_class(self ):
154161
self.print_decl_header()
155162
curr_level = self.level + 1
156163
class_type = 'class type: ' + "'%s'" % str(self.__inst.class_type)
157-
self.writer( ' ' * curr_level * self.INDENT_SIZE + class_type.ljust( self.JUSTIFY ) + os.linesep )
164+
self.writer( ' ' * curr_level * self.INDENT_SIZE + class_type.ljust( self.JUSTIFY ))
158165
if self.__print_details:
159166
byte_size = 'size: %d'%(self.__inst.byte_size)
160-
self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_size.ljust( self.JUSTIFY ) + os.linesep )
167+
self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_size.ljust( self.JUSTIFY ))
161168
try:
162169
byte_align = 'align: %d'%(self.__inst.byte_align)
163-
self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_align.ljust( self.JUSTIFY ) + os.linesep )
170+
self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_align.ljust( self.JUSTIFY ))
164171
except NotImplementedError:
165-
self.writer( ' ' * curr_level * self.INDENT_SIZE + "align: not implemented".ljust( self.JUSTIFY ) + os.linesep )
172+
self.writer( ' ' * curr_level * self.INDENT_SIZE + "align: not implemented".ljust( self.JUSTIFY ))
166173

167174
if self.__inst.aliases:
168175
aliases = map( lambda typedef: typedef.name, self.__inst.aliases )
169176
msg = 'aliases: ' + `aliases`
170-
self.writer( ' ' * curr_level * self.INDENT_SIZE + msg.ljust( self.JUSTIFY ) + os.linesep )
177+
self.writer( ' ' * curr_level * self.INDENT_SIZE + msg.ljust( self.JUSTIFY ))
171178

172179
def print_hierarchy(hierarchy_type, classes, curr_level):
173-
self.writer( ' ' * curr_level * self.INDENT_SIZE + hierarchy_type.ljust( self.JUSTIFY ) + os.linesep )
180+
self.writer( ' ' * curr_level * self.INDENT_SIZE + hierarchy_type.ljust( self.JUSTIFY ))
174181
curr_level += 1
175182
for class_ in classes:
176183
class_str = 'class: ' + "'%s'" % str(class_.related_class.decl_string)
177-
self.writer( ' ' * curr_level * self.INDENT_SIZE + class_str.ljust( self.JUSTIFY ) + os.linesep )
184+
self.writer( ' ' * curr_level * self.INDENT_SIZE + class_str.ljust( self.JUSTIFY ))
178185
access = 'access type: ' + "'%s'" % str(class_.access)
179-
self.writer( ' ' * (curr_level + 1)* self.INDENT_SIZE + access.ljust( self.JUSTIFY ) + os.linesep )
186+
self.writer( ' ' * (curr_level + 1)* self.INDENT_SIZE + access.ljust( self.JUSTIFY ))
180187
if not ( None is class_.is_virtual ):
181188
is_virtual = 'virtual inheritance: ' + "'%s'" % str(class_.is_virtual)
182-
self.writer( ' ' * (curr_level + 1)* self.INDENT_SIZE + is_virtual.ljust( self.JUSTIFY ) + os.linesep )
189+
self.writer( ' ' * (curr_level + 1)* self.INDENT_SIZE + is_virtual.ljust( self.JUSTIFY ))
183190

184191
def print_members(members_type, members, curr_level):
185-
self.writer( ' ' * curr_level * self.INDENT_SIZE + members_type.ljust( self.JUSTIFY ) + os.linesep )
192+
self.writer( ' ' * curr_level * self.INDENT_SIZE + members_type.ljust( self.JUSTIFY ))
186193
if self.__recursive:
187194
curr_level += 1
188195
for member in members:
@@ -207,7 +214,7 @@ def visit_enumeration(self):
207214
value_level = ' ' * ( curr_level + 1 )* self.INDENT_SIZE
208215
self.writer( os.linesep )
209216
for name, value in self.__inst.values:
210-
self.writer( value_level + "%s : %s"% (name, value) + os.linesep )
217+
self.writer( value_level + "%s : %s"% (name, value))
211218

212219
def visit_namespace(self ):
213220
self.print_decl_header()
@@ -220,24 +227,24 @@ def visit_namespace(self ):
220227
def visit_typedef(self ):
221228
self.print_decl_header()
222229
curr_level = self.level + 1
223-
self.writer( ' ' * curr_level * self.INDENT_SIZE + 'alias to: ' + self.__inst.type.decl_string + os.linesep )
230+
self.writer( ' ' * curr_level * self.INDENT_SIZE + 'alias to: ' + self.__inst.type.decl_string)
224231

225232
def visit_variable(self ):
226233
self.print_decl_header()
227234
curr_level = self.level + 1
228235
self.writer( ' ' * curr_level * self.INDENT_SIZE + 'type: %s value: %s'%(self.__inst.type.decl_string, self.__inst.value) + os.linesep)
229236
if self.__print_details:
230237
byte_size = 'size: %d'%(self.__inst.type.byte_size)
231-
self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_size.ljust( self.JUSTIFY ) + os.linesep )
238+
self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_size.ljust( self.JUSTIFY ))
232239
try:
233240
byte_align = 'align: %d'%(self.__inst.type.byte_align)
234-
self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_align.ljust( self.JUSTIFY ) + os.linesep )
241+
self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_align.ljust( self.JUSTIFY ))
235242
except NotImplementedError:
236-
self.writer( ' ' * curr_level * self.INDENT_SIZE + "align: not implemented".ljust( self.JUSTIFY ) + os.linesep )
243+
self.writer( ' ' * curr_level * self.INDENT_SIZE + "align: not implemented".ljust( self.JUSTIFY ))
237244
byte_offset = 'offset: %d'%(self.__inst.byte_offset)
238245
self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_offset + os.linesep)
239246

240-
def print_declarations( decls, detailed=True, recursive=True, writer=sys.stdout.write ):
247+
def print_declarations( decls, detailed=True, recursive=True, writer=lambda x: sys.stdout.write( x + os.linesep ) ):
241248
""" Print decl tree rooted at each of the included nodes.
242249
decls - either a single decl or a list of decls.
243250
"""

pygccxml/msvc/pdb/loader.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ def ns_filter( smbl ):
178178
self.logger.debug( 'scanning symbols table - done' )
179179

180180
def __update_decls_tree( self, decl ):
181+
#~ if decl.name == 'money_base' and isinstance( decl, declarations.class_t ):
182+
#~ pdb.set_trace()
181183
smbl = decl.dia_symbols[0]
182184
if smbl.classParentId in self.__id2decl:
183185
self.__adopt_declaration( self.__id2decl[smbl.classParentId], decl )
@@ -208,16 +210,16 @@ def __adopt_declaration( self, parent, decl ):
208210
self.__id2decl[ smbl.symIndexId ] = decl
209211
else:
210212
for other_decl in already_added:
211-
for other_smbl in other_decl.dia_symbols:
212-
if self.__are_symbols_equivalent( other_smbl, smbl ):
213-
other_decl.dia_symbols.append( smbl )
214-
self.__id2decl[ smbl.symIndexId ] = other_decl
215-
return
213+
if self.__is_same_smbls( other_decl, decl ):
214+
other_decl.dia_symbols.append( smbl )
215+
self.__id2decl[ smbl.symIndexId ] = other_decl
216+
return
216217
else:
217218
if isinstance( parent, declarations.namespace_t ):
218219
parent.adopt_declaration( decl )
219220
else:
220221
parent.adopt_declaration( decl, self.__guess_access_type( smbl ) )
222+
self.__id2decl[ smbl.symIndexId ] = decl
221223

222224
def __guess_access_type( self, smbl ):
223225
if enums.CV_access_e.CV_private == smbl.access:
@@ -327,16 +329,18 @@ def dia_global_scope(self):
327329
def global_ns(self):
328330
return self.__global_ns
329331

330-
def __are_symbols_equivalent( self, smbl1, smbl2 ):
331-
result = smbl1.symTag == smbl2.symTag and smbl1.uname == smbl2.uname
332-
if not result:
333-
result = self.__dia_session.symsAreEquiv( smbl1, smbl2 )
334-
if result:
335-
msg = 'Symbols "%s(%d)" and "%s(%d)" are equivalent.'
332+
def __is_same_smbls( self, decl1, decl2 ):
333+
if not( decl1.__class__ is decl2.__class__ ):
334+
return False
335+
if decl1.name == decl2.name:
336+
if isinstance( decl1, declarations.calldef_t ):
337+
#TODO: well, I will have to fix this someday
338+
return False
339+
else:
340+
return True
336341
else:
337-
msg = 'Symbols "%s(%d)" and "%s(%d)" are NOT equivalent.'
338-
self.logger.debug( msg, smbl1.uname, smbl1.symIndexId, smbl2.uname, smbl2.symIndexId )
339-
return result
342+
return False
343+
#~ return self.__dia_session.symsAreEquiv( decl1.dia_symbols[0], decl2.dia_symbols[0] )
340344

341345
def __find_udt( self, name ):
342346
self.logger.debug( 'testing whether name( "%s" ) is UDT symbol' % name )
@@ -530,6 +534,8 @@ def __guess_constructor( self, smbl, calldef_type ):
530534

531535
def __create_calldef( self, smbl ):
532536
self.logger.debug( 'creating calldef "%s"', smbl.uname )
537+
#~ if smbl.uname == 'some_function':
538+
#~ pdb.set_trace()
533539
name_splitter = impl_details.get_name_splitter( smbl.uname )
534540
calldef_type = self.create_type( smbl.type ) #what does happen with constructor?
535541
decl = None
@@ -542,6 +548,10 @@ def __create_calldef( self, smbl ):
542548
decl = self.__guess_constructor( smbl, calldef_type )
543549
if not decl:
544550
decl = declarations.member_function_t()
551+
if smbl.virtual:
552+
decl.virtuality = iif( smbl.pure
553+
, declarations.VIRTUALITY_TYPES.PURE_VIRTUAL
554+
, declarations.VIRTUALITY_TYPES.VIRTUAL )
545555
else:
546556
decl = self.__guess_operator_type(smbl, calldef_type)
547557
if not decl:

unittests/data/core_types.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@ typedef int (*function_ptr)(int, double);
5151
struct exception{};
5252

5353
struct members_pointers_t{
54-
int some_function( double ) const throw( exception );
54+
int some_function( double hi, int i ){
55+
return 0;
56+
}
57+
int some_function( double hi) const throw( exception ){
58+
return 0;
59+
};
5560
int m_some_const_member;
5661
int xxx;
5762
};

unittests/data/msvc_build/all.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ void use_core_types(){
9393
core::types::function_ptr function_ptr_ = 0;
9494
core::types::member_function_ptr_t member_function_ptr_ = 0;
9595

96+
core::types::members_pointers_t members_pointers_inst;
97+
members_pointers_inst.some_function( 0.23 );
98+
members_pointers_inst.some_function( 0.23, 11 );
99+
96100
}
97101

98102
void use_core_ns_join_3(){

0 commit comments

Comments
 (0)