Changeset 114bde6


Ignore:
Timestamp:
Mar 20, 2019, 4:16:54 PM (3 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
arm-eh, cleanup-dtors, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, persistent-indexer
Children:
92d41a4
Parents:
181a6af
Message:

Trim old version of removeSpecialOverrides

Location:
src/SymTab
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.cc

    r181a6af r114bde6  
    7474        }
    7575
    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 functions
    78                 if ( ! CodeGen::isCtorDtorAssign( id ) ) return;
    79 
    80                 // helpful data structure to organize properties for a type
    81                 struct ValueType {
    82                         struct DeclBall { // properties for this particular decl
    83                                 IdData decl;
    84                                 bool isUserDefinedFunc;
    85                                 bool isCopyFunc;
    86                         };
    87                         // properties for this type
    88                         bool existsUserDefinedCopyFunc = false;    // user-defined copy ctor found
    89                         BaseSyntaxNode * deleteStmt = nullptr;     // non-null if a user-defined function is found
    90                         std::list< DeclBall > decls;
    91 
    92                         // another FunctionDecl for the current type was found - determine
    93                         // if it has special properties and update data structure accordingly
    94                         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                 }; // ValueType
    108 
    109                 std::list< IdData > copy;
    110                 copy.splice( copy.end(), out );
    111 
    112                 // organize discovered declarations by type
    113                 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, which
    128                 // 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 generated
    131                 // field ctors are available. If the user defines any ctor then the generated default ctor
    132                 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines
    133                 // anything that looks like a copy constructor, then the generated copy constructor is
    134                 // 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 are
    143                                 // not copy functions (assignment or copy constructor). If a  user-defined copy
    144                                 // function exists, do not pass along the non-user-defined copy functions since
    145                                 // signatures do not have to match, and the generated functions will often be
    146                                 // cheaper.
    147                                 if ( isNotUserDefinedFunc ) {
    148                                         if ( isCopyFunc ) {
    149                                                 // Skip over non-user-defined copy functions when there is a user-defined
    150                                                 // copy function. Since their signatures do not have to be exact, deleting
    151                                                 // 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 
    16476        Indexer::Indexer()
    16577        : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(),
     
    208120                        out.push_back( decl.second );
    209121                }
    210                
    211                 // some special functions, e.g. constructors and destructors
    212                 // remove autogenerated functions when they are defined so that
    213                 // they can never be matched
    214                 removeSpecialOverrides( id, out );
    215122        }
    216123
     
    461368                        // perform removals from mangle table, and deletions if necessary
    462369                        for ( const auto& key : removed ) {
     370                                ++*stats().map_mutations;
    463371                                mangleTable = mangleTable->erase( key );
    464372                        }
    465373                        if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) {
     374                                ++*stats().map_mutations;
    466375                                mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
    467376                        }
     
    493402                        // this needs to be a separate loop because of iterator invalidation
    494403                        for ( const auto& entry : deleted ) {
     404                                ++*stats().map_mutations;
    495405                                mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
    496406                        }
     
    592502                lazyInitScope();
    593503                IdData data{ decl, baseExpr, deleteStmt, scope };
     504                // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary
    594505                if ( ! removeSpecialOverrides( data, mangleTable ) ) return;
    595506                *stats().map_mutations += 2;
  • src/SymTab/Indexer.h

    r181a6af r114bde6  
    142142                const Indexer* atScope( unsigned long scope ) const;
    143143
    144                 /// Removes matching autogenerated constructors and destructors
    145                 /// so that they will not be selected
    146                 void removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const;
    147 
    148144                /// Removes matching autogenerated constructors and destructors so that they will not be
    149145                /// selected. If returns false, passed decl should not be added.
Note: See TracChangeset for help on using the changeset viewer.