Changeset 1ced874 for src/InitTweak
- Timestamp:
- Sep 6, 2016, 4:36:29 PM (9 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:
- e76acbe
- Parents:
- 0362d42 (diff), f04a8b81 (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. - Location:
- src/InitTweak
- Files:
-
- 4 edited
-
FixInit.cc (modified) (8 diffs)
-
GenInit.cc (modified) (9 diffs)
-
InitTweak.cc (modified) (6 diffs)
-
InitTweak.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
r0362d42 r1ced874 200 200 ObjectDecl * thisParam = 0; 201 201 bool isCtor = false; // true if current function is a constructor 202 StructDecl * structDecl = 0; 202 203 }; 203 204 … … 744 745 ValueGuard< ObjectDecl * > oldThisParam( thisParam ); 745 746 ValueGuard< bool > oldIsCtor( isCtor ); 747 ValueGuard< StructDecl * > oldStructDecl( structDecl ); 746 748 747 749 // need to start with fresh sets … … 758 760 StructInstType * structType = dynamic_cast< StructInstType * >( ptrType->get_base() ); 759 761 if ( structType ) { 760 StructDecl *structDecl = structType->get_baseStruct();762 structDecl = structType->get_baseStruct(); 761 763 for ( Declaration * member : structDecl->get_members() ) { 762 764 if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) { … … 775 777 std::set_difference( usedUninit.begin(), usedUninit.end(), unhandled.begin(), unhandled.end(), std::inserter( diff, diff.begin() ) ); 776 778 for ( DeclarationWithType * member : diff ) { 777 emit( "in ", CodeGen::genType( function->get_functionType(), function->get_name(), false ), ", member", member->get_name(), " used before being constructed" );779 emit( "in ", CodeGen::genType( function->get_functionType(), function->get_name(), false ), ", field ", member->get_name(), " used before being constructed" ); 778 780 } 779 781 … … 781 783 // need to explicitly re-add function parameters in order to resolve copy constructors 782 784 enterScope(); 783 // maybeAccept( function->get_functionType(), *this ); 784 for ( DeclarationWithType * member : unhandled ) { 785 // insert and resolve default/copy constructor call for each member that's unhandled 785 maybeAccept( function->get_functionType(), *this ); 786 787 // need to iterate through members in reverse in order for 788 // ctor/dtor statements to come out in the right order 789 for ( Declaration * member : reverseIterate( structDecl->get_members() ) ) { 790 DeclarationWithType * field = dynamic_cast< DeclarationWithType * >( member ); 791 // skip non-DWT members 792 if ( ! field ) continue; 793 // skip handled members 794 if ( ! unhandled.count( field ) ) continue; 795 796 // insert and resolve default/copy constructor call for each field that's unhandled 786 797 std::list< Statement * > stmt; 787 798 UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) ); 788 799 deref->get_args().push_back( new VariableExpr( thisParam ) ); 789 InitExpander srcParam( (Initializer *)NULL ); // xxx - if copy ctor, need to pass appropriate argument - second param of this function dot member 790 SymTab::genImplicitCall( srcParam, new MemberExpr( member, deref ), function->get_name(), back_inserter( stmt ), member, isCtor ); 800 801 Expression * arg2 = 0; 802 if ( isCopyConstructor( function ) ) { 803 // if copy ctor, need to pass second-param-of-this-function.field 804 std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters(); 805 assert( params.size() == 2 ); 806 arg2 = new MemberExpr( field, new VariableExpr( params.back() ) ); 807 } 808 InitExpander srcParam( arg2 ); 809 SymTab::genImplicitCall( srcParam, new MemberExpr( field, deref ), function->get_name(), back_inserter( stmt ), field, isCtor ); 791 810 792 811 assert( stmt.size() <= 1 ); … … 796 815 MutatingResolver resolver( *this ); 797 816 try { 798 // xxx - these should be in field declaration order799 817 callStmt->acceptMutator( resolver ); 800 818 if ( isCtor ) { … … 805 823 } 806 824 } catch ( SemanticError & error ) { 807 emit( "in ", CodeGen::genType( function->get_functionType(), function->get_name(), false ), ", member ", member->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed", " and no ", isCtor ? "default constructor" : "destructor", " found" );825 emit( "in ", CodeGen::genType( function->get_functionType(), function->get_name(), false ), ", field ", field->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed", " and no ", isCtor ? "default constructor" : "destructor", " found" ); 808 826 } 809 827 } … … 832 850 handleFirstParam( firstParam ); 833 851 } 834 } else if ( fname == "?=?" && isIntrinsicCallExpr( appExpr ) ) {835 // forgive use of intrinsic assignment to construct, since instrinsic constructors836 // codegen as assignment anyway.837 assert( appExpr->get_args().size() == 2 );838 handleFirstParam( appExpr->get_args().front() );839 852 } 840 853 -
src/InitTweak/GenInit.cc
r0362d42 r1ced874 25 25 #include "SynTree/Mutator.h" 26 26 #include "SymTab/Autogen.h" 27 #include "SymTab/Mangler.h" 27 28 #include "GenPoly/PolyMutator.h" 28 29 #include "GenPoly/DeclMutator.h" 30 #include "GenPoly/ScopedSet.h" 29 31 30 32 namespace InitTweak { … … 55 57 class CtorDtor : public GenPoly::PolyMutator { 56 58 public: 59 typedef GenPoly::PolyMutator Parent; 60 using Parent::mutate; 57 61 /// create constructor and destructor statements for object declarations. 58 62 /// the actual call statements will be added in after the resolver has run … … 65 69 // should not traverse into any of these declarations to find objects 66 70 // that need to be constructed or destructed 67 virtual Declaration* mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }71 virtual Declaration* mutate( StructDecl *aggregateDecl ); 68 72 virtual Declaration* mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; } 69 73 virtual Declaration* mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; } … … 74 78 virtual Type * mutate( FunctionType *funcType ) { return funcType; } 75 79 76 protected: 80 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ); 81 82 private: 83 // set of mangled type names for which a constructor or destructor exists in the current scope. 84 // these types require a ConstructorInit node to be generated, anything else is a POD type and thus 85 // should not have a ConstructorInit generated. 86 87 bool isManaged( ObjectDecl * objDecl ) const ; // determine if object is managed 88 void handleDWT( DeclarationWithType * dwt ); // add type to managed if ctor/dtor 89 GenPoly::ScopedSet< std::string > managedTypes; 90 bool inFunction = false; 77 91 }; 78 92 … … 142 156 143 157 DeclarationWithType* ReturnFixer::mutate( FunctionDecl *functionDecl ) { 144 std::list<DeclarationWithType*> oldReturnVals = returnVals;145 std::string oldFuncName = funcName;158 ValueGuard< std::list<DeclarationWithType*> > oldReturnVals( returnVals ); 159 ValueGuard< std::string > oldFuncName( funcName ); 146 160 147 161 FunctionType * type = functionDecl->get_functionType(); … … 149 163 funcName = functionDecl->get_name(); 150 164 DeclarationWithType * decl = Mutator::mutate( functionDecl ); 151 returnVals = oldReturnVals;152 funcName = oldFuncName;153 165 return decl; 154 166 } … … 197 209 198 210 DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) { 199 bool oldInFunc = inFunction;211 ValueGuard< bool > oldInFunc( inFunction ); 200 212 inFunction = true; 201 213 DeclarationWithType * decl = Parent::mutate( functionDecl ); 202 inFunction = oldInFunc;203 214 return decl; 204 215 } … … 209 220 } 210 221 222 bool CtorDtor::isManaged( ObjectDecl * objDecl ) const { 223 Type * type = objDecl->get_type(); 224 while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 225 type = at->get_base(); 226 } 227 return managedTypes.find( SymTab::Mangler::mangle( type ) ) != managedTypes.end(); 228 } 229 230 void CtorDtor::handleDWT( DeclarationWithType * dwt ) { 231 // if this function is a user-defined constructor or destructor, mark down the type as "managed" 232 if ( ! LinkageSpec::isOverridable( dwt->get_linkage() ) && isCtorDtor( dwt->get_name() ) ) { 233 std::list< DeclarationWithType * > & params = GenPoly::getFunctionType( dwt->get_type() )->get_parameters(); 234 assert( ! params.empty() ); 235 PointerType * type = safe_dynamic_cast< PointerType * >( params.front()->get_type() ); 236 managedTypes.insert( SymTab::Mangler::mangle( type->get_base() ) ); 237 } 238 } 239 211 240 DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) { 212 // hands off if designated, if @=, or if extern 213 if ( tryConstruct( objDecl ) ) { 241 handleDWT( objDecl ); 242 // hands off if @=, extern, builtin, etc. 243 // if global but initializer is not constexpr, always try to construct, since this is not legal C 244 if ( ( tryConstruct( objDecl ) && isManaged( objDecl ) ) || (! inFunction && ! isConstExpr( objDecl->get_init() ) ) ) { 245 // constructed objects cannot be designated 246 if ( isDesignated( objDecl->get_init() ) ) throw SemanticError( "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.", objDecl ); 247 // constructed objects should not have initializers nested too deeply 248 if ( ! checkInitDepth( objDecl ) ) throw SemanticError( "Managed object's initializer is too deep ", objDecl ); 249 214 250 // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor 215 251 // for each constructable object … … 241 277 } 242 278 } 243 return Mutator::mutate( objDecl );279 return Parent::mutate( objDecl ); 244 280 } 245 281 246 282 DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) { 283 ValueGuard< bool > oldInFunc = inFunction; 284 inFunction = true; 285 286 handleDWT( functionDecl ); 287 288 managedTypes.beginScope(); 289 // go through assertions and recursively add seen ctor/dtors 290 for ( TypeDecl * tyDecl : functionDecl->get_functionType()->get_forall() ) { 291 for ( DeclarationWithType *& assertion : tyDecl->get_assertions() ) { 292 assertion = assertion->acceptMutator( *this ); 293 } 294 } 247 295 // parameters should not be constructed and destructed, so don't mutate FunctionType 248 296 mutateAll( functionDecl->get_oldDecls(), *this ); 249 297 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) ); 298 299 managedTypes.endScope(); 250 300 return functionDecl; 251 301 } 302 303 Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) { 304 // don't construct members, but need to take note if there is a managed member, 305 // because that means that this type is also managed 306 for ( Declaration * member : aggregateDecl->get_members() ) { 307 if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) { 308 if ( isManaged( field ) ) { 309 managedTypes.insert( SymTab::Mangler::mangle( aggregateDecl ) ); 310 break; 311 } 312 } 313 } 314 return aggregateDecl; 315 } 316 317 CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) { 318 managedTypes.beginScope(); 319 CompoundStmt * stmt = Parent::mutate( compoundStmt ); 320 managedTypes.endScope(); 321 return stmt; 322 } 323 252 324 } // namespace InitTweak 253 325 -
src/InitTweak/InitTweak.cc
r0362d42 r1ced874 7 7 #include "SynTree/Attribute.h" 8 8 #include "GenPoly/GenPoly.h" 9 #include "ResolvExpr/typeops.h" 9 10 10 11 namespace InitTweak { … … 22 23 }; 23 24 25 class InitDepthChecker : public Visitor { 26 public: 27 bool depthOkay = true; 28 Type * type; 29 int curDepth = 0, maxDepth = 0; 30 InitDepthChecker( Type * type ) : type( type ) { 31 Type * t = type; 32 while ( ArrayType * at = dynamic_cast< ArrayType * >( t ) ) { 33 maxDepth++; 34 t = at->get_base(); 35 } 36 maxDepth++; 37 } 38 virtual void visit( ListInit * listInit ) { 39 curDepth++; 40 if ( curDepth > maxDepth ) depthOkay = false; 41 Visitor::visit( listInit ); 42 curDepth--; 43 } 44 }; 45 24 46 class InitFlattener : public Visitor { 25 47 public: … … 52 74 maybeAccept( init, finder ); 53 75 return finder.hasDesignations; 76 } 77 78 bool checkInitDepth( ObjectDecl * objDecl ) { 79 InitDepthChecker checker( objDecl->get_type() ); 80 maybeAccept( objDecl->get_init(), checker ); 81 return checker.depthOkay; 54 82 } 55 83 … … 231 259 return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) && 232 260 (objDecl->get_init() == NULL || 233 ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) && 234 ! isDesignated( objDecl->get_init() ) 261 ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) 235 262 && objDecl->get_storageClass() != DeclarationNode::Extern; 236 263 } … … 390 417 virtual void visit( ApplicationExpr *applicationExpr ) { isConstExpr = false; } 391 418 virtual void visit( UntypedExpr *untypedExpr ) { isConstExpr = false; } 392 virtual void visit( NameExpr *nameExpr ) { isConstExpr = false; } 393 virtual void visit( CastExpr *castExpr ) { isConstExpr = false; } 419 virtual void visit( NameExpr *nameExpr ) { 420 // xxx - temporary hack, because 0 and 1 really should be constexprs, even though they technically aren't in Cforall today 421 if ( nameExpr->get_name() != "0" && nameExpr->get_name() != "1" ) isConstExpr = false; 422 } 423 // virtual void visit( CastExpr *castExpr ) { isConstExpr = false; } 424 virtual void visit( AddressExpr *addressExpr ) { 425 // address of a variable or member expression is constexpr 426 Expression * arg = addressExpr->get_arg(); 427 if ( ! dynamic_cast< NameExpr * >( arg) && ! dynamic_cast< VariableExpr * >( arg ) && ! dynamic_cast< MemberExpr * >( arg ) && ! dynamic_cast< UntypedMemberExpr * >( arg ) ) isConstExpr = false; 428 } 394 429 virtual void visit( LabelAddressExpr *labAddressExpr ) { isConstExpr = false; } 395 430 virtual void visit( UntypedMemberExpr *memberExpr ) { isConstExpr = false; } 396 431 virtual void visit( MemberExpr *memberExpr ) { isConstExpr = false; } 397 432 virtual void visit( VariableExpr *variableExpr ) { isConstExpr = false; } 398 virtual void visit( ConstantExpr *constantExpr ) { /* bottom out */ }399 433 // these might be okay? 400 434 // virtual void visit( SizeofExpr *sizeofExpr ); … … 439 473 bool isDestructor( const std::string & str ) { return str == "^?{}"; } 440 474 bool isCtorDtor( const std::string & str ) { return isConstructor( str ) || isDestructor( str ); } 475 476 FunctionDecl * isCopyConstructor( Declaration * decl ) { 477 FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl ); 478 if ( ! function ) return 0; 479 if ( ! isConstructor( function->get_name() ) ) return 0; 480 FunctionType * ftype = function->get_functionType(); 481 if ( ftype->get_parameters().size() != 2 ) return 0; 482 483 Type * t1 = ftype->get_parameters().front()->get_type(); 484 Type * t2 = ftype->get_parameters().back()->get_type(); 485 PointerType * ptrType = dynamic_cast< PointerType * > ( t1 ); 486 assert( ptrType ); 487 488 if ( ResolvExpr::typesCompatible( ptrType->get_base(), t2, SymTab::Indexer() ) ) { 489 return function; 490 } else { 491 return 0; 492 } 493 } 441 494 } -
src/InitTweak/InitTweak.h
r0362d42 r1ced874 30 30 bool isCtorDtor( const std::string & ); 31 31 32 FunctionDecl * isCopyConstructor( Declaration * decl ); 33 32 34 /// transform Initializer into an argument list that can be passed to a call expression 33 35 std::list< Expression * > makeInitList( Initializer * init ); … … 38 40 /// True if the Initializer contains designations 39 41 bool isDesignated( Initializer * init ); 42 43 /// True if the ObjectDecl's Initializer nesting level is not deeper than the depth of its 44 /// type, where the depth of its type is the number of nested ArrayTypes + 1 45 bool checkInitDepth( ObjectDecl * objDecl ); 40 46 41 47 /// Non-Null if expr is a call expression whose target function is intrinsic
Note:
See TracChangeset
for help on using the changeset viewer.