Changeset 114bde6
- Timestamp:
- Mar 20, 2019, 4:16:54 PM (6 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:
- 92d41a4
- Parents:
- 181a6af
- Location:
- src/SymTab
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Indexer.cc
r181a6af r114bde6 74 74 } 75 75 76 void Indexer::removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const {77 // only need to perform this step for constructors, destructors, and assignment functions78 if ( ! CodeGen::isCtorDtorAssign( id ) ) return;79 80 // helpful data structure to organize properties for a type81 struct ValueType {82 struct DeclBall { // properties for this particular decl83 IdData decl;84 bool isUserDefinedFunc;85 bool isCopyFunc;86 };87 // properties for this type88 bool existsUserDefinedCopyFunc = false; // user-defined copy ctor found89 BaseSyntaxNode * deleteStmt = nullptr; // non-null if a user-defined function is found90 std::list< DeclBall > decls;91 92 // another FunctionDecl for the current type was found - determine93 // if it has special properties and update data structure accordingly94 ValueType & operator+=( IdData data ) {95 DeclarationWithType * function = data.id;96 bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage );97 bool isCopyFunc = InitTweak::isCopyFunction( function, function->name );98 decls.push_back( DeclBall{ data, isUserDefinedFunc, isCopyFunc } );99 existsUserDefinedCopyFunc |= (isUserDefinedFunc && isCopyFunc);100 if ( isUserDefinedFunc && ! deleteStmt ) {101 // any user-defined function can act as an implicit delete statement for generated constructors.102 // a delete stmt should not act as an implicit delete statement.103 deleteStmt = data.id;104 }105 return *this;106 }107 }; // ValueType108 109 std::list< IdData > copy;110 copy.splice( copy.end(), out );111 112 // organize discovered declarations by type113 std::unordered_map< std::string, ValueType > funcMap;114 for ( auto decl : copy ) {115 if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) {116 std::list< DeclarationWithType * > & params = function->type->parameters;117 assert( ! params.empty() );118 // use base type of pointer, so that qualifiers on the pointer type aren't considered.119 Type * base = InitTweak::getPointerBase( params.front()->get_type() );120 assert( base );121 funcMap[ Mangler::mangle( base ) ] += decl;122 } else {123 out.push_back( decl );124 }125 }126 127 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which128 // determinethe set of ctor/dtor/assign that can be used by the requester. In particular,129 // if the user defines a default ctor, then the generated default ctor is unavailable,130 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated131 // field ctors are available. If the user defines any ctor then the generated default ctor132 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines133 // anything that looks like a copy constructor, then the generated copy constructor is134 // unavailable, and likewise for the assignment operator.135 for ( std::pair< const std::string, ValueType > & pair : funcMap ) {136 ValueType & val = pair.second;137 for ( ValueType::DeclBall ball : val.decls ) {138 bool isNotUserDefinedFunc = ! ball.isUserDefinedFunc && ball.decl.id->linkage != LinkageSpec::Intrinsic;139 bool isCopyFunc = ball.isCopyFunc;140 bool existsUserDefinedCopyFunc = val.existsUserDefinedCopyFunc;141 142 // only implicitly delete non-user defined functions that are not intrinsic, and are143 // not copy functions (assignment or copy constructor). If a user-defined copy144 // function exists, do not pass along the non-user-defined copy functions since145 // signatures do not have to match, and the generated functions will often be146 // cheaper.147 if ( isNotUserDefinedFunc ) {148 if ( isCopyFunc ) {149 // Skip over non-user-defined copy functions when there is a user-defined150 // copy function. Since their signatures do not have to be exact, deleting151 // them is the wrong choice.152 if ( existsUserDefinedCopyFunc ) continue;153 } else {154 // delete non-user-defined non-copy functions if applicable.155 // deleteStmt will be non-null only if a user-defined function is found.156 ball.decl.deleteStmt = val.deleteStmt;157 }158 }159 out.push_back( ball.decl );160 }161 }162 }163 164 76 Indexer::Indexer() 165 77 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), … … 208 120 out.push_back( decl.second ); 209 121 } 210 211 // some special functions, e.g. constructors and destructors212 // remove autogenerated functions when they are defined so that213 // they can never be matched214 removeSpecialOverrides( id, out );215 122 } 216 123 … … 461 368 // perform removals from mangle table, and deletions if necessary 462 369 for ( const auto& key : removed ) { 370 ++*stats().map_mutations; 463 371 mangleTable = mangleTable->erase( key ); 464 372 } 465 373 if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) { 374 ++*stats().map_mutations; 466 375 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 467 376 } … … 493 402 // this needs to be a separate loop because of iterator invalidation 494 403 for ( const auto& entry : deleted ) { 404 ++*stats().map_mutations; 495 405 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 496 406 } … … 592 502 lazyInitScope(); 593 503 IdData data{ decl, baseExpr, deleteStmt, scope }; 504 // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary 594 505 if ( ! removeSpecialOverrides( data, mangleTable ) ) return; 595 506 *stats().map_mutations += 2; -
src/SymTab/Indexer.h
r181a6af r114bde6 142 142 const Indexer* atScope( unsigned long scope ) const; 143 143 144 /// Removes matching autogenerated constructors and destructors145 /// so that they will not be selected146 void removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const;147 148 144 /// Removes matching autogenerated constructors and destructors so that they will not be 149 145 /// selected. If returns false, passed decl should not be added.
Note: See TracChangeset
for help on using the changeset viewer.