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