Changes in src/SymTab/Indexer.cc [1057e3d:3f024c9]
- File:
-
- 1 edited
-
src/SymTab/Indexer.cc (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Indexer.cc
r1057e3d r3f024c9 106 106 if ( ! CodeGen::isCtorDtorAssign( id ) ) return; 107 107 108 // helpful data structure to organize properties for a type108 // helpful data structure 109 109 struct ValueType { 110 struct DeclBall { // properties for this particular decl110 struct DeclBall { 111 111 IdData decl; 112 bool isUserDefinedFunc; 112 bool isUserDefinedFunc; // properties for this particular decl 113 bool isDefaultCtor; 114 bool isDtor; 113 115 bool isCopyFunc; 114 116 }; 115 117 // properties for this type 118 bool existsUserDefinedFunc = false; // any user-defined function found 119 bool existsUserDefinedCtor = false; // any user-defined constructor found 120 bool existsUserDefinedDtor = false; // any user-defined destructor found 116 121 bool existsUserDefinedCopyFunc = false; // user-defined copy ctor found 117 BaseSyntaxNode * deleteStmt = nullptr; // non-null if a user-defined function isfound122 bool existsUserDefinedDefaultCtor = false; // user-defined default ctor found 118 123 std::list< DeclBall > decls; 119 124 … … 122 127 ValueType & operator+=( IdData data ) { 123 128 DeclarationWithType * function = data.id; 124 bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage ); 125 bool isCopyFunc = InitTweak::isCopyFunction( function, function->name ); 126 decls.push_back( DeclBall{ data, isUserDefinedFunc, isCopyFunc } ); 129 bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() ); 130 bool isDefaultCtor = InitTweak::isDefaultConstructor( function ); 131 bool isDtor = InitTweak::isDestructor( function ); 132 bool isCopyFunc = InitTweak::isCopyFunction( function, function->get_name() ); 133 decls.push_back( DeclBall{ data, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } ); 134 existsUserDefinedFunc = existsUserDefinedFunc || isUserDefinedFunc; 135 existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && CodeGen::isConstructor( function->get_name() ) ); 136 existsUserDefinedDtor = existsUserDefinedDtor || (isUserDefinedFunc && isDtor); 127 137 existsUserDefinedCopyFunc = existsUserDefinedCopyFunc || (isUserDefinedFunc && isCopyFunc); 128 if ( isUserDefinedFunc && ! deleteStmt ) { 129 // any user-defined function can act as an implicit delete statement for generated constructors. 130 // a delete stmt should not act as an implicit delete statement. 131 deleteStmt = data.id; 132 } 138 existsUserDefinedDefaultCtor = existsUserDefinedDefaultCtor || (isUserDefinedFunc && isDefaultCtor); 133 139 return *this; 134 140 } … … 142 148 for ( auto decl : copy ) { 143 149 if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) { 144 std::list< DeclarationWithType * > & params = function-> type->parameters;150 std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters(); 145 151 assert( ! params.empty() ); 146 152 // use base type of pointer, so that qualifiers on the pointer type aren't considered. … … 154 160 155 161 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which determine 156 // the set of ctor/dtor/assign that can be used by the requester. In particular, if the user defines 157 // a default ctor, then the generated default ctor is unavailable, likewise for copy ctor 158 // and dtor. If the user defines any ctor/dtor, then no generated field ctors are available. 159 // If the user defines any ctor then the generated default ctor is unavailable (intrinsic default 160 // ctor must be overridden exactly). If the user defines anything that looks like a copy constructor, 161 // then the generated copy constructor is unavailable, and likewise for the assignment operator. 162 // the set of ctor/dtor/assign that are seen by the requester. In particular, if the user defines 163 // a default ctor, then the generated default ctor should never be seen, likewise for copy ctor 164 // and dtor. If the user defines any ctor/dtor, then no generated field ctors should be seen. 165 // If the user defines any ctor then the generated default ctor should not be seen (intrinsic default 166 // ctor must be overridden exactly). 162 167 for ( std::pair< const std::string, ValueType > & pair : funcMap ) { 163 168 ValueType & val = pair.second; 164 169 for ( ValueType::DeclBall ball : val.decls ) { 165 bool isNotUserDefinedFunc = ! ball.isUserDefinedFunc && ball.decl.id->linkage != LinkageSpec::Intrinsic; 166 bool isCopyFunc = ball.isCopyFunc; 167 bool existsUserDefinedCopyFunc = val.existsUserDefinedCopyFunc; 168 169 // only implicitly delete non-user defined functions that are not intrinsic, and are 170 // not copy functions (assignment or copy constructor). If a user-defined copy function exists, 171 // do not pass along the non-user-defined copy functions since signatures do not have to match, 172 // and the generated functions will often be cheaper. 173 if ( isNotUserDefinedFunc ) { 174 if ( isCopyFunc ) { 175 // Skip over non-user-defined copy functions when there is a user-defined copy function. 176 // Since their signatures do not have to be exact, deleting them is the wrong choice. 177 if ( existsUserDefinedCopyFunc ) continue; 178 } else { 179 // delete non-user-defined non-copy functions if applicable. 180 // deleteStmt will be non-null only if a user-defined function is found. 181 ball.decl.deleteStmt = val.deleteStmt; 182 } 170 bool noUserDefinedFunc = ! val.existsUserDefinedFunc; 171 bool isUserDefinedFunc = ball.isUserDefinedFunc; 172 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 173 bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator 174 bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor; 175 if ( noUserDefinedFunc || isUserDefinedFunc || isAcceptableDefaultCtor || isAcceptableCopyFunc || isAcceptableDtor ) { 176 // decl conforms to the rules described above, so it should be seen by the requester 177 out.push_back( ball.decl ); 183 178 } 184 out.push_back( ball.decl );185 179 } 186 180 } … … 477 471 void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) { 478 472 // default handling of conflicts is to raise an error 479 addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr , decl->isDeleted ? decl : nullptr);473 addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr ); 480 474 } 481 475
Note:
See TracChangeset
for help on using the changeset viewer.