Example #1
0
    def is_convertible(self):
        source = self.__source
        target = self.__target

        if self.__test_trivial(source, target):
            return True
        if is_array(source) or is_array(target):
            return False
        if self.__test_const_x_ref__to__x(source, target):
            return True
        if self.__test_const_ref_x__to__y(source, target):
            return True
        if self.__test_ref_x__to__x(source, target):
            return True
        if self.__test_ref_x__to__y(source, target):
            return True
        if self.__test_fundamental__to__fundamental(source, target):
            return True
        if self.__test_pointer_to_func_or_mv__to__func_or_mv(source, target):
            return True
        if self.__test_derived_to_based(source, target):
            return True

        if isinstance(source, cpptypes.declarated_t):
            if isinstance( source.declaration, enumeration.enumeration_t ) \
               and is_fundamental( target ) \
               and not is_void( target ):
                return True  # enum could be converted to any integral type

            if isinstance(source.declaration, class_declaration.class_t):
                source_inst = source.declaration
                #class instance could be convertible to something else if it has operator
                casting_operators = algorithm.find_all_declarations(
                    source_inst.declarations,
                    type=calldef.casting_operator_t,
                    recursive=False)
                if casting_operators:
                    for operator in casting_operators:
                        if is_convertible(operator.return_type, target):
                            return True

        #may be target is class too, so in this case we should check whether is
        #has constructor from source
        if isinstance(target, cpptypes.declarated_t):
            if isinstance(target.declaration, class_declaration.class_t):
                constructors = algorithm.find_all_declarations(
                    target.declaration.declarations,
                    type=calldef.constructor_t,
                    recursive=False)
                if constructors:
                    for constructor in constructors:
                        if 1 != len(constructor.arguments):
                            continue
                        #TODO: add test to check explicitness
                        if is_convertible(source,
                                          constructor.arguments[0].type):
                            return True

        return False
    def is_convertible( self ):
        source = self.__source
        target = self.__target

        if self.__test_trivial(source, target):
            return True
        if is_array( source ) or is_array( target ):
            return False
        if self.__test_const_x_ref__to__x(source, target):
            return True
        if self.__test_const_ref_x__to__y(source, target):
            return True
        if self.__test_ref_x__to__x(source, target):
            return True
        if self.__test_ref_x__to__y(source, target):
            return True
        if self.__test_fundamental__to__fundamental( source, target ):
            return True
        if self.__test_pointer_to_func_or_mv__to__func_or_mv( source, target ):
            return True
        if self.__test_derived_to_based( source, target ):
            return True

        if isinstance( source, cpptypes.declarated_t ):
            if isinstance( source.declaration, enumeration.enumeration_t ) \
               and is_fundamental( target ) \
               and not is_void( target ):
                return True # enum could be converted to any integral type

            if isinstance( source.declaration, class_declaration.class_t ):
                source_inst = source.declaration
                #class instance could be convertible to something else if it has operator
                casting_operators = algorithm.find_all_declarations( source_inst.declarations
                                                                     , type=calldef.casting_operator_t
                                                                     , recursive=False )
                if casting_operators:
                    for operator in casting_operators:
                        if is_convertible( operator.return_type, target ):
                            return True

        #may be target is class too, so in this case we should check whether is
        #has constructor from source
        if isinstance( target, cpptypes.declarated_t ):
            if isinstance( target.declaration, class_declaration.class_t ):
                constructors = algorithm.find_all_declarations( target.declaration.declarations
                                                                , type=calldef.constructor_t
                                                                , recursive=False )
                if constructors:
                    for constructor in constructors:
                        if 1 != len( constructor.arguments ):
                            continue
                        #TODO: add test to check explicitness
                        if is_convertible( source, constructor.arguments[0].type ):
                            return True

        return False
Example #3
0
def has_public_assign(type):
    """returns True, if class has public assign operator, False otherwise"""
    assert isinstance( type, class_declaration.class_t )
    decls = algorithm.find_all_declarations( type.public_members
                                             , type=calldef.member_operator_t
                                             , recursive=False )
    decls = filter( lambda decl: decl.symbol == '=', decls )
    return bool( decls )
Example #4
0
def has_public_constructor(type):
    """returns True, if class has public constructor, False otherwise"""
    assert isinstance( type, class_declaration.class_t )
    decls = algorithm.find_all_declarations( type.public_members
                                             , type=calldef.constructor_t
                                             , recursive=False )
    constructors = filter( lambda decl: not decl.is_copy_constructor, decls )
    return bool( constructors ) or has_trivial_constructor( type )
Example #5
0
def has_public_assign(type):
    """returns True, if class has public assign operator, False otherwise"""
    assert isinstance(type, class_declaration.class_t)
    decls = algorithm.find_all_declarations(type.public_members,
                                            type=calldef.member_operator_t,
                                            recursive=False)
    decls = filter(lambda decl: decl.symbol == '=', decls)
    return bool(decls)
Example #6
0
def has_public_constructor(type):
    """returns True, if class has public constructor, False otherwise"""
    assert isinstance(type, class_declaration.class_t)
    decls = algorithm.find_all_declarations(type.public_members,
                                            type=calldef.constructor_t,
                                            recursive=False)
    constructors = filter(lambda decl: not decl.is_copy_constructor, decls)
    return bool(constructors) or has_trivial_constructor(type)