Changeset c14cff1 for src/GenPoly
- Timestamp:
- Feb 25, 2016, 5:16:15 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 071a31a
- Parents:
- a9a259c (diff), ac1ed49 (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/GenPoly/Box.cc
ra9a259c rc14cff1 25 25 #include "PolyMutator.h" 26 26 #include "FindFunction.h" 27 #include "ScopedMap.h"28 27 #include "ScrubTyVars.h" 29 28 … … 38 37 39 38 #include "ResolvExpr/TypeEnvironment.h" 39 #include "ResolvExpr/TypeMap.h" 40 #include "ResolvExpr/typeops.h" 40 41 41 42 #include "SymTab/Mangler.h" … … 101 102 typedef std::map< std::string, DeclarationWithType *> AdapterMap; 102 103 std::map< std::string, DeclarationWithType *> assignOps; 103 ScopedMap< std::string, DeclarationWithType *> scopedAssignOps;104 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; 104 105 std::stack< AdapterMap > adapters; 105 106 DeclarationWithType *retval; … … 248 249 } 249 250 250 /// returns T if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be), NULL otherwise251 ReferenceToType *isAssignment( DeclarationWithType *decl ) {251 /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise 252 TypeInstType *isTypeInstAssignment( DeclarationWithType *decl ) { 252 253 if ( decl->get_name() == "?=?" ) { 253 254 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) { 254 255 if ( funType->get_parameters().size() == 2 ) { 255 256 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 256 if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( pointer->get_base() ) ) {257 if ( ReferenceToType *refType2 = dynamic_cast< ReferenceToType *>( funType->get_parameters().back()->get_type() ) ) {257 if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 258 if ( TypeInstType *refType2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) { 258 259 if ( refType->get_name() == refType2->get_name() ) { 259 260 return refType; … … 267 268 return 0; 268 269 } 270 271 /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise 272 /// Only picks assignments where neither parameter is cv-qualified 273 Type *isAssignment( DeclarationWithType *decl ) { 274 if ( decl->get_name() == "?=?" ) { 275 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) { 276 if ( funType->get_parameters().size() == 2 ) { 277 Type::Qualifiers defaultQualifiers; 278 Type *paramType1 = funType->get_parameters().front()->get_type(); 279 if ( paramType1->get_qualifiers() != defaultQualifiers ) return 0; 280 Type *paramType2 = funType->get_parameters().back()->get_type(); 281 if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0; 282 283 if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) { 284 Type *baseType1 = pointerType->get_base(); 285 if ( baseType1->get_qualifiers() != defaultQualifiers ) return 0; 286 SymTab::Indexer dummy; 287 if ( ResolvExpr::typesCompatible( baseType1, paramType2, dummy ) ) { 288 return baseType1; 289 } // if 290 } // if 291 } // if 292 } // if 293 } // if 294 return 0; 295 } 269 296 270 297 void Pass1::findAssignOps( const std::list< TypeDecl *> &forall ) { … … 274 301 for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { 275 302 std::string typeName; 276 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( isAssignment( *assert )) ) {303 if ( TypeInstType *typeInst = isTypeInstAssignment( *assert ) ) { 277 304 assignOps[ typeInst->get_name() ] = *assert; 278 305 } // if … … 283 310 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 284 311 // if this is a polymorphic assignment function, put it in the map for this scope 285 if ( ReferenceToType *refType = isAssignment( functionDecl ) ) {286 if ( ! dynamic_cast< TypeInstType* >( refType ) ) {287 scopedAssignOps.insert( refType->get_name(), functionDecl );312 if ( Type *assignedType = isAssignment( functionDecl ) ) { 313 if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) { 314 scopedAssignOps.insert( assignedType, functionDecl ); 288 315 } 289 316 } … … 935 962 TyVarMap exprTyVars; 936 963 makeTyVarMap( function, exprTyVars ); 937 ReferenceToType *polyRetType = 0;938 939 if ( polyRetType = isPolyRet( function )) {964 ReferenceToType *polyRetType = isPolyRet( function ); 965 966 if ( polyRetType ) { 940 967 ret = addPolyRetParam( appExpr, function, polyRetType, arg ); 941 968 } else if ( needsAdapter( function, scopeTyVars ) ) { … … 1043 1070 } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) { 1044 1071 // find assignment operator for generic type 1045 ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name());1046 if ( assignIter == scopedAssignOps.end()) {1072 DeclarationWithType *functionDecl = scopedAssignOps.find( refType ); 1073 if ( ! functionDecl ) { 1047 1074 throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() ); 1048 1075 } 1049 1076 1050 1077 // wrap it up in an application expression 1051 DeclarationWithType *functionDecl = assignIter->second;1052 1078 assignExpr = new ApplicationExpr( wrapFunctionDecl( functionDecl ) ); 1053 1079 assignExpr->set_env( env->clone() ); … … 1064 1090 assert( ! asserts.empty() && "Type param needs assignment operator assertion" ); 1065 1091 DeclarationWithType *actualDecl = asserts.front(); 1066 ReferenceToType *actualType = isAssignment( actualDecl );1092 TypeInstType *actualType = isTypeInstAssignment( actualDecl ); 1067 1093 assert( actualType && "First assertion of type with assertions should be assignment operator" ); 1068 1094 TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt ); … … 1078 1104 } 1079 1105 assertAssign = assertAssignIt->second; 1080 //assignExpr->get_env()->add( formalTypeInstType->get_name(), actualType ); 1081 } else if ( ReferenceToType *formalReferenceType = dynamic_cast< ReferenceToType* >( formalType ) ) { 1082 ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = scopedAssignOps.find( formalReferenceType->get_name() ); 1083 if ( assertAssignIt == scopedAssignOps.end() ) { 1084 throw SemanticError( "No assignment operation found for ", formalReferenceType ); 1106 } else { 1107 assertAssign = scopedAssignOps.find( formalType ); 1108 if ( ! assertAssign ) { 1109 throw SemanticError( "No assignment operation found for ", formalType ); 1085 1110 } 1086 assertAssign = assertAssignIt->second; 1087 } else assert( false && "returning polymorphic types with non struct/polymorphic parameters not yet supported" ); 1111 } 1088 1112 1089 1113 … … 1425 1449 assert( newMemberExpr ); 1426 1450 1427 // wrap pointer members in appropriate cast 1428 if ( dynamic_cast< PointerType* >( memberExpr->get_member()->get_type() ) ) { 1429 CastExpr *ptrCastExpr = new CastExpr( newMemberExpr, new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ) ) ); 1451 Type *memberType = memberExpr->get_member()->get_type(); 1452 if ( ! isPolyType( memberType, scopeTyVars ) ) { 1453 // Not all members of a polymorphic type are themselves of polymorphic type; in this case the member expression should be wrapped and dereferenced to form an lvalue 1454 CastExpr *ptrCastExpr = new CastExpr( newMemberExpr, new PointerType( Type::Qualifiers(), memberType->clone() ) ); 1430 1455 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 1431 1456 derefExpr->get_args().push_back( ptrCastExpr );
Note: See TracChangeset
for help on using the changeset viewer.