Package pygccxml :: Package declarations :: Module cpptypes

Source Code for Module pygccxml.declarations.cpptypes

  1  # Copyright 2004-2008 Roman Yakovenko. 
  2  # Distributed under the Boost Software License, Version 1.0. (See 
  3  # accompanying file LICENSE_1_0.txt or copy at 
  4  # http://www.boost.org/LICENSE_1_0.txt) 
  5   
  6  """ 
  7  defines classes, that describe C++ types 
  8  """ 
  9   
 10  import compilers 
 11  import algorithms_cache 
12 13 -class type_t(object):
14 """base class for all types"""
15 - def __init__(self):
16 object.__init__( self ) 17 self.cache = algorithms_cache.type_algs_cache_t() 18 self._byte_size = 0 19 self._byte_align = 0 20 self.compiler = None
21
22 - def __str__(self):
23 res = self.decl_string 24 if res[:2]=="::": 25 res = res[2:] 26 return res
27
28 - def __eq__(self, other):
29 if not isinstance( other, type_t ): 30 return False 31 return self.decl_string == other.decl_string
32
33 - def __ne__( self, other):
34 return not self.__eq__( other )
35
36 - def __lt__(self, other):
37 if not isinstance( other, self.__class__ ): 38 return self.__class__.__name__ < other.__class__.__name__ 39 return self.decl_string < other.decl_string
40
41 - def build_decl_string(self, with_defaults=True):
42 raise NotImplementedError()
43 44 @property
45 - def decl_string( self ):
46 return self.build_decl_string()
47 48 @property
49 - def partial_decl_string( self ):
50 return self.build_decl_string( False )
51
52 - def _clone_impl( self ):
53 raise NotImplementedError()
54
55 - def clone( self ):
56 "returns new instance of the type" 57 answer = self._clone_impl() 58 return answer
59
60 - def _get_byte_size(self):
61 return self._byte_size
62 - def _set_byte_size( self, new_byte_size ):
63 self._byte_size = new_byte_size
64 byte_size = property( _get_byte_size, _set_byte_size 65 , doc="Size of this type in bytes @type: int") 66
67 - def _get_byte_align(self):
68 if self.compiler == compilers.MSVC_PDB_9: 69 compilers.on_missing_functionality( self.compiler, "byte align" ) 70 return self._byte_align
71 - def _set_byte_align( self, new_byte_align ):
72 self._byte_align = new_byte_align
73 byte_align = property( _get_byte_align, _set_byte_align 74 , doc="Alignment of this type in bytes @type: int")
75
76 77 #There are cases when GCC-XML reports something like this 78 #<Unimplemented id="_9482" tree_code="188" tree_code_name="template_type_parm" node="0xcc4d5b0"/> 79 #In this case I will use this as type 80 81 82 -class dummy_type_t( type_t ):
83 """provides L{type_t} interface for a string, that defines C++ type. 84 85 This class could be very useful in the code generator. 86 """
87 - def __init__( self, decl_string ):
88 type_t.__init__( self ) 89 self._decl_string = decl_string
90
91 - def build_decl_string(self, with_defaults=True):
92 return self._decl_string
93
94 - def _clone_impl( self ):
95 return dummy_type_t( self._decl_string )
96
97 -class unknown_t( type_t ):
98 "type, that represents all C++ types, that could not be parsed by GCC-XML"
99 - def __init__( self ):
100 type_t.__init__( self )
101
102 - def build_decl_string(self, with_defaults=True):
103 return '?unknown?'
104
105 - def _clone_impl( self ):
106 return self
107
108 -class ellipsis_t( type_t ):
109 """type, that represents "..." in function definition"""
110 - def __init__( self ):
111 type_t.__init__( self )
112
113 - def build_decl_string(self, with_defaults=True):
114 return '...'
115
116 - def _clone_impl( self ):
117 return self
118
119 ################################################################################ 120 ## Fundamental types: 121 122 -class fundamental_t( type_t ):
123 """base class for all fundamental, build-in types"""
124 - def __init__( self, name ):
125 type_t.__init__( self ) 126 self._name = name
127
128 - def build_decl_string(self, with_defaults=True):
129 return self._name
130
131 - def _clone_impl( self ):
132 return self
133
134 -class java_fundamental_t( fundamental_t ):
135 """base class for all JNI defined fundamental types"""
136 - def __init__( self, name ):
138
139 -class void_t( fundamental_t ):
140 """represents void type""" 141 CPPNAME = 'void'
142 - def __init__( self ):
144
145 -class char_t( fundamental_t ):
146 """represents char type""" 147 CPPNAME = 'char'
148 - def __init__( self ):
150
151 -class signed_char_t( fundamental_t ):
152 """represents signed char type""" 153 CPPNAME = 'signed char'
154 - def __init__( self ):
156
157 -class unsigned_char_t( fundamental_t ):
158 """represents unsigned char type""" 159 CPPNAME = 'unsigned char'
160 - def __init__( self ):
162
163 -class wchar_t( fundamental_t ):
164 """represents wchar_t type""" 165 CPPNAME = 'wchar_t'
166 - def __init__( self ):
168
169 -class short_int_t( fundamental_t ):
170 """represents short int type""" 171 CPPNAME = 'short int'
172 - def __init__( self ):
174
175 -class short_unsigned_int_t( fundamental_t ):
176 """represents short unsigned int type""" 177 CPPNAME = 'short unsigned int'
178 - def __init__( self ):
180
181 -class bool_t( fundamental_t ):
182 """represents bool type""" 183 CPPNAME = 'bool'
184 - def __init__( self ):
186
187 -class int_t( fundamental_t ):
188 """represents int type""" 189 CPPNAME = 'int'
190 - def __init__( self ):
192
193 -class unsigned_int_t( fundamental_t ):
194 """represents unsigned int type""" 195 CPPNAME = 'unsigned int'
196 - def __init__( self ):
198
199 -class long_int_t( fundamental_t ):
200 """represents long int type""" 201 CPPNAME = 'long int'
202 - def __init__( self ):
204
205 -class long_unsigned_int_t( fundamental_t ):
206 """represents long unsigned int type""" 207 CPPNAME = 'long unsigned int'
208 - def __init__( self ):
210
211 -class long_long_int_t( fundamental_t ):
212 """represents long long int type""" 213 CPPNAME = 'long long int'
214 - def __init__( self ):
216
217 -class long_long_unsigned_int_t( fundamental_t ):
218 """represents long long unsigned int type""" 219 CPPNAME = 'long long unsigned int'
220 - def __init__( self ):
222
223 -class float_t( fundamental_t ):
224 """represents float type""" 225 CPPNAME = 'float'
226 - def __init__( self ):
228
229 -class double_t( fundamental_t ):
230 """represents double type""" 231 CPPNAME = 'double'
232 - def __init__( self ):
234
235 -class long_double_t( fundamental_t ):
236 """represents long double type""" 237 CPPNAME = 'long double'
238 - def __init__( self ):
240
241 -class complex_double_t( fundamental_t ):
242 """represents complex double type""" 243 CPPNAME = 'complex double'
244 - def __init__( self ):
246
247 -class complex_long_double_t( fundamental_t ):
248 """represents complex long double type""" 249 CPPNAME = 'complex long double'
250 - def __init__( self ):
252
253 -class complex_float_t( fundamental_t ):
254 """represents complex float type""" 255 CPPNAME = 'complex float'
256 - def __init__( self ):
258
259 -class jbyte_t( java_fundamental_t ):
260 """represents jbyte type""" 261 JNAME = 'jbyte'
262 - def __init__( self ):
264
265 -class jshort_t( java_fundamental_t ):
266 """represents jshort type""" 267 JNAME = 'jshort'
268 - def __init__( self ):
270
271 -class jint_t( java_fundamental_t ):
272 """represents jint type""" 273 JNAME = 'jint'
274 - def __init__( self ):
276
277 -class jlong_t( java_fundamental_t ):
278 """represents jlong type""" 279 JNAME = 'jlong'
280 - def __init__( self ):
282
283 -class jfloat_t( java_fundamental_t ):
284 """represents jfloat type""" 285 JNAME = 'jfloat'
286 - def __init__( self ):
288
289 -class jdouble_t( java_fundamental_t ):
290 """represents jdouble type""" 291 JNAME = 'jdouble'
292 - def __init__( self ):
294
295 -class jchar_t( java_fundamental_t ):
296 """represents jchar type""" 297 JNAME = 'jchar'
298 - def __init__( self ):
300
301 -class jboolean_t( java_fundamental_t ):
302 """represents jboolean type""" 303 JNAME = 'jboolean'
304 - def __init__( self ):
306 307 FUNDAMENTAL_TYPES = { 308 void_t.CPPNAME : void_t() 309 , char_t.CPPNAME : char_t() 310 , signed_char_t.CPPNAME : signed_char_t() 311 , unsigned_char_t.CPPNAME : unsigned_char_t() 312 , wchar_t.CPPNAME : wchar_t() 313 , short_int_t.CPPNAME : short_int_t() 314 , 'signed ' + short_int_t.CPPNAME : short_int_t() 315 , short_unsigned_int_t.CPPNAME : short_unsigned_int_t() 316 , bool_t.CPPNAME : bool_t() 317 , int_t.CPPNAME : int_t() 318 , 'signed ' + int_t.CPPNAME : int_t() 319 , unsigned_int_t.CPPNAME : unsigned_int_t() 320 , long_int_t.CPPNAME : long_int_t() 321 , long_unsigned_int_t.CPPNAME : long_unsigned_int_t() 322 , long_long_int_t.CPPNAME : long_long_int_t() 323 , long_long_unsigned_int_t.CPPNAME : long_long_unsigned_int_t() 324 , float_t.CPPNAME : float_t() 325 , double_t.CPPNAME : double_t() 326 , long_double_t.CPPNAME : long_double_t() 327 , complex_long_double_t.CPPNAME : complex_long_double_t() 328 , complex_double_t.CPPNAME : complex_double_t() 329 , complex_float_t.CPPNAME : complex_float_t() 330 ##adding java types 331 , jbyte_t.JNAME : jbyte_t() 332 , jshort_t.JNAME : jshort_t() 333 , jint_t.JNAME : jint_t() 334 , jlong_t.JNAME : jlong_t() 335 , jfloat_t.JNAME : jfloat_t() 336 , jdouble_t.JNAME : jdouble_t() 337 , jchar_t.JNAME : jchar_t() 338 , jboolean_t.JNAME : jboolean_t() 339 , '__java_byte' : jbyte_t() 340 , '__java_short' : jshort_t() 341 , '__java_int' : jint_t() 342 , '__java_long' : jlong_t() 343 , '__java_float' : jfloat_t() 344 , '__java_double' : jdouble_t() 345 , '__java_char' : jchar_t() 346 , '__java_boolean' : jboolean_t() 347 } 348 """ 349 defines a mapping between fundamental type name and its synonym to the instance 350 of class that describes the type 351 """
352 353 ################################################################################ 354 ## Compaund types: 355 356 -class compound_t( type_t ):
357 """class that allows to represent compound types like C{const int*}"""
358 - def __init__( self, base ):
359 type_t.__init__( self ) 360 self._base = base
361
362 - def _get_base(self):
363 return self._base
364 - def _set_base(self, new_base):
365 self._base = new_base
366 367 base = property( _get_base, _set_base 368 , doc="reference to internal/base class")
369
370 -class volatile_t( compound_t ):
371 """represents C{volatile whatever} type"""
372 - def __init__( self, base ):
373 compound_t.__init__( self, base)
374
375 - def build_decl_string(self, with_defaults=True):
376 return 'volatile ' + self.base.build_decl_string(with_defaults)
377
378 - def _clone_impl( self ):
379 return volatile_t( self.base.clone() )
380
381 -class restrict_t( compound_t ):
382 """represents C{restrict whatever} type""" 383 384 #The restrict keyword can be considered an extension to the strict aliasing 385 #rule. It allows the programmer to declare that pointers which share the same 386 #type (or were otherwise validly created) do not alias eachother. By using 387 #restrict the programmer can declare that any loads and stores through the 388 #qualified pointer (or through another pointer copied either directly or 389 #indirectly from the restricted pointer) are the only loads and stores to 390 #the same address during the lifetime of the pointer. In other words, the 391 #pointer is not aliased by any pointers other than its own copies. 392
393 - def __init__( self, base ):
394 compound_t.__init__( self, base)
395
396 - def build_decl_string(self, with_defaults=True):
397 return '__restrict__ ' + self.base.build_decl_string( with_defaults )
398
399 - def _clone_impl( self ):
400 return restrict_t( self.base.clone() )
401
402 -class const_t( compound_t ):
403 """represents C{whatever const} type"""
404 - def __init__( self, base ):
405 compound_t.__init__( self, base )
406
407 - def build_decl_string(self, with_defaults=True):
408 return self.base.build_decl_string(with_defaults) + ' const'
409
410 - def _clone_impl( self ):
411 return const_t( self.base.clone() )
412
413 -class pointer_t( compound_t ):
414 """represents C{whatever*} type"""
415 - def __init__( self, base ):
416 compound_t.__init__( self, base )
417
418 - def build_decl_string(self, with_defaults=True):
419 return self.base.build_decl_string( with_defaults ) + ' *'
420
421 - def _clone_impl( self ):
422 return pointer_t( self.base.clone() )
423
424 -class reference_t( compound_t ):
425 """represents C{whatever&} type"""
426 - def __init__( self, base ):
427 compound_t.__init__( self, base)
428
429 - def build_decl_string(self, with_defaults=True):
430 return self.base.build_decl_string(with_defaults) + ' &'
431
432 - def _clone_impl( self ):
433 return reference_t( self.base.clone() )
434
435 -class array_t( compound_t ):
436 """represents C++ array type""" 437 SIZE_UNKNOWN = -1
438 - def __init__( self, base, size ):
439 compound_t.__init__( self, base ) 440 self._size = size
441
442 - def _get_size(self):
443 return self._size
444 - def _set_size(self, size):#sometimes there is a need to update the size of the array
445 self.cache.reset() 446 self._size = size
447 size = property( _get_size, _set_size, 448 doc="returns array size" ) 449
450 - def build_decl_string(self, with_defaults=True):
451 return self.base.build_decl_string(with_defaults) + '[%d]' % self.size
452
453 - def _clone_impl( self ):
454 return array_t( self.base.clone(), self.size )
455
456 -class calldef_type_t( object ):
457 """base class for all types that describes "callable" declaration"""
458 - def __init__( self, return_type=None, arguments_types=None ):
459 object.__init__( self ) 460 self._return_type = return_type 461 if arguments_types is None: 462 arguments_types = [] 463 self._arguments_types = arguments_types
464
465 - def _get_return_type(self):
466 return self._return_type
467 - def _set_return_type(self, new_return_type):
468 self._return_type = new_return_type
469 return_type = property( _get_return_type, _set_return_type 470 , doc="reference to L{return type<type_t>}") 471
472 - def _get_arguments_types(self):
473 return self._arguments_types
474 - def _set_arguments_types(self, new_arguments_types):
475 self._arguments_types = new_arguments_types
476 arguments_types = property( _get_arguments_types, _set_arguments_types 477 , doc="list of argument L{types<type_t>}") 478 479 @property
480 - def has_ellipsis( self ):
481 return self.arguments_types and isinstance( self.arguments_types[-1], ellipsis_t )
482
483 484 -class free_function_type_t( type_t, calldef_type_t ):
485 """describes free function type""" 486 NAME_TEMPLATE = '%(return_type)s (*)( %(arguments)s )' 487 TYPEDEF_NAME_TEMPLATE = '%(return_type)s ( *%(typedef_name)s )( %(arguments)s )'
488 - def __init__( self, return_type=None, arguments_types=None ):
491 492 @staticmethod
493 - def create_decl_string( return_type, arguments_types, with_defaults=True ):
494 """ 495 returns free function type 496 497 @param return_type: function return type 498 @type return_type: L{type_t} 499 500 @param arguments_types: list of argument L{type<type_t>} 501 502 @return: L{free_function_type_t} 503 """ 504 return free_function_type_t.NAME_TEMPLATE % { 505 'return_type' : return_type.build_decl_string( with_defaults ) 506 , 'arguments' : ','.join( map( lambda x: x.build_decl_string( with_defaults ) 507 , arguments_types ) ) }
508
509 - def build_decl_string(self, with_defaults=True):
510 return self.create_decl_string( self.return_type, self.arguments_types, with_defaults )
511
512 - def _clone_impl( self ):
513 rt_clone = None 514 if self.return_type: 515 rt_clone = self.return_type.clone() 516 return free_function_type_t( rt_clone 517 , [ arg.clone() for arg in self.arguments_types ] )
518 519 #TODO: create real typedef
520 - def create_typedef( self, typedef_name, unused=None, with_defaults=True):
521 """returns string, that contains valid C++ code, that defines typedef to function type 522 523 @param name: the desired name of typedef 524 """ 525 #unused argument simplifies user code 526 return free_function_type_t.TYPEDEF_NAME_TEMPLATE % { 527 'typedef_name' : typedef_name 528 , 'return_type' : self.return_type.build_decl_string( with_defaults ) 529 , 'arguments' : ','.join( map( lambda x: x.build_decl_string( with_defaults ) 530 , self.arguments_types ) ) }
531
532 -class member_function_type_t( type_t, calldef_type_t ):
533 """describes member function type""" 534 NAME_TEMPLATE = '%(return_type)s ( %(class)s::* )( %(arguments)s ) %(has_const)s' 535 TYPEDEF_NAME_TEMPLATE = '%(return_type)s ( %(class)s::*%(typedef_name)s )( %(arguments)s ) %(has_const)s' 536
537 - def __init__( self, class_inst=None, return_type=None, arguments_types=None, has_const=False):
538 type_t.__init__(self) 539 calldef_type_t.__init__( self, return_type, arguments_types ) 540 self._has_const = has_const 541 self._class_inst = class_inst
542
543 - def _get_has_const(self):
544 return self._has_const
545 - def _set_has_const(self, has_const ):
546 self._has_const = has_const
547 has_const = property( _get_has_const, _set_has_const 548 , doc="describes, whether function has const modifier") 549
550 - def _get_class_inst(self):
551 return self._class_inst
552 - def _set_class_inst(self, class_inst ):
553 self._class_inst = class_inst
554 class_inst = property( _get_class_inst, _set_class_inst 555 ,doc="reference to parent L{class<declaration_t>}" ) 556 557 #TODO: create real typedef
558 - def create_typedef( self, typedef_name, class_alias=None, with_defaults=True):
559 """creates typedef to the function type 560 561 @param typedef_name: desired type name 562 @return: string 563 """ 564 has_const_str = '' 565 if self.has_const: 566 has_const_str = 'const' 567 if None is class_alias: 568 if with_defaults: 569 class_alias = self.class_inst.decl_string 570 else: 571 class_alias = self.class_inst.partial_decl_string 572 return member_function_type_t.TYPEDEF_NAME_TEMPLATE % { 573 'typedef_name' : typedef_name 574 , 'return_type' : self.return_type.build_decl_string( with_defaults ) 575 , 'class' : class_alias 576 , 'arguments' : ','.join( map( lambda x: x.build_decl_string(with_defaults) 577 , self.arguments_types ) ) 578 , 'has_const' : has_const_str }
579
580 - def create(self):
581 return self.build_decl_string( self.return_type 582 , self.class_inst.decl_string 583 , self.arguments_types 584 , self.has_const )
585 586 587 @staticmethod
588 - def create_decl_string(return_type, class_decl_string, arguments_types, has_const, with_defaults=True):
589 has_const_str = '' 590 if has_const: 591 has_const_str = 'const' 592 return_type_decl_string = '' 593 if return_type: 594 return_type_decl_string = return_type.build_decl_string( with_defaults ) 595 return member_function_type_t.NAME_TEMPLATE % { 596 'return_type' : return_type_decl_string 597 , 'class' : class_decl_string 598 , 'arguments' : ','.join( map( lambda x: x.build_decl_string(with_defaults) 599 , arguments_types ) ) 600 , 'has_const' : has_const_str }
601
602 - def build_decl_string(self, with_defaults=True):
603 return self.create_decl_string( self.return_type 604 , self.class_inst.decl_string 605 , self.arguments_types 606 , self.has_const 607 , with_defaults)
608
609 - def _clone_impl( self ):
610 rt_clone = None 611 if self.return_type: 612 rt_clone = self.return_type.clone() 613 614 return member_function_type_t( self.class_inst 615 , rt_clone 616 , [ arg.clone() for arg in self.arguments_types ] 617 , self.has_const )
618
619 620 -class member_variable_type_t( compound_t ):
621 """describes member variable type""" 622 NAME_TEMPLATE = '%(type)s ( %(class)s::* )'
623 - def __init__( self, class_inst=None, variable_type=None ):
624 compound_t.__init__(self, class_inst) 625 self._mv_type = variable_type
626
627 - def _get_variable_type(self):
628 return self._mv_type
629 - def _set_variable_type(self, new_type):
630 self._mv_type = new_type
631 variable_type = property( _get_variable_type, _set_variable_type 632 , doc="describes member variable L{type<type_t>}") 633
634 - def build_decl_string(self, with_defaults=True):
635 return self.NAME_TEMPLATE % { 'type' : self.variable_type.build_decl_string(with_defaults) 636 , 'class' : self.base.build_decl_string(with_defaults) }
637
638 - def _clone_impl( self ):
641
642 643 ################################################################################ 644 ## declarated types: 645 646 -class declarated_t( type_t ):
647 """class that binds between to hierarchies: L{type_t} and L{declaration_t}"""
648 - def __init__( self, declaration ):
649 type_t.__init__( self ) 650 self._declaration = declaration
651
652 - def _get_declaration(self):
653 return self._declaration
654 - def _set_declaration(self, new_declaration):
655 self._declaration = new_declaration
656 declaration = property( _get_declaration, _set_declaration 657 , doc="reference to L{declaration<declaration_t>}") 658
659 - def build_decl_string(self, with_defaults=True):
660 if with_defaults: 661 return self._declaration.decl_string 662 else: 663 return self._declaration.partial_decl_string
664
665 - def _clone_impl( self ):
666 return declarated_t( self._declaration )
667 668 @property
669 - def byte_size (self):
670 "Size of this type in bytes @type: int" 671 return self._declaration.byte_size
672 673 @property
674 - def byte_align (self):
675 "alignment of this type in bytes @type: int" 676 return self._declaration.byte_align
677
678 -class type_qualifiers_t( object ):
679 """contains additional information about type: mutable, static, extern"""
680 - def __init__(self, has_static=False, has_mutable=False ):
681 self._has_static = has_static 682 self._has_mutable = has_mutable
683
684 - def __eq__(self, other):
685 if not isinstance( other, type_qualifiers_t ): 686 return False 687 return self.has_static == other.has_static \ 688 and self.has_mutable == other.has_mutable
689
690 - def __ne__( self, other):
691 return not self.__eq__( other )
692
693 - def __lt__(self, other):
694 if not isinstance( other, type_qualifiers_t ): 695 return object.__lt__( self, other ) 696 return self.has_static < other.has_static \ 697 and self.has_mutable < other.has_mutable
698
699 - def _get_has_static(self):
700 return self._has_static
701 - def _set_has_static(self, has_static ):
702 self._has_static = has_static
703 has_static = property( _get_has_static, _set_has_static ) 704 has_extern = has_static #synonim to static 705
706 - def _get_has_mutable(self):
707 return self._has_mutable
708 - def _set_has_mutable(self, has_mutable ):
709 self._has_mutable = has_mutable
710 has_mutable = property( _get_has_mutable, _set_has_mutable )
711