Example #1
0
def is_same_return_type( f1, f2 ):
    #covariant returns
    #The return type of an overriding function shall be either identical to the
    #return type of the overridden function or covariant with the classes of the
    #functions. If a function D::f overrides a function B::f, the return types
    #of the functions are covariant if they satisfy the following criteria:

    #* both are pointers to classes or references to classes
    #* the class in the return type of B::f is the same class as the class in
    #  the return type of D::f or, is an unambiguous direct or indirect base
    #  class of the class in the return type of D::f and is accessible in D
    #* both pointers or references have the same cv-qualification and the class
    #  type in the return type of D::f has the same cv-qualification as or less
    #  cv-qualification than the class type in the return type of B::f.

    if not f1.__class__ is f2.__class__:
        #it should be assert
        return False #2 different calldef types
    if not isinstance( f1, calldef.member_calldef_t ):
        #for free functions we compare return types as usual
        return type_traits.is_same( f1.return_type, f2.return_type)
    if f1.virtuality == calldef.VIRTUALITY_TYPES.NOT_VIRTUAL \
       or f2.virtuality == calldef.VIRTUALITY_TYPES.NOT_VIRTUAL:
        #for non-virtual member functions we compare types as usual
        return type_traits.is_same( f1.return_type, f2.return_type)
    rt1 = f1.return_type
    rt2 = f2.return_type
    if type_traits.is_pointer( rt1 ) and type_traits.is_pointer( rt2 ):
        rt1 = type_traits.remove_pointer( rt1 )
        rt2 = type_traits.remove_pointer( rt2 )
    elif type_traits.is_reference( rt1 ) and type_traits.is_reference( rt2 ):
        rt1 = type_traits.remove_reference( rt1 )
        rt2 = type_traits.remove_reference( rt2 )
    else:
        return type_traits.is_same( f1.return_type, f2.return_type)
    if ( type_traits.is_const( rt1 ) and type_traits.is_const( rt2 ) ) \
       or ( False == type_traits.is_const( rt1 ) and False == type_traits.is_const( rt2 ) ):
        rt1 = type_traits.remove_const( rt1 )
        rt2 = type_traits.remove_const( rt2 )
    else:
        return False
    if not type_traits.is_class( rt1 ) or not type_traits.is_class( rt2 ):
        return type_traits.is_same( rt1, rt2 )
    c1 = type_traits.class_traits.get_declaration( rt1 )
    c2 = type_traits.class_traits.get_declaration( rt2 )
    if c1.class_type == class_declaration.CLASS_TYPES.UNION \
       or c2.class_type == class_declaration.CLASS_TYPES.UNION:
        return type_traits.is_same( rt1, rt2 )
    return type_traits.is_same( c1, c2 ) \
           or type_traits.is_base_and_derived( c1, c2 ) \
           or type_traits.is_base_and_derived( c2, c1 )
Example #2
0
def is_same_return_type(f1, f2):
    #covariant returns
    #The return type of an overriding function shall be either identical to the
    #return type of the overridden function or covariant with the classes of the
    #functions. If a function D::f overrides a function B::f, the return types
    #of the functions are covariant if they satisfy the following criteria:

    #* both are pointers to classes or references to classes
    #* the class in the return type of B::f is the same class as the class in
    #  the return type of D::f or, is an unambiguous direct or indirect base
    #  class of the class in the return type of D::f and is accessible in D
    #* both pointers or references have the same cv-qualification and the class
    #  type in the return type of D::f has the same cv-qualification as or less
    #  cv-qualification than the class type in the return type of B::f.

    if not f1.__class__ is f2.__class__:
        #it should be assert
        return False  #2 different calldef types
    if not isinstance(f1, calldef.member_calldef_t):
        #for free functions we compare return types as usual
        return type_traits.is_same(f1.return_type, f2.return_type)
    if f1.virtuality == calldef.VIRTUALITY_TYPES.NOT_VIRTUAL \
       or f2.virtuality == calldef.VIRTUALITY_TYPES.NOT_VIRTUAL:
        #for non-virtual member functions we compare types as usual
        return type_traits.is_same(f1.return_type, f2.return_type)
    rt1 = f1.return_type
    rt2 = f2.return_type
    if type_traits.is_pointer(rt1) and type_traits.is_pointer(rt2):
        rt1 = type_traits.remove_pointer(rt1)
        rt2 = type_traits.remove_pointer(rt2)
    elif type_traits.is_reference(rt1) and type_traits.is_reference(rt2):
        rt1 = type_traits.remove_reference(rt1)
        rt2 = type_traits.remove_reference(rt2)
    else:
        return type_traits.is_same(f1.return_type, f2.return_type)
    if ( type_traits.is_const( rt1 ) and type_traits.is_const( rt2 ) ) \
       or ( False == type_traits.is_const( rt1 ) and False == type_traits.is_const( rt2 ) ):
        rt1 = type_traits.remove_const(rt1)
        rt2 = type_traits.remove_const(rt2)
    else:
        return False
    if not type_traits.is_class(rt1) or not type_traits.is_class(rt2):
        return type_traits.is_same(rt1, rt2)
    c1 = type_traits.class_traits.get_declaration(rt1)
    c2 = type_traits.class_traits.get_declaration(rt2)
    if c1.class_type == class_declaration.CLASS_TYPES.UNION \
       or c2.class_type == class_declaration.CLASS_TYPES.UNION:
        return type_traits.is_same(rt1, rt2)
    return type_traits.is_same( c1, c2 ) \
           or type_traits.is_base_and_derived( c1, c2 ) \
           or type_traits.is_base_and_derived( c2, c1 )
Example #3
0
 def find_noncopyable_vars( self ):
     """returns list of all `noncopyable` variables"""
     import type_traits as tt#prevent cyclic dependencies
     logger = utils.loggers.cxx_parser
     mvars = self.vars( lambda v: not v.type_qualifiers.has_static, recursive=False, allow_empty=True )
     noncopyable_vars = []
     for mvar in mvars:
         type_ = tt.remove_reference( mvar.type )
         if tt.is_const( type_ ):
             no_const = tt.remove_const( type_ )
             if tt.is_fundamental( no_const ) or tt.is_enum( no_const):
                 logger.debug( "__contains_noncopyable_mem_var - %s - TRUE - containes const member variable - fundamental or enum" % self.decl_string )
                 noncopyable_vars.append( mvar )
             if tt.is_class( no_const ):
                 logger.debug( "__contains_noncopyable_mem_var - %s - TRUE - containes const member variable - class" % self.decl_string )
                 noncopyable_vars.append( mvar )
             if tt.is_array( no_const ):
                 logger.debug( "__contains_noncopyable_mem_var - %s - TRUE - containes const member variable - array" % self.decl_string )
                 noncopyable_vars.append( mvar )
         if tt.class_traits.is_my_case( type_ ):
             cls = tt.class_traits.get_declaration( type_ )
             if tt.is_noncopyable( cls ):
                 logger.debug( "__contains_noncopyable_mem_var - %s - TRUE - containes member variable - class that is not copyable" % self.decl_string )
                 noncopyable_vars.append( mvar )
     logger.debug( "__contains_noncopyable_mem_var - %s - false - doesn't contains noncopyable members" % self.decl_string )
     return noncopyable_vars
Example #4
0
 def find_noncopyable_vars(self):
     """returns list of all noncopyable variables"""
     import type_traits as tt  #prevent cyclic dependencies
     logger = utils.loggers.cxx_parser
     mvars = self.vars(lambda v: not v.type_qualifiers.has_static,
                       recursive=False,
                       allow_empty=True)
     noncopyable_vars = []
     for mvar in mvars:
         type_ = tt.remove_reference(mvar.type)
         if tt.is_const(type_):
             no_const = tt.remove_const(type_)
             if tt.is_fundamental(no_const) or tt.is_enum(no_const):
                 logger.debug(
                     "__contains_noncopyable_mem_var - %s - TRUE - containes const member variable - fundamental or enum"
                     % self.decl_string)
                 noncopyable_vars.append(mvar)
             if tt.is_class(no_const):
                 logger.debug(
                     "__contains_noncopyable_mem_var - %s - TRUE - containes const member variable - class"
                     % self.decl_string)
                 noncopyable_vars.append(mvar)
             if tt.is_array(no_const):
                 logger.debug(
                     "__contains_noncopyable_mem_var - %s - TRUE - containes const member variable - array"
                     % self.decl_string)
                 noncopyable_vars.append(mvar)
         if tt.class_traits.is_my_case(type_):
             cls = tt.class_traits.get_declaration(type_)
             if tt.is_noncopyable(cls):
                 logger.debug(
                     "__contains_noncopyable_mem_var - %s - TRUE - containes member variable - class that is not copyable"
                     % self.decl_string)
                 noncopyable_vars.append(mvar)
     logger.debug(
         "__contains_noncopyable_mem_var - %s - false - doesn't contains noncopyable members"
         % self.decl_string)
     return noncopyable_vars