Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/PtrsAssignable.cc

    rc6b4432 r5bf3976  
    1919#include "AST/Type.hpp"
    2020#include "AST/TypeEnvironment.hpp"
     21#include "Common/PassVisitor.h"
     22#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
     23#include "SynTree/Type.h"                // for TypeInstType, Type, BasicType
     24#include "SynTree/Visitor.h"             // for Visitor
     25
    2126
    2227namespace ResolvExpr {
     28        struct PtrsAssignable : public WithShortCircuiting {
     29                PtrsAssignable( const Type * dest, const TypeEnvironment &env );
     30
     31                int get_result() const { return result; }
     32
     33                void previsit( const Type * ) { visit_children = false; }
     34
     35                void postvisit( const VoidType * voidType );
     36                void postvisit( const BasicType * basicType );
     37                void postvisit( const PointerType * pointerType );
     38                void postvisit( const ArrayType * arrayType );
     39                void postvisit( const FunctionType * functionType );
     40                void postvisit( const StructInstType * inst );
     41                void postvisit( const UnionInstType * inst );
     42                void postvisit( const EnumInstType * inst );
     43                void postvisit( const TraitInstType * inst );
     44                void postvisit( const TypeInstType * inst );
     45                void postvisit( const TupleType * tupleType );
     46                void postvisit( const VarArgsType * varArgsType );
     47                void postvisit( const ZeroType * zeroType );
     48                void postvisit( const OneType * oneType );
     49          private:
     50                const Type * dest;
     51                int result;
     52                const TypeEnvironment &env;
     53        };
     54
     55        int ptrsAssignable( const Type *src, const Type * dest, const TypeEnvironment &env ) {
     56                // std::cerr << "assignable: " << src << " | " << dest << std::endl;
     57                if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
     58                        if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
     59                                return ptrsAssignable( src, eqvClass->type, env );
     60                        } // if
     61                } // if
     62                if ( dynamic_cast< const VoidType* >( dest ) ) {
     63                        // void * = T * for any T is unsafe
     64                        // xxx - this should be safe, but that currently breaks the build
     65                        return -1;
     66                } else {
     67                        PassVisitor<PtrsAssignable> ptrs( dest, env );
     68                        src->accept( ptrs );
     69                        return ptrs.pass.get_result();
     70                } // if
     71        }
     72
     73        PtrsAssignable::PtrsAssignable( const Type * dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
     74
     75        void PtrsAssignable::postvisit( const VoidType * ) {
     76                // T * = void * is disallowed - this is a change from C, where any
     77                // void * can be assigned or passed to a non-void pointer without a cast.
     78        }
     79
     80        void PtrsAssignable::postvisit( const BasicType * ) {}
     81        void PtrsAssignable::postvisit( const PointerType * ) {}
     82        void PtrsAssignable::postvisit( const ArrayType * ) {}
     83        void PtrsAssignable::postvisit( const FunctionType * ) {}
     84
     85        void PtrsAssignable::postvisit( const StructInstType * ) {}
     86        void PtrsAssignable::postvisit( const UnionInstType * ) {}
     87
     88        void PtrsAssignable::postvisit( const EnumInstType * ) {
     89                if ( dynamic_cast< const BasicType* >( dest ) ) {
     90                        // int * = E *, etc. is safe. This isn't technically correct, as each
     91                        // enum has one basic type that it is compatible with, an that type can
     92                        // differ from enum to enum. Without replicating GCC's internal logic,
     93                        // there is no way to know which type this particular enum is compatible
     94                        // with, so punt on this for now.
     95                        result = 1;
     96                }
     97        }
     98
     99        void PtrsAssignable::postvisit(  const TraitInstType * ) {}
     100        void PtrsAssignable::postvisit( const TypeInstType * inst ) {
     101                if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
     102                        if ( eqvClass->type ) {
     103                                // T * = S * for any S depends on the type bound to T
     104                                result = ptrsAssignable( eqvClass->type, dest, env );
     105                        }
     106                } // if
     107        }
     108
     109        void PtrsAssignable::postvisit( const TupleType * ) {}
     110        void PtrsAssignable::postvisit( const VarArgsType * ) {}
     111        void PtrsAssignable::postvisit( const ZeroType * ) {}
     112        void PtrsAssignable::postvisit( const OneType * ) {}
    23113
    24114// TODO: Get rid of the `_new` suffix when the old version is removed.
Note: See TracChangeset for help on using the changeset viewer.