Changeset 42f1279c for src/SymTab
- Timestamp:
- Mar 19, 2019, 11:31:06 AM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, persistent-indexer, pthread-emulation, qualifiedEnum
- Children:
- 181a6af
- Parents:
- fdae913
- Location:
- src/SymTab
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Indexer.cc
rfdae913 r42f1279c 22 22 #include <unordered_set> // for unordered_set 23 23 #include <utility> // for pair, make_pair, move 24 #include <vector> // for vector 24 25 25 26 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign … … 386 387 } 387 388 389 /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function 390 std::string getOtypeKey( FunctionDecl* function ) { 391 auto& params = function->type->parameters; 392 assert( ! params.empty() ); 393 // use base type of pointer, so that qualifiers on the pointer type aren't considered. 394 Type* base = InitTweak::getPointerBase( params.front()->get_type() ); 395 assert( base ); 396 return Mangler::mangle( base ); 397 } 398 399 /// gets the declaration for the function acting on a type specified by otype key, 400 /// nullptr if none such 401 FunctionDecl * getFunctionForOtype( DeclarationWithType * decl, const std::string& otypeKey ) { 402 FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ); 403 if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr; 404 return func; 405 } 406 407 bool Indexer::removeSpecialOverrides( 408 Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) { 409 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 410 // determinethe set of ctor/dtor/assign that can be used by the requester. In particular, 411 // if the user defines a default ctor, then the generated default ctor is unavailable, 412 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 413 // field ctors are available. If the user defines any ctor then the generated default ctor 414 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 415 // anything that looks like a copy constructor, then the generated copy constructor is 416 // unavailable, and likewise for the assignment operator. 417 418 // only relevant on function declarations 419 FunctionDecl * function = dynamic_cast< FunctionDecl * >( data.id ); 420 if ( ! function ) return true; 421 // only need to perform this check for constructors, destructors, and assignment functions 422 if ( ! CodeGen::isCtorDtorAssign( data.id->name ) ) return true; 423 424 // set up information for this type 425 bool dataIsUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage ); 426 bool dataIsCopyFunc = InitTweak::isCopyFunction( function, function->name ); 427 std::string dataOtypeKey = getOtypeKey( function ); 428 429 if ( dataIsUserDefinedFunc && dataIsCopyFunc ) { 430 // this is a user-defined copy function 431 // if this is the first such, delete/remove non-user-defined overloads as needed 432 std::vector< std::string > removed; 433 std::vector< MangleTable::value_type > deleted; 434 bool alreadyUserDefinedFunc = false; 435 436 for ( const auto& entry : *mangleTable ) { 437 // skip decls that aren't functions or are for the wrong type 438 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 439 if ( ! decl ) continue; 440 441 bool isCopyFunc = InitTweak::isCopyFunction( decl, decl->name ); 442 if ( ! LinkageSpec::isOverridable( decl->linkage ) ) { 443 // matching user-defined function 444 if ( isCopyFunc ) { 445 // mutation already performed, return early 446 return true; 447 } else { 448 // note that non-copy deletions already performed 449 alreadyUserDefinedFunc = true; 450 } 451 } else { 452 // non-user-defined function; mark for deletion/removal as appropriate 453 if ( isCopyFunc ) { 454 removed.push_back( entry.first ); 455 } else if ( ! alreadyUserDefinedFunc ) { 456 deleted.push_back( entry ); 457 } 458 } 459 } 460 461 // perform removals from mangle table, and deletions if necessary 462 for ( const auto& key : removed ) { 463 mangleTable = mangleTable->erase( key ); 464 } 465 if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) { 466 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 467 } 468 } else if ( dataIsUserDefinedFunc ) { 469 // this is a user-defined non-copy function 470 // if this is the first user-defined function, delete non-user-defined overloads 471 std::vector< MangleTable::value_type > deleted; 472 473 for ( const auto& entry : *mangleTable ) { 474 // skip decls that aren't functions or are for the wrong type 475 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 476 if ( ! decl ) continue; 477 478 // exit early if already a matching user-defined function; 479 // earlier function will have mutated table 480 if ( ! LinkageSpec::isOverridable( decl->linkage ) ) return true; 481 482 // skip mutating intrinsic functions 483 if ( decl->linkage == LinkageSpec::Intrinsic ) continue; 484 485 // user-defined non-copy functions do not override copy functions 486 if ( InitTweak::isCopyFunction( decl, decl->name ) ) continue; 487 488 // this function to be deleted after mangleTable iteration is complete 489 deleted.push_back( entry ); 490 } 491 492 // mark deletions to update mangle table 493 // this needs to be a separate loop because of iterator invalidation 494 for ( const auto& entry : deleted ) { 495 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 496 } 497 } else if ( function->linkage != LinkageSpec::Intrinsic ) { 498 // this is an overridable generated function 499 // if there already exists a matching user-defined function, delete this appropriately 500 for ( const auto& entry : *mangleTable ) { 501 // skip decls that aren't functions or are for the wrong type 502 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 503 if ( ! decl ) continue; 504 505 // skip non-user-defined functions 506 if ( LinkageSpec::isOverridable( decl->linkage ) ) continue; 507 508 if ( dataIsCopyFunc ) { 509 // remove current function if exists a user-defined copy function 510 // since the signatures for copy functions don't need to match exactly, using 511 // a delete statement is the wrong approach 512 if ( InitTweak::isCopyFunction( decl, decl->name ) ) return false; 513 } else { 514 // mark current function deleted by first user-defined function found 515 data.deleteStmt = decl; 516 return true; 517 } 518 } 519 } 520 521 // nothing (more) to fix, return true 522 return true; 523 } 524 388 525 void Indexer::addId( 389 526 DeclarationWithType *decl, OnConflict handleConflicts, Expression * baseExpr, 390 527 BaseSyntaxNode * deleteStmt ) { 391 528 ++*stats().add_calls; 392 if ( decl->name == "" ) return; 529 const std::string &name = decl->name; 530 if ( name == "" ) return; 393 531 394 const std::string &name = decl->name;395 532 std::string mangleName; 396 533 if ( LinkageSpec::isOverridable( decl->linkage ) ) { … … 454 591 // add/overwrite with new identifier 455 592 lazyInitScope(); 593 IdData data{ decl, baseExpr, deleteStmt, scope }; 594 if ( ! removeSpecialOverrides( data, mangleTable ) ) return; 456 595 *stats().map_mutations += 2; 457 idTable = idTable->set( 458 name, 459 mangleTable->set( mangleName, IdData{ decl, baseExpr, deleteStmt, scope } ) ); 596 idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) ); 460 597 } 461 598 -
src/SymTab/Indexer.h
rfdae913 r42f1279c 144 144 /// Removes matching autogenerated constructors and destructors 145 145 /// so that they will not be selected 146 /// void removeSpecialOverrides( FunctionDecl *decl );147 146 void removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const; 147 148 /// Removes matching autogenerated constructors and destructors so that they will not be 149 /// selected. If returns false, passed decl should not be added. 150 bool removeSpecialOverrides( IdData& decl, MangleTable::Ptr& mangleTable ); 148 151 149 152 /// Options for handling identifier conflicts
Note: See TracChangeset
for help on using the changeset viewer.