Changeset 7527e63 for src/SymTab/Autogen.cc
- Timestamp:
- Aug 16, 2016, 3:20:06 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 1f6d4624
- Parents:
- 950f7a7 (diff), 7880579 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Autogen.cc
r950f7a7 r7527e63 26 26 27 27 namespace SymTab { 28 Type * SizeType = 0; 29 28 30 class AutogenerateRoutines : public Visitor { 29 31 public: … … 59 61 bool isUnnamedBitfield( ObjectDecl * obj ) { 60 62 return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL; 61 }62 63 template< typename OutputIterator >64 void makeScalarFunction( Expression *src, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) {65 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );66 // unnamed bit fields are not copied as they cannot be accessed67 if ( isUnnamedBitfield( obj ) ) return;68 69 // want to be able to generate assignment, ctor, and dtor generically,70 // so fname is either ?=?, ?{}, or ^?{}71 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );72 73 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );74 derefExpr->get_args().push_back( new VariableExpr( dstParam ) );75 76 // do something special for unnamed members77 Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );78 fExpr->get_args().push_back( dstselect );79 80 if ( src ) {81 fExpr->get_args().push_back( src );82 }83 84 Statement * callStmt = new ExprStmt( noLabels, fExpr );85 if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ) ) {86 // implicitly generated ctor/dtor calls should be wrapped87 // so that later passes are aware they were generated.88 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,89 // because this causes the address to be taken at codegen, which is illegal in C.90 callStmt = new ImplicitCtorDtorStmt( callStmt );91 }92 *out++ = callStmt;93 63 } 94 64 … … 203 173 } 204 174 205 void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric, bool forward = true ) { 206 if ( isGeneric ) { 207 // rewrite member type in terms of the type variables on this operator 208 field = field->clone(); 209 genericSubs.apply( field ); 210 211 if ( src ) { 212 genericSubs.apply( src ); 213 } 214 } 175 void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, TypeSubstitution & genericSubs, bool isDynamicLayout, bool forward = true ) { 176 // if ( isDynamicLayout && src ) { 177 // genericSubs.apply( src ); 178 // } 215 179 216 180 ObjectDecl * returnVal = NULL; … … 219 183 } 220 184 185 InitTweak::InitExpander srcParam( src ); 186 221 187 // assign to destination (and return value if generic) 222 if ( ArrayType *array = dynamic_cast< ArrayType * >( field->get_type() ) ) { 223 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 224 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 225 Expression *dstselect = new MemberExpr( field, derefExpr ); 226 227 makeArrayFunction( src, dstselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward ); 228 if ( isGeneric && returnVal ) { 229 UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) ); 230 derefRet->get_args().push_back( new VariableExpr( returnVal ) ); 231 Expression *retselect = new MemberExpr( field, derefRet ); 232 233 makeArrayFunction( src, retselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward ); 234 } 235 } else { 236 makeScalarFunction( src, dstParam, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) ); 237 if ( isGeneric && returnVal ) makeScalarFunction( src, returnVal, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) ); 188 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 189 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 190 Expression *dstselect = new MemberExpr( field, derefExpr ); 191 genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward ); 192 193 if ( isDynamicLayout && returnVal ) { 194 UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) ); 195 derefRet->get_args().push_back( new VariableExpr( returnVal ) ); 196 Expression *retselect = new MemberExpr( field, derefRet ); 197 genImplicitCall( srcParam, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward ); 238 198 } // if 239 199 } 240 200 241 201 template<typename Iterator> 242 void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool is Generic, bool forward = true ) {202 void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isDynamicLayout, bool forward = true ) { 243 203 for ( ; member != end; ++member ) { 244 204 if ( DeclarationWithType *field = dynamic_cast< DeclarationWithType * >( *member ) ) { // otherwise some form of type declaration, e.g. Aggregate … … 276 236 277 237 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL; 278 makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, is Generic, forward );238 makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isDynamicLayout, forward ); 279 239 } // if 280 240 } // for … … 284 244 /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields. 285 245 template<typename Iterator> 286 void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool is Generic) {246 void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isDynamicLayout ) { 287 247 FunctionType * ftype = func->get_functionType(); 288 248 std::list<DeclarationWithType*> & params = ftype->get_parameters(); … … 310 270 // matching parameter, initialize field with copy ctor 311 271 Expression *srcselect = new VariableExpr(*parameter); 312 makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, is Generic);272 makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isDynamicLayout ); 313 273 ++parameter; 314 274 } else { 315 275 // no matching parameter, initialize field with default ctor 316 makeStructMemberOp( dstParam, NULL, field, func, genericSubs, is Generic);276 makeStructMemberOp( dstParam, NULL, field, func, genericSubs, isDynamicLayout ); 317 277 } 318 278 } … … 324 284 325 285 // Make function polymorphic in same parameters as generic struct, if applicable 326 bool is Generic= false; // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)286 bool isDynamicLayout = false; // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union) 327 287 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters(); 328 288 std::list< Expression* > structParams; // List of matching parameters to put on types 329 289 TypeSubstitution genericSubs; // Substitutions to make to member types of struct 330 290 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) { 331 i sGeneric= true;291 if ( (*param)->get_kind() == TypeDecl::Any ) isDynamicLayout = true; 332 292 TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() ); 333 293 assignType->get_forall().push_back( typeParam ); … … 389 349 FunctionDecl * ctor = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, memCtorType->clone(), new CompoundStmt( noLabels ), true, false ); 390 350 ctor->fixUniqueId(); 391 makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, genericSubs, is Generic);351 makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, genericSubs, isDynamicLayout ); 392 352 memCtors.push_back( ctor ); 393 353 } … … 395 355 396 356 // generate appropriate calls to member ctor, assignment 397 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), assignDecl, genericSubs, is Generic);398 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctorDecl, genericSubs, is Generic);399 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), copyCtorDecl, genericSubs, is Generic);357 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), assignDecl, genericSubs, isDynamicLayout ); 358 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctorDecl, genericSubs, isDynamicLayout ); 359 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), copyCtorDecl, genericSubs, isDynamicLayout ); 400 360 // needs to do everything in reverse, so pass "forward" as false 401 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dtorDecl, genericSubs, is Generic, false );402 403 if ( ! is Generic) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );361 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dtorDecl, genericSubs, isDynamicLayout, false ); 362 363 if ( ! isDynamicLayout ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 404 364 405 365 declsToAdd.push_back( assignDecl ); … … 414 374 415 375 // Make function polymorphic in same parameters as generic union, if applicable 416 bool is Generic = false;// NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)376 bool isDynamicLayout = false; // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct) 417 377 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters(); 418 378 std::list< Expression* > unionParams; // List of matching parameters to put on types 419 379 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) { 420 i sGeneric= true;380 if ( (*param)->get_kind() == TypeDecl::Any ) isDynamicLayout = true; 421 381 TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() ); 422 382 assignType->get_forall().push_back( typeParam ); … … 454 414 455 415 makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) ); 456 if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) ); 457 458 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 416 if ( isDynamicLayout ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) ); 417 else assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 459 418 460 419 // body of assignment and copy ctor is the same
Note:
See TracChangeset
for help on using the changeset viewer.