Changeset 28e58fd for src/SymTab/Autogen.cc
- Timestamp:
- Aug 25, 2017, 10:38:34 AM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 800d275
- Parents:
- af08051 (diff), 3eab308c (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
raf08051 r28e58fd 13 13 // Update Count : 62 14 14 // 15 15 16 #include "Autogen.h" 16 17 … … 24 25 #include <vector> // for vector 25 26 26 #include "AddVisit.h" // for addVisit 27 #include "Common/ScopedMap.h" // for ScopedMap 28 #include "GenPoly/DeclMutator.h" // for DeclMutator 29 #include "GenPoly/ScopedSet.h" // for ScopedSet 30 #include "Parser/LinkageSpec.h" // for AutoGen, Intrinsic, Spec 31 #include "SymTab/Mangler.h" // for mangleType 32 #include "SynTree/Statement.h" // for SwitchStmt (ptr only), CompoundStmt 33 #include "SynTree/Type.h" // for Type, ArrayType, Type::StorageClasses 34 #include "SynTree/Visitor.h" // for Visitor 27 #include "AddVisit.h" // for addVisit 28 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign 29 #include "Common/ScopedMap.h" // for ScopedMap<>::const_iterator, Scope... 30 #include "Common/utility.h" // for cloneAll, operator+ 31 #include "GenPoly/DeclMutator.h" // for DeclMutator 32 #include "GenPoly/ScopedSet.h" // for ScopedSet, ScopedSet<>::iterator 33 #include "SymTab/Mangler.h" // for Mangler 34 #include "SynTree/Attribute.h" // For Attribute 35 #include "SynTree/Mutator.h" // for maybeMutate 36 #include "SynTree/Statement.h" // for CompoundStmt, ReturnStmt, ExprStmt 37 #include "SynTree/Type.h" // for FunctionType, Type, TypeInstType 38 #include "SynTree/Visitor.h" // for maybeAccept, Visitor, acceptAll 39 40 class Attribute; 35 41 36 42 namespace SymTab { … … 130 136 FunctionType * genDefaultType( Type * paramType ) { 131 137 FunctionType *ftype = new FunctionType( Type::Qualifiers(), false ); 132 ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), paramType->clone() ), nullptr );138 ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr ); 133 139 ftype->get_parameters().push_back( dstParam ); 134 140 … … 150 156 ftype->get_returnVals().push_back( returnVal ); 151 157 return ftype; 152 }153 154 /// true if the aggregate's layout is dynamic155 template< typename AggrDecl >156 bool hasDynamicLayout( AggrDecl * aggregateDecl ) {157 for ( TypeDecl * param : aggregateDecl->get_parameters() ) {158 if ( param->isComplete() ) return true;159 }160 return false;161 158 } 162 159 … … 181 178 FunctionType * ftype = funcDecl->get_functionType(); 182 179 assert( ! ftype->get_parameters().empty() ); 183 Type * t = safe_dynamic_cast< PointerType * >( ftype->get_parameters().front()->get_type() )->get_base(); 180 Type * t = InitTweak::getPointerBase( ftype->get_parameters().front()->get_type() ); 181 assert( t ); 184 182 map.insert( Mangler::mangleType( t ), true ); 185 183 } … … 227 225 FunctionType * ftype = data.genType( refType ); 228 226 229 if(concurrent_type && InitTweak::isDestructor( data.fname )) {227 if(concurrent_type && CodeGen::isDestructor( data.fname )) { 230 228 ftype->get_parameters().front()->get_type()->set_mutex( true ); 231 229 } … … 279 277 FunctionType *copyCtorType = genCopyType( refType->clone() ); 280 278 279 // add unused attribute to parameters of default constructor and destructor 280 ctorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 281 dtorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 282 281 283 // xxx - should we also generate void ?{}(E *, int) and E ?{}(E *, E)? 282 284 // right now these cases work, but that might change. … … 301 303 302 304 /// generates a single struct member operation (constructor call, destructor call, assignment call) 303 void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool isDynamicLayout, bool forward = true ) { 304 ObjectDecl * returnVal = NULL; 305 if ( ! func->get_functionType()->get_returnVals().empty() ) { 306 returnVal = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_returnVals().front() ); 307 } 308 305 void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward = true ) { 309 306 InitTweak::InitExpander srcParam( src ); 310 307 311 // assign to destination (and return value if generic) 312 UntypedExpr *derefExpr = UntypedExpr::createDeref( new VariableExpr( dstParam ) ); 313 Expression *dstselect = new MemberExpr( field, derefExpr ); 308 // assign to destination 309 Expression *dstselect = new MemberExpr( field, new CastExpr( new VariableExpr( dstParam ), safe_dynamic_cast< ReferenceType* >( dstParam->get_type() )->get_base()->clone() ) ); 314 310 genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward ); 315 316 if ( isDynamicLayout && returnVal ) {317 // xxx - there used to be a dereference on returnVal, but this seems to have been wrong?318 Expression *retselect = new MemberExpr( field, new VariableExpr( returnVal ) );319 genImplicitCall( srcParam, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );320 } // if321 311 } 322 312 323 313 /// generates the body of a struct function by iterating the struct members (via parameters) - generates default ctor, copy ctor, assignment, and dtor bodies, but NOT field ctor bodies 324 314 template<typename Iterator> 325 void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool isDynamicLayout, boolforward = true ) {315 void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward = true ) { 326 316 for ( ; member != end; ++member ) { 327 317 if ( DeclarationWithType *field = dynamic_cast< DeclarationWithType * >( *member ) ) { // otherwise some form of type declaration, e.g. Aggregate … … 359 349 360 350 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL; 361 makeStructMemberOp( dstParam, srcselect, field, func, isDynamicLayout,forward );351 makeStructMemberOp( dstParam, srcselect, field, func, forward ); 362 352 } // if 363 353 } // for … … 367 357 /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields. 368 358 template<typename Iterator> 369 void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func , bool isDynamicLayout) {359 void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func ) { 370 360 FunctionType * ftype = func->get_functionType(); 371 361 std::list<DeclarationWithType*> & params = ftype->get_parameters(); … … 393 383 // matching parameter, initialize field with copy ctor 394 384 Expression *srcselect = new VariableExpr(*parameter); 395 makeStructMemberOp( dstParam, srcselect, field, func , isDynamicLayout);385 makeStructMemberOp( dstParam, srcselect, field, func ); 396 386 ++parameter; 397 387 } else { 398 388 // no matching parameter, initialize field with default ctor 399 makeStructMemberOp( dstParam, NULL, field, func , isDynamicLayout);389 makeStructMemberOp( dstParam, NULL, field, func ); 400 390 } 401 391 } … … 413 403 // Make function polymorphic in same parameters as generic struct, if applicable 414 404 const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions 415 bool isDynamicLayout = hasDynamicLayout( aggregateDecl ); // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)416 405 417 406 // generate each of the functions based on the supplied FuncData objects … … 423 412 424 413 // field ctors are only generated if default constructor and copy constructor are both generated 425 unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return InitTweak::isConstructor( dcl->get_name() ); } );414 unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return CodeGen::isConstructor( dcl->get_name() ); } ); 426 415 427 416 if ( functionNesting == 0 ) { … … 438 427 // generate appropriate calls to member ctor, assignment 439 428 // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor 440 if ( ! InitTweak::isDestructor( dcl->get_name() ) ) {441 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl , isDynamicLayout);429 if ( ! CodeGen::isDestructor( dcl->get_name() ) ) { 430 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl ); 442 431 } else { 443 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, isDynamicLayout,false );444 } 445 if ( InitTweak::isAssignment( dcl->get_name() ) ) {432 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, false ); 433 } 434 if ( CodeGen::isAssignment( dcl->get_name() ) ) { 446 435 // assignment needs to return a value 447 436 FunctionType * assignType = dcl->get_functionType(); … … 472 461 // our inheritance model. I think the correct way to handle this is to 473 462 // cast the structure to the type of the member and let the resolver 474 // figure out whether it's valid and have a pass afterwards that fixes 475 // the assignment to use pointer arithmetic with the offset of the 476 // member, much like how generic type members are handled. 463 // figure out whether it's valid/choose the correct unnamed member 477 464 continue; 478 465 } 479 466 memCtorType->get_parameters().push_back( new ObjectDecl( member->get_name(), Type::StorageClasses(), LinkageSpec::Cforall, 0, member->get_type()->clone(), 0 ) ); 480 467 FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting ); 481 makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor , isDynamicLayout);468 makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor ); 482 469 declsToAdd.push_back( ctor ); 483 470 } … … 490 477 void makeUnionFieldsAssignment( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) { 491 478 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); 492 copy->get_args().push_back( new VariableExpr( dstParam) );479 copy->get_args().push_back( new AddressExpr( new VariableExpr( dstParam ) ) ); 493 480 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) ); 494 481 copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) ); … … 502 489 ObjectDecl * dstParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() ); 503 490 ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().back() ); 504 ObjectDecl * returnVal = nullptr;505 if ( ! ftype->get_returnVals().empty() ) {506 returnVal = safe_dynamic_cast< ObjectDecl * >( ftype->get_returnVals().front() );507 }508 491 509 492 makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) ); 510 if ( returnVal ) { 493 if ( CodeGen::isAssignment( funcDecl->get_name() ) ) { 494 // also generate return statement in assignment 511 495 funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 512 496 } … … 535 519 cloneAll( typeParams, copyCtorType->get_forall() ); 536 520 cloneAll( typeParams, assignType->get_forall() ); 521 522 // add unused attribute to parameters of default constructor and destructor 523 ctorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 524 dtorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 537 525 538 526 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
Note: See TracChangeset
for help on using the changeset viewer.