Changeset a40d503
- Timestamp:
- Dec 1, 2017, 5:12:03 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:
- e4bc986
- Parents:
- 3ca540f
- Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r3ca540f ra40d503 469 469 std::cerr << std::endl; 470 470 ) 471 std::list< DeclarationWithType*> candidates;471 std::list< SymTab::Indexer::IdData > candidates; 472 472 decls.lookupId( curDecl->get_name(), candidates ); 473 473 /// if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; } 474 for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) { 474 for ( const auto & data : candidates ) { 475 DeclarationWithType * candidate = data.id; 475 476 PRINT( 476 477 std::cerr << "inferRecursive: candidate is "; 477 (*candidate)->print( std::cerr );478 candidate->print( std::cerr ); 478 479 std::cerr << std::endl; 479 480 ) … … 482 483 TypeEnvironment newEnv( newAlt.env ); 483 484 OpenVarSet newOpenVars( openVars ); 484 Type *adjType = (*candidate)->get_type()->clone();485 Type *adjType = candidate->get_type()->clone(); 485 486 adjustExprType( adjType, newEnv, indexer ); 486 487 adjType->accept( global_renamer ); … … 500 501 Alternative newerAlt( newAlt ); 501 502 newerAlt.env = newEnv; 502 assertf( (*candidate)->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( *candidate ).c_str() ); 503 DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ); 503 assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() ); 504 504 505 505 // everything with an empty idChain was pulled in by the current assertion. … … 516 516 // DOESN'T WORK: grandchild nodes conflict with their cousins 517 517 //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue; 518 Expression *varExpr = new VariableExpr( candDecl);518 Expression *varExpr = data.combine(); 519 519 delete varExpr->get_result(); 520 520 varExpr->set_result( adjType->clone() ); … … 522 522 std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " "; 523 523 curDecl->print( std::cerr ); 524 std::cerr << " with declaration " << (*candidate)->get_uniqueId() << " ";525 (*candidate)->print( std::cerr );524 std::cerr << " with declaration " << candidate->get_uniqueId() << " "; 525 candidate->print( std::cerr ); 526 526 std::cerr << std::endl; 527 527 ) … … 532 532 } 533 533 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions 534 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );534 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr ); 535 535 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out ); 536 536 } else { … … 1317 1317 1318 1318 void AlternativeFinder::visit( NameExpr *nameExpr ) { 1319 std::list< DeclarationWithType*> declList;1319 std::list< SymTab::Indexer::IdData > declList; 1320 1320 indexer.lookupId( nameExpr->get_name(), declList ); 1321 1321 PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; ) 1322 for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) { 1323 VariableExpr newExpr( *i ); 1324 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) ); 1322 for ( auto & data : declList ) { 1323 Expression * newExpr = data.combine(); 1324 // xxx - add in extra cost for with-statement exprs? 1325 alternatives.push_back( Alternative( newExpr, env, Cost::zero ) ); 1325 1326 PRINT( 1326 1327 std::cerr << "decl is "; 1327 (*i)->print( std::cerr );1328 data.id->print( std::cerr ); 1328 1329 std::cerr << std::endl; 1329 1330 std::cerr << "newExpr is "; 1330 newExpr .print( std::cerr );1331 newExpr->print( std::cerr ); 1331 1332 std::cerr << std::endl; 1332 1333 ) … … 1420 1421 } 1421 1422 1422 void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) { 1423 // assume no polymorphism 1424 // assume no implicit conversions 1425 assert( function->get_parameters().size() == 1 ); 1426 PRINT( 1427 std::cerr << "resolvAttr: funcDecl is "; 1428 funcDecl->print( std::cerr ); 1429 std::cerr << " argType is "; 1430 argType->print( std::cerr ); 1431 std::cerr << std::endl; 1432 ) 1433 if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) { 1434 alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) ); 1435 for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) { 1436 alternatives.back().expr->set_result( (*i)->get_type()->clone() ); 1437 } // for 1438 } // if 1423 namespace { 1424 void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) { 1425 // assume no polymorphism 1426 // assume no implicit conversions 1427 assert( function->get_parameters().size() == 1 ); 1428 PRINT( 1429 std::cerr << "resolvAttr: funcDecl is "; 1430 data.id->print( std::cerr ); 1431 std::cerr << " argType is "; 1432 argType->print( std::cerr ); 1433 std::cerr << std::endl; 1434 ) 1435 const SymTab::Indexer & indexer = finder.get_indexer(); 1436 AltList & alternatives = finder.get_alternatives(); 1437 if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) { 1438 alternatives.push_back( Alternative( new AttrExpr( data.combine(), argType->clone() ), env, Cost::zero ) ); 1439 for ( DeclarationWithType * retVal : function->returnVals ) { 1440 alternatives.back().expr->result = retVal->get_type()->clone(); 1441 } // for 1442 } // if 1443 } 1439 1444 } 1440 1445 … … 1443 1448 NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() ); 1444 1449 assert( nameExpr ); 1445 std::list< DeclarationWithType*> attrList;1450 std::list< SymTab::Indexer::IdData > attrList; 1446 1451 indexer.lookupId( nameExpr->get_name(), attrList ); 1447 1452 if ( attrExpr->get_isType() || attrExpr->get_expr() ) { 1448 for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) { 1453 for ( auto & data : attrList ) { 1454 DeclarationWithType * id = data.id; 1449 1455 // check if the type is function 1450 if ( FunctionType *function = dynamic_cast< FunctionType* >( (*i)->get_type() ) ) {1456 if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) { 1451 1457 // assume exactly one parameter 1452 1458 if ( function->get_parameters().size() == 1 ) { 1453 1459 if ( attrExpr->get_isType() ) { 1454 resolveAttr( *i, function, attrExpr->get_type(), env);1460 resolveAttr( data, function, attrExpr->get_type(), env, *this ); 1455 1461 } else { 1456 1462 AlternativeFinder finder( indexer, env ); … … 1458 1464 for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) { 1459 1465 if ( choice->expr->get_result()->size() == 1 ) { 1460 resolveAttr( *i, function, choice->expr->get_result(), choice->env);1466 resolveAttr(data, function, choice->expr->get_result(), choice->env, *this ); 1461 1467 } // fi 1462 1468 } // for … … 1466 1472 } // for 1467 1473 } else { 1468 for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) { 1469 VariableExpr newExpr( *i ); 1470 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) ); 1474 for ( auto & data : attrList ) { 1475 alternatives.push_back( Alternative( data.combine(), env, Cost::zero ) ); 1471 1476 renameTypes( alternatives.back().expr ); 1472 1477 } // for -
src/ResolvExpr/AlternativeFinder.h
r3ca540f ra40d503 142 142 template< typename OutputIterator > 143 143 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); 144 void resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env );145 144 146 145 const SymTab::Indexer &indexer; -
src/SymTab/Indexer.cc
r3ca540f ra40d503 40 40 41 41 namespace SymTab { 42 typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable; 42 std::ostream & operator<<( std::ostream & out, const Indexer::IdData & data ) { 43 return out << "(" << data.id << "," << data.baseExpr << ")"; 44 } 45 46 typedef std::unordered_map< std::string, Indexer::IdData > MangleTable; 43 47 typedef std::unordered_map< std::string, MangleTable > IdTable; 44 48 typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable; … … 97 101 } 98 102 99 void Indexer::removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType *> & out ) const {103 void Indexer::removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const { 100 104 // only need to perform this step for constructors, destructors, and assignment functions 101 105 if ( ! CodeGen::isCtorDtorAssign( id ) ) return; … … 104 108 struct ValueType { 105 109 struct DeclBall { 106 FunctionDecl *decl;110 IdData decl; 107 111 bool isUserDefinedFunc; // properties for this particular decl 108 112 bool isDefaultCtor; … … 120 124 // another FunctionDecl for the current type was found - determine 121 125 // if it has special properties and update data structure accordingly 122 ValueType & operator+=( FunctionDecl * function ) { 126 ValueType & operator+=( IdData data ) { 127 DeclarationWithType * function = data.id; 123 128 bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() ); 124 129 bool isDefaultCtor = InitTweak::isDefaultConstructor( function ); 125 130 bool isDtor = InitTweak::isDestructor( function ); 126 131 bool isCopyFunc = InitTweak::isCopyFunction( function, function->get_name() ); 127 decls.push_back( DeclBall{ function, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } );132 decls.push_back( DeclBall{ data, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } ); 128 133 existsUserDefinedFunc = existsUserDefinedFunc || isUserDefinedFunc; 129 134 existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && CodeGen::isConstructor( function->get_name() ) ); … … 135 140 }; // ValueType 136 141 137 std::list< DeclarationWithType *> copy;142 std::list< IdData > copy; 138 143 copy.splice( copy.end(), out ); 139 144 140 145 // organize discovered declarations by type 141 146 std::unordered_map< std::string, ValueType > funcMap; 142 for ( DeclarationWithType *decl : copy ) {143 if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl ) ) {147 for ( auto decl : copy ) { 148 if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) { 144 149 std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters(); 145 150 assert( ! params.empty() ); … … 147 152 Type * base = InitTweak::getPointerBase( params.front()->get_type() ); 148 153 assert( base ); 149 funcMap[ Mangler::mangle( base ) ] += function;154 funcMap[ Mangler::mangle( base ) ] += decl; 150 155 } else { 151 156 out.push_back( decl ); … … 164 169 bool noUserDefinedFunc = ! val.existsUserDefinedFunc; 165 170 bool isUserDefinedFunc = ball.isUserDefinedFunc; 166 bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl ->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides171 bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides 167 172 bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator 168 173 bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor; … … 219 224 } 220 225 221 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType*> &out ) const {226 void Indexer::lookupId( const std::string &id, std::list< IdData > &out ) const { 222 227 std::unordered_set< std::string > foundMangleNames; 223 228 … … 289 294 const MangleTable &mangleTable = decls->second; 290 295 MangleTable::const_iterator decl = mangleTable.find( mangleName ); 291 if ( decl != mangleTable.end() ) return decl->second ;296 if ( decl != mangleTable.end() ) return decl->second.id; 292 297 } 293 298 … … 304 309 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 305 310 // check for C decls with the same name, skipping those with a compatible type (by mangleName) 306 if ( ! LinkageSpec::isMangled( decl->second ->get_linkage() ) && decl->first != mangleName ) return true;311 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first != mangleName ) return true; 307 312 } 308 313 } … … 321 326 // check for C decls with the same name, skipping 322 327 // those with an incompatible type (by mangleName) 323 if ( ! LinkageSpec::isMangled( decl->second ->get_linkage() ) && decl->first == mangleName ) return true;328 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first == mangleName ) return true; 324 329 } 325 330 } … … 403 408 } 404 409 405 void Indexer::addId( DeclarationWithType *decl ) {410 void Indexer::addId( DeclarationWithType *decl, Expression * baseExpr ) { 406 411 debugPrint( "Adding Id " << decl->name << std::endl ); 407 412 makeWritable(); … … 439 444 440 445 // add to indexer 441 tables->idTable[ name ][ mangleName ] = decl;446 tables->idTable[ name ][ mangleName ] = { decl, baseExpr }; 442 447 ++tables->size; 443 448 } … … 573 578 assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() ); 574 579 575 // xxx - this is wrong, needs to somehow hook up chain of objects576 580 for ( Declaration * decl : aggr->members ) { 577 581 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 578 addId( dwt );582 addId( dwt, expr ); 579 583 } 580 584 } … … 661 665 662 666 } 667 668 Expression * Indexer::IdData::combine() const { 669 if ( baseExpr ) { 670 Expression * base = baseExpr->clone(); 671 Expression * ret = new MemberExpr( id, base ); 672 // xxx - this introduces hidden environments, for now remove them. 673 // std::swap( base->env, ret->env ); 674 delete base->env; 675 base->env = nullptr; 676 return ret; 677 } else { 678 return new VariableExpr( id ); 679 } 680 } 663 681 } // namespace SymTab 664 682 -
src/SymTab/Indexer.h
r3ca540f ra40d503 39 39 void leaveScope(); 40 40 41 struct IdData { 42 DeclarationWithType * id; 43 Expression * baseExpr; // WithExpr 44 45 Expression * combine() const; 46 }; 47 41 48 /// Gets all declarations with the given ID 42 void lookupId( const std::string &id, std::list< DeclarationWithType*> &out ) const;49 void lookupId( const std::string &id, std::list< IdData > &out ) const; 43 50 /// Gets the top-most type declaration with the given ID 44 51 NamedTypeDecl *lookupType( const std::string &id ) const; … … 67 74 TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const; 68 75 69 void addId( DeclarationWithType *decl );76 void addId( DeclarationWithType *decl, Expression * baseExpr = nullptr ); 70 77 void addType( NamedTypeDecl *decl ); 71 78 void addStruct( const std::string &id ); … … 103 110 // so that they will not be selected 104 111 // void removeSpecialOverrides( FunctionDecl *decl ); 105 void removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType *> & out ) const;112 void removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const; 106 113 107 114 /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
Note: See TracChangeset
for help on using the changeset viewer.