Changeset b067d9b for src/ResolvExpr/PtrsAssignable.cc
- Timestamp:
- Oct 29, 2019, 4:01:24 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 773db65, 9421f3d8
- Parents:
- 7951100 (diff), 8364209 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/PtrsAssignable.cc
r7951100 rb067d9b 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 11:44:11 2015 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:36:05 2016 13 // Update Count : 8 14 // 15 11 // Last Modified By : Andrew 12 // Last Modified On : Mon Jun 24 15:29:00 2019 13 // Update Count : 9 14 // 15 16 #include "typeops.h" 17 18 #include "AST/Pass.hpp" 19 #include "AST/Type.hpp" 20 #include "AST/TypeEnvironment.hpp" 16 21 #include "Common/PassVisitor.h" 17 22 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment … … 22 27 namespace ResolvExpr { 23 28 struct PtrsAssignable : public WithShortCircuiting { 24 PtrsAssignable( Type *dest, const TypeEnvironment &env );29 PtrsAssignable( const Type * dest, const TypeEnvironment &env ); 25 30 26 31 int get_result() const { return result; } 27 32 28 void previsit( Type * ) { visit_children = false; }29 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 );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 ); 44 49 private: 45 Type *dest;50 const Type * dest; 46 51 int result; 47 52 const TypeEnvironment &env; 48 53 }; 49 54 50 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {55 int ptrsAssignable( const Type *src, const Type * dest, const TypeEnvironment &env ) { 51 56 // std::cerr << "assignable: " << src << " | " << dest << std::endl; 52 if ( TypeInstType *destAsTypeInst = dynamic_cast<TypeInstType* >( dest ) ) {53 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {57 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) { 58 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) { 54 59 return ptrsAssignable( src, eqvClass->type, env ); 55 60 } // if 56 61 } // if 57 if ( dynamic_cast< VoidType* >( dest ) ) {62 if ( dynamic_cast< const VoidType* >( dest ) ) { 58 63 // void * = T * for any T is unsafe 59 64 // xxx - this should be safe, but that currently breaks the build … … 66 71 } 67 72 68 PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}69 70 void PtrsAssignable::postvisit( VoidType * ) {73 PtrsAssignable::PtrsAssignable( const Type * dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {} 74 75 void PtrsAssignable::postvisit( const VoidType * ) { 71 76 // T * = void * is disallowed - this is a change from C, where any 72 77 // void * can be assigned or passed to a non-void pointer without a cast. 73 78 } 74 79 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) {}79 80 void PtrsAssignable::postvisit( __attribute__((unused)) StructInstType *inst) {}81 void PtrsAssignable::postvisit( __attribute__((unused)) UnionInstType *inst) {}82 83 void PtrsAssignable::postvisit( EnumInstType * ) {84 if ( dynamic_cast< BasicType* >( dest ) ) {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 ) ) { 85 90 // int * = E *, etc. is safe. This isn't technically correct, as each 86 91 // enum has one basic type that it is compatible with, an that type can … … 92 97 } 93 98 94 void PtrsAssignable::postvisit( __attribute__((unused)) TraitInstType *inst) {}95 void PtrsAssignable::postvisit( TypeInstType *inst ) {96 if ( const EqvClass * eqvClass = env.lookup( inst->get_name()) ) {99 void PtrsAssignable::postvisit( const TraitInstType * ) {} 100 void PtrsAssignable::postvisit( const TypeInstType * inst ) { 101 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) { 97 102 if ( eqvClass->type ) { 98 103 // T * = S * for any S depends on the type bound to T … … 102 107 } 103 108 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 ) {} 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 } 108 193 109 194 } // namespace ResolvExpr
Note:
See TracChangeset
for help on using the changeset viewer.