Changes in src/SymTab/Autogen.cc [6ea87486:46adb83]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Autogen.cc
r6ea87486 r46adb83 10 10 // Created On : Thu Mar 03 15:45:56 2016 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jul 14 16:41:00 201713 // Update Count : 6 212 // Last Modified On : Wed Jun 28 15:30:00 2017 13 // Update Count : 61 14 14 // 15 15 … … 17 17 #include <iterator> 18 18 #include "SynTree/Visitor.h" 19 #include "SynTree/Attribute.h" 19 20 #include "SynTree/Type.h" 20 21 #include "SynTree/Statement.h" 21 22 #include "SynTree/TypeSubstitution.h" 22 23 #include "Common/utility.h" 24 #include "CodeGen/OperatorTable.h" 23 25 #include "AddVisit.h" 24 26 #include "MakeLibCfa.h" … … 125 127 FunctionType * genDefaultType( Type * paramType ) { 126 128 FunctionType *ftype = new FunctionType( Type::Qualifiers(), false ); 127 ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), paramType->clone() ), nullptr );129 ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr ); 128 130 ftype->get_parameters().push_back( dstParam ); 129 131 … … 176 178 FunctionType * ftype = funcDecl->get_functionType(); 177 179 assert( ! ftype->get_parameters().empty() ); 178 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 ); 179 182 map.insert( Mangler::mangleType( t ), true ); 180 183 } … … 222 225 FunctionType * ftype = data.genType( refType ); 223 226 224 if(concurrent_type && InitTweak::isDestructor( data.fname )) {227 if(concurrent_type && CodeGen::isDestructor( data.fname )) { 225 228 ftype->get_parameters().front()->get_type()->set_mutex( true ); 226 229 } … … 274 277 FunctionType *copyCtorType = genCopyType( refType->clone() ); 275 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 276 283 // xxx - should we also generate void ?{}(E *, int) and E ?{}(E *, E)? 277 284 // right now these cases work, but that might change. … … 297 304 /// generates a single struct member operation (constructor call, destructor call, assignment call) 298 305 void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool isDynamicLayout, bool forward = true ) { 299 ObjectDecl * returnVal = NULL;300 if ( ! func->get_functionType()->get_returnVals().empty() ) {301 returnVal = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_returnVals().front() );302 }303 304 306 InitTweak::InitExpander srcParam( src ); 305 307 306 // assign to destination (and return value if generic) 307 UntypedExpr *derefExpr = UntypedExpr::createDeref( new VariableExpr( dstParam ) ); 308 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() ) ); 309 310 genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward ); 310 311 if ( isDynamicLayout && returnVal ) {312 // xxx - there used to be a dereference on returnVal, but this seems to have been wrong?313 Expression *retselect = new MemberExpr( field, new VariableExpr( returnVal ) );314 genImplicitCall( srcParam, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );315 } // if316 311 } 317 312 … … 401 396 void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) { 402 397 // Builtins do not use autogeneration. 403 if ( aggregateDecl->get_linkage() == LinkageSpec::Builtin CFA||398 if ( aggregateDecl->get_linkage() == LinkageSpec::Builtin || 404 399 aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) { 405 400 return; … … 418 413 419 414 // field ctors are only generated if default constructor and copy constructor are both generated 420 unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return InitTweak::isConstructor( dcl->get_name() ); } );415 unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return CodeGen::isConstructor( dcl->get_name() ); } ); 421 416 422 417 if ( functionNesting == 0 ) { … … 433 428 // generate appropriate calls to member ctor, assignment 434 429 // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor 435 if ( ! InitTweak::isDestructor( dcl->get_name() ) ) {430 if ( ! CodeGen::isDestructor( dcl->get_name() ) ) { 436 431 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl, isDynamicLayout ); 437 432 } else { 438 433 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, isDynamicLayout, false ); 439 434 } 440 if ( InitTweak::isAssignment( dcl->get_name() ) ) {435 if ( CodeGen::isAssignment( dcl->get_name() ) ) { 441 436 // assignment needs to return a value 442 437 FunctionType * assignType = dcl->get_functionType(); … … 467 462 // our inheritance model. I think the correct way to handle this is to 468 463 // cast the structure to the type of the member and let the resolver 469 // figure out whether it's valid and have a pass afterwards that fixes 470 // the assignment to use pointer arithmetic with the offset of the 471 // member, much like how generic type members are handled. 464 // figure out whether it's valid/choose the correct unnamed member 472 465 continue; 473 466 } … … 485 478 void makeUnionFieldsAssignment( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) { 486 479 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); 487 copy->get_args().push_back( new VariableExpr( dstParam) );480 copy->get_args().push_back( new AddressExpr( new VariableExpr( dstParam ) ) ); 488 481 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) ); 489 482 copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) ); … … 497 490 ObjectDecl * dstParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() ); 498 491 ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().back() ); 499 ObjectDecl * returnVal = nullptr;500 if ( ! ftype->get_returnVals().empty() ) {501 returnVal = safe_dynamic_cast< ObjectDecl * >( ftype->get_returnVals().front() );502 }503 492 504 493 makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) ); 505 if ( returnVal ) { 494 if ( CodeGen::isAssignment( funcDecl->get_name() ) ) { 495 // also generate return statement in assignment 506 496 funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 507 497 } … … 512 502 // Make function polymorphic in same parameters as generic union, if applicable 513 503 const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions 514 504 515 505 // default ctor/dtor need only first parameter 516 506 // void ?{}(T *); void ^?{}(T *); … … 530 520 cloneAll( typeParams, copyCtorType->get_forall() ); 531 521 cloneAll( typeParams, assignType->get_forall() ); 522 523 // add unused attribute to parameters of default constructor and destructor 524 ctorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 525 dtorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 532 526 533 527 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
Note: See TracChangeset
for help on using the changeset viewer.