Changeset 65cec25
- Timestamp:
- Jul 13, 2017, 3:06:29 PM (7 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:
- 6b9b047
- Parents:
- 2463d0e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CommonType.cc
r2463d0e r65cec25 17 17 #include "SynTree/Type.h" 18 18 #include "Unify.h" 19 20 19 21 20 /// #define DEBUG … … 31 30 virtual void visit( PointerType *pointerType ); 32 31 virtual void visit( ArrayType *arrayType ); 32 virtual void visit( ReferenceType *refType ); 33 33 virtual void visit( FunctionType *functionType ); 34 34 virtual void visit( StructInstType *aggregateUseType ); … … 42 42 virtual void visit( OneType *oneType ); 43 43 44 void getCommonWithVoidPointer( PointerType* voidPointer, PointerType* otherPointer ); 44 template< typename Pointer > void getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer ); 45 template< typename RefType > void handleRefType( RefType *inst, Type *other ); 45 46 46 47 Type *result; … … 52 53 }; 53 54 55 Type * handleReference( ReferenceType * refType, Type * other, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment & env, const OpenVarSet &openVars ) { 56 Type * result = nullptr, * common = nullptr; 57 AssertionSet have, need; 58 OpenVarSet newOpen( openVars ); 59 // need unify to bind type variables 60 if ( unify( refType->get_base(), other, env, have, need, newOpen, indexer, common ) ) { 61 // std::cerr << "unify success" << std::endl; 62 if ( widenSecond ) { 63 if ( widenFirst || other->get_qualifiers() <= refType->get_qualifiers() ) { 64 result = new ReferenceType( refType->get_qualifiers(), common ); // refType->clone(); 65 result->get_qualifiers() |= other->get_qualifiers(); 66 } 67 } else if ( widenFirst ) { 68 if ( widenSecond || refType->get_qualifiers() <= other->get_qualifiers() ) { 69 result = common; 70 result->get_qualifiers() |= refType->get_qualifiers(); 71 } 72 } 73 } else { 74 // std::cerr << "exact unify failed: " << refType << " " << other << std::endl; 75 } 76 // std::cerr << "common type of reference [" << refType << "] and non-reference [" << other << "] is [" << result << "]" << std::endl; 77 return result; 78 } 79 54 80 Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) { 55 81 CommonType visitor( type2, widenFirst, widenSecond, indexer, env, openVars ); 82 83 ReferenceType * refType1 = dynamic_cast< ReferenceType * >( type1 ); 84 ReferenceType * refType2 = dynamic_cast< ReferenceType * >( type2 ); 85 if ( (refType1 || refType2) && (! refType1 || ! refType2) ) { 86 // handle the case where exactly one of the types is a reference type specially 87 if ( refType1 ) { 88 return handleReference( refType1, type2, widenFirst, widenSecond, indexer, env, openVars ); 89 } else if ( refType2 ) { 90 return handleReference( refType2, type1, widenSecond, widenFirst, indexer, env, openVars ); 91 } 92 } 93 56 94 type1->accept( visitor ); 57 95 Type *result = visitor.get_result(); … … 142 180 } 143 181 144 void CommonType::getCommonWithVoidPointer( PointerType* voidPointer, PointerType* otherPointer ) { 182 template< typename Pointer > 183 void CommonType::getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer ) { 145 184 if ( TypeInstType* var = dynamic_cast< TypeInstType* >( otherPointer->get_base() ) ) { 146 185 OpenVarSet::const_iterator entry = openVars.find( var->get_name() ); … … 188 227 189 228 void CommonType::visit( __attribute((unused)) ArrayType *arrayType ) {} 229 230 void CommonType::visit( ReferenceType *refType ) { 231 if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) { 232 if ( widenFirst && dynamic_cast< VoidType* >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) { 233 getCommonWithVoidPointer( otherRef, refType ); 234 } else if ( widenSecond && dynamic_cast< VoidType* >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) { 235 getCommonWithVoidPointer( refType, otherRef ); 236 } else if ( ( refType->get_base()->get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst ) 237 && ( refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers() || widenSecond ) ) { 238 Type::Qualifiers tq1 = refType->get_base()->get_qualifiers(), tq2 = otherRef->get_base()->get_qualifiers(); 239 refType->get_base()->get_qualifiers() = Type::Qualifiers(); 240 otherRef->get_base()->get_qualifiers() = Type::Qualifiers(); 241 AssertionSet have, need; 242 OpenVarSet newOpen( openVars ); 243 if ( unifyExact( refType->get_base(), otherRef->get_base(), env, have, need, newOpen, indexer ) ) { 244 if ( tq1 < tq2 ) { 245 result = refType->clone(); 246 } else { 247 result = otherRef->clone(); 248 } // if 249 result->get_qualifiers() = tq1 | tq2; 250 } else { 251 /// std::cout << "place for ptr-to-type" << std::endl; 252 } // if 253 refType->get_base()->get_qualifiers() = tq1; 254 otherRef->get_base()->get_qualifiers() = tq2; 255 } // if 256 } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) { 257 result = refType->clone(); 258 result->get_qualifiers() |= type2->get_qualifiers(); 259 } // if 260 } 261 190 262 void CommonType::visit( __attribute((unused)) FunctionType *functionType ) {} 191 263 void CommonType::visit( __attribute((unused)) StructInstType *aggregateUseType ) {} … … 195 267 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) { 196 268 // reuse BasicType, EnumInstType code by swapping type2 with enumInstType 197 Type * temp = type2;269 ValueGuard< Type * > temp( type2 ); 198 270 type2 = enumInstType; 199 temp->accept( *this ); 200 type2 = temp; 271 temp.old->accept( *this ); 201 272 } // if 202 273 }
Note: See TracChangeset
for help on using the changeset viewer.