- File:
-
- 1 edited
-
src/ResolvExpr/PtrsAssignable.cc (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/PtrsAssignable.cc
r7870799 r00ac42e 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 11:44:11 2015 11 // Last Modified By : Andrew12 // Last Modified On : Mon Jun 24 15:29:00 201913 // Update Count : 911 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:36:05 2016 13 // Update Count : 8 14 14 // 15 15 16 #include "typeops.h"17 18 #include "AST/Pass.hpp"19 #include "AST/Type.hpp"20 #include "AST/TypeEnvironment.hpp"21 16 #include "Common/PassVisitor.h" 22 17 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment … … 27 22 namespace ResolvExpr { 28 23 struct PtrsAssignable : public WithShortCircuiting { 29 PtrsAssignable( const Type *dest, const TypeEnvironment &env );24 PtrsAssignable( Type *dest, const TypeEnvironment &env ); 30 25 31 26 int get_result() const { return result; } 32 27 33 void previsit( constType * ) { visit_children = false; }28 void previsit( Type * ) { visit_children = false; } 34 29 35 void postvisit( constVoidType * voidType );36 void postvisit( constBasicType * basicType );37 void postvisit( constPointerType * pointerType );38 void postvisit( constArrayType * arrayType );39 void postvisit( constFunctionType * functionType );40 void postvisit( constStructInstType * inst );41 void postvisit( constUnionInstType * inst );42 void postvisit( constEnumInstType * inst );43 void postvisit( constTraitInstType * inst );44 void postvisit( constTypeInstType * inst );45 void postvisit( constTupleType * tupleType );46 void postvisit( constVarArgsType * varArgsType );47 void postvisit( constZeroType * zeroType );48 void postvisit( constOneType * 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 ); 49 44 private: 50 const Type *dest;45 Type *dest; 51 46 int result; 52 47 const TypeEnvironment &env; 53 48 }; 54 49 55 int ptrsAssignable( const Type *src, const Type *dest, const TypeEnvironment &env ) {50 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) { 56 51 // std::cerr << "assignable: " << src << " | " << dest << std::endl; 57 if ( const TypeInstType * destAsTypeInst = dynamic_cast< constTypeInstType* >( 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() ) ) { 59 54 return ptrsAssignable( src, eqvClass->type, env ); 60 55 } // if 61 56 } // if 62 if ( dynamic_cast< constVoidType* >( dest ) ) {57 if ( dynamic_cast< VoidType* >( dest ) ) { 63 58 // void * = T * for any T is unsafe 64 59 // xxx - this should be safe, but that currently breaks the build … … 71 66 } 72 67 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 ) {} 74 69 75 void PtrsAssignable::postvisit( constVoidType * ) {70 void PtrsAssignable::postvisit( VoidType * ) { 76 71 // T * = void * is disallowed - this is a change from C, where any 77 72 // void * can be assigned or passed to a non-void pointer without a cast. 78 73 } 79 74 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 ) {} 84 79 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 ) {} 87 82 88 void PtrsAssignable::postvisit( constEnumInstType * ) {89 if ( dynamic_cast< constBasicType* >( dest ) ) {83 void PtrsAssignable::postvisit( EnumInstType * ) { 84 if ( dynamic_cast< BasicType* >( dest ) ) { 90 85 // int * = E *, etc. is safe. This isn't technically correct, as each 91 86 // enum has one basic type that it is compatible with, an that type can … … 97 92 } 98 93 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() ) ) { 102 97 if ( eqvClass->type ) { 103 98 // T * = S * for any S depends on the type bound to T … … 107 102 } 108 103 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 ) {} 193 108 194 109 } // namespace ResolvExpr
Note:
See TracChangeset
for help on using the changeset viewer.