Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/PtrsAssignable.cc

    r7870799 r00ac42e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 11:44:11 2015
    11 // Last Modified By : Andrew
    12 // Last Modified On : Mon Jun 24 15:29:00 2019
    13 // Update Count     : 9
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Mar  2 17:36:05 2016
     13// Update Count     : 8
    1414//
    1515
    16 #include "typeops.h"
    17 
    18 #include "AST/Pass.hpp"
    19 #include "AST/Type.hpp"
    20 #include "AST/TypeEnvironment.hpp"
    2116#include "Common/PassVisitor.h"
    2217#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
     
    2722namespace ResolvExpr {
    2823        struct PtrsAssignable : public WithShortCircuiting {
    29                 PtrsAssignable( const Type * dest, const TypeEnvironment &env );
     24                PtrsAssignable( Type *dest, const TypeEnvironment &env );
    3025
    3126                int get_result() const { return result; }
    3227
    33                 void previsit( const Type * ) { visit_children = false; }
     28                void previsit( Type * ) { visit_children = false; }
    3429
    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 );
     30                void postvisit( VoidType * voidType );
     31                void postvisit( BasicType * basicType );
     32                void postvisit( PointerType * pointerType );
     33                void postvisit( ArrayType * arrayType );
     34                void postvisit( FunctionType * functionType );
     35                void postvisit( StructInstType * inst );
     36                void postvisit( UnionInstType * inst );
     37                void postvisit( EnumInstType * inst );
     38                void postvisit( TraitInstType * inst );
     39                void postvisit( TypeInstType * inst );
     40                void postvisit( TupleType * tupleType );
     41                void postvisit( VarArgsType * varArgsType );
     42                void postvisit( ZeroType * zeroType );
     43                void postvisit( OneType * oneType );
    4944          private:
    50                 const Type * dest;
     45                Type *dest;
    5146                int result;
    5247                const TypeEnvironment &env;
    5348        };
    5449
    55         int ptrsAssignable( const Type *src, const Type * dest, const TypeEnvironment &env ) {
     50        int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {
    5651                // 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() ) ) {
     52                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     53                        if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
    5954                                return ptrsAssignable( src, eqvClass->type, env );
    6055                        } // if
    6156                } // if
    62                 if ( dynamic_cast< const VoidType* >( dest ) ) {
     57                if ( dynamic_cast< VoidType* >( dest ) ) {
    6358                        // void * = T * for any T is unsafe
    6459                        // xxx - this should be safe, but that currently breaks the build
     
    7166        }
    7267
    73         PtrsAssignable::PtrsAssignable( const Type * dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
     68        PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
    7469
    75         void PtrsAssignable::postvisit( const VoidType * ) {
     70        void PtrsAssignable::postvisit( VoidType * ) {
    7671                // T * = void * is disallowed - this is a change from C, where any
    7772                // void * can be assigned or passed to a non-void pointer without a cast.
    7873        }
    7974
    80         void PtrsAssignable::postvisit( const BasicType * ) {}
    81         void PtrsAssignable::postvisit( const PointerType * ) {}
    82         void PtrsAssignable::postvisit( const ArrayType * ) {}
    83         void PtrsAssignable::postvisit( const FunctionType * ) {}
     75        void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType ) {}
     76        void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType ) {}
     77        void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType ) {}
     78        void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType ) {}
    8479
    85         void PtrsAssignable::postvisit( const StructInstType * ) {}
    86         void PtrsAssignable::postvisit( const UnionInstType * ) {}
     80        void PtrsAssignable::postvisit(  __attribute__((unused)) StructInstType *inst ) {}
     81        void PtrsAssignable::postvisit(  __attribute__((unused)) UnionInstType *inst ) {}
    8782
    88         void PtrsAssignable::postvisit( const EnumInstType * ) {
    89                 if ( dynamic_cast< const BasicType* >( dest ) ) {
     83        void PtrsAssignable::postvisit( EnumInstType * ) {
     84                if ( dynamic_cast< BasicType* >( dest ) ) {
    9085                        // int * = E *, etc. is safe. This isn't technically correct, as each
    9186                        // enum has one basic type that it is compatible with, an that type can
     
    9792        }
    9893
    99         void PtrsAssignable::postvisit(  const TraitInstType * ) {}
    100         void PtrsAssignable::postvisit( const TypeInstType * inst ) {
    101                 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
     94        void PtrsAssignable::postvisit(  __attribute__((unused)) TraitInstType *inst ) {}
     95        void PtrsAssignable::postvisit( TypeInstType *inst ) {
     96                if ( const EqvClass *eqvClass = env.lookup( inst->get_name() ) ) {
    10297                        if ( eqvClass->type ) {
    10398                                // T * = S * for any S depends on the type bound to T
     
    107102        }
    108103
    109         void PtrsAssignable::postvisit( const TupleType * ) {}
    110         void PtrsAssignable::postvisit( const VarArgsType * ) {}
    111         void PtrsAssignable::postvisit( const ZeroType * ) {}
    112         void PtrsAssignable::postvisit( const OneType * ) {}
    113 
    114 // TODO: Get rid of the `_new` suffix when the old version is removed.
    115 struct PtrsAssignable_new : public ast::WithShortCircuiting {
    116         const ast::Type * dst;
    117         const ast::TypeEnvironment & typeEnv;
    118         int result;
    119 
    120         PtrsAssignable_new( const ast::Type * dst, const ast::TypeEnvironment & env ) :
    121                 dst( dst ), typeEnv( env ), result( 0 ) {}
    122 
    123         void previsit( Type * ) { visit_children = false; }
    124 
    125         void postvisit( const ast::EnumInstType * ) {
    126                 if ( dynamic_cast< const ast::BasicType * >( dst ) ) {
    127                         // int * = E *, etc. is safe. This isn't technically correct, as each
    128                         // enum has one basic type that it is compatible with, an that type can
    129                         // differ from enum to enum. Without replicating GCC's internal logic,
    130                         // there is no way to know which type this particular enum is compatible
    131                         // with, so punt on this for now.
    132                         result = 1;
    133                 }
    134         }
    135         void postvisit( const ast::TypeInstType * inst ) {
    136                 if ( const ast::EqvClass * eqv = typeEnv.lookup( inst->name ) ) {
    137                         if ( eqv->bound ) {
    138                                 // T * = S * for any S depends on the type bound to T
    139                                 result = ptrsAssignable( eqv->bound, dst, typeEnv );
    140                         }
    141                 }
    142         }
    143 };
    144 
    145 int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
    146                 const ast::TypeEnvironment & env ) {
    147         if ( const ast::TypeInstType * dstAsInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
    148                 if ( const ast::EqvClass * eqv = env.lookup( dstAsInst->name ) ) {
    149                         return ptrsAssignable( src, eqv->bound, env );
    150                 }
    151         }
    152         if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
    153                 return -1;
    154         } else {
    155                 ast::Pass<PtrsAssignable_new> visitor( dst, env );
    156                 src->accept( visitor );
    157                 return visitor.pass.result;
    158         }
    159 
    160 // see ticket #136 (this should be able to replace the visitor).
    161 #if 0
    162         if ( const ast::TypeInstType * dstAsTypeInst =
    163                         dynamic_cast< const ast::TypeInstType* >( dst ) ) {
    164                 if ( const ast::EqvClass * eqv = env.lookup( dstAsTypeInst->get_name() ) ) {
    165                         return ptrsAssignable( src, eqv->type, env );
    166                 } // if
    167         } // if
    168         if ( dynamic_cast< VoidType* >( dst ) ) {
    169                 // void * = T * for any T is unsafe
    170                 // xxx - this should be safe, but that currently breaks the build
    171                 return -1;
    172         } else if ( dynamic_cast< EnumInstType * >( src ) ) {
    173                 if ( dynamic_cast< BasicType * >( dst ) ) {
    174                         // int * = E *, etc. is safe. This isn't technically correct, as each
    175                         // enum has one basic type that it is compatible with, an that type can
    176                         // differ from enum to enum. Without replicating GCC's internal logic,
    177                         // there is no way to know which type this particular enum is compatible
    178                         // with, so punt on this for now.
    179                         return 1;
    180                 }
    181         } else if ( const ast::TypeInstType * typeInstType =
    182                         dynamic_cast< const ast::TypeInstType * >( src ) ) {
    183                 if ( const ast::EqvClass * eqv = env.lookup( typeInstType->name ) ) {
    184                         if ( eqv->bound ) {
    185                                 // T * = S * for any S depends on the type bound to T
    186                                 return ptrsAssignable( eqv->bound, dst, env );
    187                         }
    188                 }
    189         }
    190         return 0;
    191 #endif
    192 }
     104        void PtrsAssignable::postvisit(  __attribute__((unused)) TupleType *tupleType ) {}
     105        void PtrsAssignable::postvisit(  __attribute__((unused)) VarArgsType *varArgsType ) {}
     106        void PtrsAssignable::postvisit(  __attribute__((unused)) ZeroType *zeroType ) {}
     107        void PtrsAssignable::postvisit(  __attribute__((unused)) OneType *oneType ) {}
    193108
    194109} // namespace ResolvExpr
Note: See TracChangeset for help on using the changeset viewer.