Changeset b6838214 for src/ResolvExpr/CommonType.cc
- Timestamp:
- Jan 23, 2018, 5:46:43 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 258e6ad5
- Parents:
- b158d8f (diff), 15d248e (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/CommonType.cc
rb158d8f rb6838214 18 18 #include <utility> // for pair 19 19 20 #include "Common/PassVisitor.h" 20 21 #include "ResolvExpr/TypeEnvironment.h" // for OpenVarSet, AssertionSet 21 22 #include "SymTab/Indexer.h" // for Indexer … … 29 30 30 31 namespace ResolvExpr { 31 class CommonType : public Visitor { 32 public: 32 struct CommonType : public WithShortCircuiting { 33 33 CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ); 34 34 Type *get_result() const { return result; } 35 36 void previsit( BaseSyntaxNode * ) { visit_children = false; } 37 38 void postvisit( VoidType * voidType ); 39 void postvisit( BasicType * basicType ); 40 void postvisit( PointerType * pointerType ); 41 void postvisit( ArrayType * arrayType ); 42 void postvisit( ReferenceType * refType ); 43 void postvisit( FunctionType * functionType ); 44 void postvisit( StructInstType * aggregateUseType ); 45 void postvisit( UnionInstType * aggregateUseType ); 46 void postvisit( EnumInstType * aggregateUseType ); 47 void postvisit( TraitInstType * aggregateUseType ); 48 void postvisit( TypeInstType * aggregateUseType ); 49 void postvisit( TupleType * tupleType ); 50 void postvisit( VarArgsType * varArgsType ); 51 void postvisit( ZeroType * zeroType ); 52 void postvisit( OneType * oneType ); 53 35 54 private: 36 virtual void visit( VoidType *voidType );37 virtual void visit( BasicType *basicType );38 virtual void visit( PointerType *pointerType );39 virtual void visit( ArrayType *arrayType );40 virtual void visit( ReferenceType *refType );41 virtual void visit( FunctionType *functionType );42 virtual void visit( StructInstType *aggregateUseType );43 virtual void visit( UnionInstType *aggregateUseType );44 virtual void visit( EnumInstType *aggregateUseType );45 virtual void visit( TraitInstType *aggregateUseType );46 virtual void visit( TypeInstType *aggregateUseType );47 virtual void visit( TupleType *tupleType );48 virtual void visit( VarArgsType *varArgsType );49 virtual void visit( ZeroType *zeroType );50 virtual void visit( OneType *oneType );51 52 55 template< typename Pointer > void getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer ); 53 56 template< typename RefType > void handleRefType( RefType *inst, Type *other ); … … 80 83 81 84 Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) { 82 CommonTypevisitor( type2, widenFirst, widenSecond, indexer, env, openVars );85 PassVisitor<CommonType> visitor( type2, widenFirst, widenSecond, indexer, env, openVars ); 83 86 84 87 int depth1 = type1->referenceDepth(); … … 91 94 // special case where one type has a reference depth of 1 larger than the other 92 95 if ( diff > 0 || diff < 0 ) { 96 // std::cerr << "reference depth diff: " << diff << std::endl; 93 97 Type * result = nullptr; 94 if ( ReferenceType * ref1 = dynamic_cast< ReferenceType * >( type1 ) ) { 98 ReferenceType * ref1 = dynamic_cast< ReferenceType * >( type1 ); 99 ReferenceType * ref2 = dynamic_cast< ReferenceType * >( type2 ); 100 if ( diff > 0 ) { 101 // deeper on the left 102 assert( ref1 ); 103 result = handleReference( ref1->base, type2, widenFirst, widenSecond, indexer, env, openVars ); 104 } else { 105 // deeper on the right 106 assert( ref2 ); 107 result = handleReference( type1, ref2->base, widenFirst, widenSecond, indexer, env, openVars ); 108 } 109 if ( result && ref1 ) { 95 110 // formal is reference, so result should be reference 96 result = handleReference( ref1->base, type2, widenFirst, widenSecond, indexer, env, openVars ); 97 if ( result ) result = new ReferenceType( ref1->get_qualifiers(), result ); 98 } else { 99 // formal is value, so result should be value 100 ReferenceType * ref2 = strict_dynamic_cast< ReferenceType * > ( type2 ); 101 result = handleReference( type1, ref2->base, widenFirst, widenSecond, indexer, env, openVars ); 111 // std::cerr << "formal is reference; result should be reference" << std::endl; 112 result = new ReferenceType( ref1->get_qualifiers(), result ); 102 113 } 103 114 // std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is [" << result << "]" << std::endl; … … 108 119 109 120 type1->accept( visitor ); 110 Type *result = visitor. get_result();121 Type *result = visitor.pass.get_result(); 111 122 if ( ! result ) { 112 123 // this appears to be handling for opaque type declarations … … 180 191 } 181 192 182 void CommonType:: visit( __attribute((unused)) VoidType *voidType) {}183 184 void CommonType:: visit( BasicType *basicType ) {193 void CommonType::postvisit( VoidType * ) {} 194 195 void CommonType::postvisit( BasicType *basicType ) { 185 196 if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) { 186 197 BasicType::Kind newType = combinedType[ basicType->get_kind() ][ otherBasic->get_kind() ]; … … 211 222 } 212 223 213 void CommonType:: visit( PointerType *pointerType ) {224 void CommonType::postvisit( PointerType *pointerType ) { 214 225 if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) { 215 226 // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl; … … 246 257 } 247 258 248 void CommonType:: visit( __attribute((unused)) ArrayType *arrayType) {}249 250 void CommonType:: visit( ReferenceType *refType ) {259 void CommonType::postvisit( ArrayType * ) {} 260 261 void CommonType::postvisit( ReferenceType *refType ) { 251 262 if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) { 252 263 // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl; … … 283 294 } 284 295 285 void CommonType:: visit( __attribute((unused)) FunctionType *functionType) {}286 void CommonType:: visit( __attribute((unused)) StructInstType *aggregateUseType) {}287 void CommonType:: visit( __attribute((unused)) UnionInstType *aggregateUseType) {}288 289 void CommonType:: visit( EnumInstType *enumInstType ) {296 void CommonType::postvisit( FunctionType * ) {} 297 void CommonType::postvisit( StructInstType * ) {} 298 void CommonType::postvisit( UnionInstType * ) {} 299 300 void CommonType::postvisit( EnumInstType *enumInstType ) { 290 301 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) { 291 302 // reuse BasicType, EnumInstType code by swapping type2 with enumInstType 292 ValueGuard< Type * > temp( type2 ); 293 type2 = enumInstType; 294 temp.old->accept( *this ); 295 } // if 296 } 297 298 void CommonType::visit( __attribute((unused)) TraitInstType *aggregateUseType ) { 299 } 300 301 void CommonType::visit( TypeInstType *inst ) { 303 result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars ); 304 } // if 305 } 306 307 void CommonType::postvisit( TraitInstType * ) { 308 } 309 310 void CommonType::postvisit( TypeInstType *inst ) { 302 311 if ( widenFirst ) { 303 312 NamedTypeDecl *nt = indexer.lookupType( inst->get_name() ); … … 321 330 } 322 331 323 void CommonType:: visit( __attribute((unused)) TupleType *tupleType) {}324 void CommonType:: visit( __attribute((unused)) VarArgsType *varArgsType) {}325 326 void CommonType:: visit( ZeroType *zeroType ) {332 void CommonType::postvisit( TupleType * ) {} 333 void CommonType::postvisit( VarArgsType * ) {} 334 335 void CommonType::postvisit( ZeroType *zeroType ) { 327 336 if ( widenFirst ) { 328 337 if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) { … … 338 347 } 339 348 340 void CommonType:: visit( OneType *oneType ) {349 void CommonType::postvisit( OneType *oneType ) { 341 350 if ( widenFirst ) { 342 351 if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
Note:
See TracChangeset
for help on using the changeset viewer.