Package pygccxml :: Package parser :: Module linker |

# Source Code for Module pygccxml.parser.linker

      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  import types
      7  from pygccxml.declarations import *
      8
      9 -class linker_t( decl_visitor_t, type_visitor_t, object ):
     10 -    def __init__( self, decls, types, access, membership, files ):
     11          decl_visitor_t.__init__(self)
     12          type_visitor_t.__init__(self)
     13          object.__init__(self)
     14
     15          self.__decls = decls
     16          self.__types = types
     17          self.__access = access
     18          self.__membership = membership
     19          self.__files = files
     20          self.__inst = None
     21
     22          self.__compiler = None
     23          if self.__decls:
     24              for d in self.__decls.itervalues():
     25                  self.__compiler = d.compiler
     26                  break
     27
     28 -    def _get_inst(self):
     29          return self.__inst
     30 -    def _set_inst(self, inst):
     31          self.__inst = inst
     32          #use inst, to reduce attribute access time
     33          if isinstance( inst, declaration_t ) and inst.location:
     34              inst.location.file_name = self.__files[inst.location.file_name]
     35      instance = property( _get_inst, _set_inst )
     36
     37 -    def __link_type(self, type_id):
     38          if type_id is None:
     39              return None #in some situations type_id is None, return_type of constructor or destructor
     40          elif self.__types.has_key( type_id ):
     41              return self.__types[type_id]
     42          elif self.__decls.has_key( type_id ):
     43              base = declarated_t( declaration=self.__decls[ type_id ] )
     44              self.__types[type_id] = base
     45              return base
     46          elif '...' == type_id:
     47              return ellipsis_t()
     48          else:
     49              return unknown_t()
     50
     51 -    def __link_compound_type(self):
     52          self.__inst.base = self.__link_type( self.__inst.base )
     53
     54 -    def __link_members(self):
     55          if not self.__membership.has_key( id(self.__inst) ):
     56              return
     57          for member in self.__membership[ id(self.__inst) ]:
     58              if not self.__access.has_key( member ):
     59                  continue
     60              access = self.__access[member]
     61              if not self.__decls.has_key( member ):
     62                  continue
     63              decl = self.__decls[member]
     64              if isinstance( self.__inst, class_t ):
     65                  self.__inst.adopt_declaration( decl, access )
     66              else:
     67                  self.__inst.adopt_declaration( decl )
     68
     69 -    def __link_calldef(self):
     70          self.__inst.return_type = self.__link_type( self.__inst.return_type )
     71          if isinstance( self.__inst, type_t ):
     72              linked_args = [ self.__link_type( arg ) for arg in self.__inst.arguments_types ]
     73              self.__inst.arguments_types = linked_args
     74          else:
     75              for arg in self.__inst.arguments:
     76                  arg.type = self.__link_type(arg.type)
     77              for index in range( len( self.__inst.exceptions ) ):
     78                  try:
     79                      self.__inst.exceptions[index] = self.__decls[ self.__inst.exceptions[index] ]
     80                  except KeyError:
     81                      self.__inst.exceptions[index] = self.__link_type( self.__inst.exceptions[index] )
     82
     83 -    def visit_member_function( self ):
     84          self.__link_calldef()
     85
     86 -    def visit_constructor( self ):
     87          self.__link_calldef()
     88
     89 -    def visit_destructor( self ):
     90          self.__link_calldef()
     91
     92 -    def visit_member_operator( self ):
     93          self.__link_calldef()
     94
     95 -    def visit_casting_operator( self ):
     96          self.__link_calldef()
     97          #will be fixed by patcher. It is needed because of demangled name taken into account
     98          #self.__inst._name = 'operator ' + self.__inst.return_type.decl_string
     99
    100 -    def visit_free_function( self ):
    101          self.__link_calldef()
    102
    103 -    def visit_free_operator( self ):
    104          self.__link_calldef()
    105
    106 -    def visit_class_declaration(self ):
    107          pass
    108
    109 -    def visit_class(self ):
    110          self.__link_members()
    111          #GCC-XML sometimes generates constructors with names that does not match
    112          #class name. I think this is because those constructors are compiler
    113          #generated. I need to find out more about this and to talk with Brad
    114
    115          new_name = self.__inst._name
    116          if templates.is_instantiation( new_name ):
    117              new_name = templates.name( new_name )
    118
    119          for decl in self.__inst.declarations:
    120              if not isinstance( decl, constructor_t ):
    121                  continue
    122              if '.' in decl._name or '$' in decl._name:
    123                  decl._name = new_name
    124
    125          bases = self.__inst.bases.split()
    126          self.__inst.bases = []
    127          for base in bases:
    128              #it could be "_5" or "protected:_5"
    129              data = base.split(':')
    130              base_decl = self.__decls[ data[-1] ]
    131              access = ACCESS_TYPES.PUBLIC
    132              if 2 == len( data ):
    133                  access = data[0]
    134              self.__inst.bases.append( hierarchy_info_t( base_decl, access ) )
    135              base_decl.derived.append( hierarchy_info_t( self.__inst, access ) )
    136
    137 -    def visit_enumeration(self ):
    138          pass
    139
    140 -    def visit_namespace(self ):
    141          self.__link_members()
    142
    143 -    def visit_typedef(self ):
    144          self.__inst.type = self.__link_type(self.__inst.type)
    145
    146 -    def visit_variable(self ):
    147          self.__inst.type = self.__link_type(self.__inst.type)
    148
    149 -    def visit_void( self ):
    150          pass
    151
    152 -    def visit_char( self ):
    153          pass
    154
    155 -    def visit_signed_char( self ):
    156          pass
    157
    158 -    def visit_unsigned_char( self ):
    159          pass
    160
    161 -    def visit_wchar( self ):
    162          pass
    163
    164 -    def visit_short_int( self ):
    165          pass
    166
    167 -    def visit_short_unsigned_int( self ):
    168          pass
    169
    170 -    def visit_bool( self ):
    171          pass
    172
    173 -    def visit_int( self ):
    174          pass
    175
    176 -    def visit_unsigned_int( self ):
    177          pass
    178
    179 -    def visit_long_int( self ):
    180          pass
    181
    182 -    def visit_long_unsigned_int( self ):
    183          pass
    184
    185 -    def visit_long_long_int( self ):
    186          pass
    187
    188 -    def visit_long_long_unsigned_int( self ):
    189          pass
    190
    191 -    def visit_float( self ):
    192          pass
    193
    194 -    def visit_double( self ):
    195          pass
    196
    197 -    def visit_long_double( self ):
    198          pass
    199
    200 -    def visit_complex_long_double(self):
    201          pass
    202
    203 -    def visit_complex_double(self):
    204          pass
    205
    206 -    def visit_complex_float(self):
    207          pass
    208
    209 -    def visit_jbyte(self):
    210          pass
    211
    212 -    def visit_jshort(self):
    213          pass
    214
    215 -    def visit_jint(self):
    216          pass
    217
    218 -    def visit_jlong(self):
    219          pass
    220
    221 -    def visit_jfloat(self):
    222          pass
    223
    224 -    def visit_jdouble(self):
    225          pass
    226
    227 -    def visit_jchar(self):
    228          pass
    229
    230 -    def visit_jboolean(self):
    231          pass
    232
    233 -    def visit_volatile( self ):
    234          self.__link_compound_type()
    235
    236 -    def visit_const( self ):
    237          self.__link_compound_type()
    238
    239 -    def visit_pointer( self ):
    240          if '0.9' in self.__compiler and isinstance( self.__inst.base, member_variable_type_t ):
    241              original_inst = self.__inst
    242              self.__inst = self.__inst.base
    243              self.visit_member_variable_type()
    244              self.__inst = original_inst
    245          else:
    246              self.__link_compound_type()
    247
    248 -    def visit_reference( self ):
    249          self.__link_compound_type()
    250
    251 -    def visit_array( self ):
    252          self.__link_compound_type()
    253
    254 -    def visit_free_function_type( self ):
    255          self.__link_calldef()
    256
    257 -    def visit_member_function_type( self ):
    258          self.__link_calldef()
    259          if isinstance( self.__inst, type_t ):
    260              self.__inst.class_inst = self.__link_type( self.__inst.class_inst )
    261
    262 -    def visit_member_variable_type( self ):
    263          self.__inst.variable_type = self.__link_type( self.__inst.variable_type )
    264          self.__link_compound_type()
    265
    266 -    def visit_declarated( self ):
    267          if isinstance( self.__inst.declaration, types.StringTypes ):
    268              self.__inst.declaration = self.__decls[self.__inst.declaration]
    269
    270 -    def visit_restrict( self ):
    271          self.__link_compound_type()
    272