- File:
-
- 1 edited
-
src/ResolvExpr/PtrsAssignable.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/PtrsAssignable.cc
rdf9317bd rfb2bde4 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" 16 #include "AST/Fwd.hpp" 21 17 #include "Common/PassVisitor.h" 22 18 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment … … 112 108 void PtrsAssignable::postvisit( __attribute__((unused)) OneType *oneType ) {} 113 109 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 each128 // enum has one basic type that it is compatible with, an that type can129 // differ from enum to enum. Without replicating GCC's internal logic,130 // there is no way to know which type this particular enum is compatible131 // 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 T139 result = ptrsAssignable( eqv->bound, dst, typeEnv );140 }141 }142 }143 };144 145 110 int ptrsAssignable( const ast::Type * src, const ast::Type * dst, 146 111 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 } 112 #warning unimplemented 113 (void)src; 114 (void)dst; 115 (void)env; 116 assert(0); 190 117 return 0; 191 #endif192 118 } 193 119
Note:
See TracChangeset
for help on using the changeset viewer.