Changes in src/InitTweak/FixInit.cc [ce8c12f:62423350]
- File:
-
- 1 edited
-
src/InitTweak/FixInit.cc (modified) (21 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
rce8c12f r62423350 10 10 // Created On : Wed Jan 13 16:29:30 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 17 09:13:47201713 // Update Count : 7 112 // Last Modified On : Wed Jun 21 17:35:05 2017 13 // Update Count : 74 14 14 // 15 15 … … 20 20 #include <unordered_map> 21 21 #include <unordered_set> 22 22 23 #include "InitTweak.h" 23 24 #include "GenInit.h" 24 25 #include "FixInit.h" 25 26 #include "FixGlobalInit.h" 27 #include "CodeGen/GenType.h" // for warning/error messages 28 #include "Common/PassVisitor.h" 29 #include "GenPoly/DeclMutator.h" 30 #include "GenPoly/PolyMutator.h" 26 31 #include "ResolvExpr/Resolver.h" 27 32 #include "ResolvExpr/typeops.h" 33 #include "SymTab/Autogen.h" 34 #include "SymTab/Indexer.h" 35 #include "SynTree/AddStmtVisitor.h" 36 #include "SynTree/Attribute.h" 28 37 #include "SynTree/Declaration.h" 29 #include "SynTree/Type.h"30 38 #include "SynTree/Expression.h" 31 #include "SynTree/Attribute.h"32 #include "SynTree/Statement.h"33 39 #include "SynTree/Initializer.h" 34 40 #include "SynTree/Mutator.h" 35 #include "SymTab/Indexer.h" 36 #include "SymTab/Autogen.h" 37 #include "GenPoly/PolyMutator.h" 38 #include "GenPoly/DeclMutator.h" 39 #include "SynTree/AddStmtVisitor.h" 40 #include "CodeGen/GenType.h" // for warning/error messages 41 #include "SynTree/Statement.h" 42 #include "SynTree/Type.h" 41 43 #include "Tuples/Tuples.h" 42 44 … … 54 56 typedef std::unordered_map< int, int > UnqCount; 55 57 56 class InsertImplicitCalls final : public GenPoly::PolyMutator{58 class InsertImplicitCalls : public WithTypeSubstitution { 57 59 public: 58 60 /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which … … 61 63 62 64 InsertImplicitCalls( EnvMap & envMap ) : envMap( envMap ) {} 63 typedef GenPoly::PolyMutator Parent; 64 using Parent::mutate; 65 virtual Expression * mutate( ApplicationExpr * appExpr ) override; 66 virtual Expression * mutate( StmtExpr * stmtExpr ) override; 65 66 Expression * postmutate( ApplicationExpr * appExpr ); 67 void premutate( StmtExpr * stmtExpr ); 67 68 68 69 // collects environments for relevant nodes … … 103 104 typedef AddStmtVisitor Parent; 104 105 using Parent::visit; 105 typedef std::set< ObjectDecl * > ObjectSet; 106 // use ordered data structure to maintain ordering for set_difference and for consistent error messages 107 typedef std::list< ObjectDecl * > ObjectSet; 106 108 virtual void visit( CompoundStmt *compoundStmt ) override; 107 109 virtual void visit( DeclStmt *stmt ) override; 108 110 109 111 // don't go into other functions 110 virtual void visit( FunctionDecl *decl ) override {}112 virtual void visit( __attribute__((unused)) FunctionDecl *decl ) override {} 111 113 112 114 protected: … … 115 117 116 118 // debug 117 struct printSet {118 typedef ObjDeclCollector::ObjectSet ObjectSet;119 printSet( const ObjectSet & objs ) : objs( objs ) {}119 template<typename ObjectSet> 120 struct PrintSet { 121 PrintSet( const ObjectSet & objs ) : objs( objs ) {} 120 122 const ObjectSet & objs; 121 123 }; 122 std::ostream & operator<<( std::ostream & out, const printSet & set) { 124 template<typename ObjectSet> 125 PrintSet<ObjectSet> printSet( const ObjectSet & objs ) { return PrintSet<ObjectSet>( objs ); } 126 template<typename ObjectSet> 127 std::ostream & operator<<( std::ostream & out, const PrintSet<ObjectSet> & set) { 123 128 out << "{ "; 124 129 for ( ObjectDecl * obj : set.objs ) { … … 190 195 }; 191 196 192 class FixInit final : public GenPoly::PolyMutator{197 class FixInit : public WithStmtsToAdd { 193 198 public: 194 199 /// expand each object declaration to use its constructor after it is declared. 195 200 static void fixInitializers( std::list< Declaration * > &translationUnit ); 196 201 197 typedef GenPoly::PolyMutator Parent; 198 using Parent::mutate; 199 virtual DeclarationWithType * mutate( ObjectDecl *objDecl ) override; 202 DeclarationWithType * postmutate( ObjectDecl *objDecl ); 200 203 201 204 std::list< Declaration * > staticDtorDecls; … … 300 303 namespace { 301 304 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ) { 302 InsertImplicitCallsinserter( envMap );305 PassVisitor<InsertImplicitCalls> inserter( envMap ); 303 306 mutateAll( translationUnit, inserter ); 304 307 } … … 310 313 311 314 void FixInit::fixInitializers( std::list< Declaration * > & translationUnit ) { 312 FixInitfixer;315 PassVisitor<FixInit> fixer; 313 316 314 317 // can't use mutateAll, because need to insert declarations at top-level … … 318 321 try { 319 322 *i = maybeMutate( *i, fixer ); 320 translationUnit.splice( i, fixer. staticDtorDecls );323 translationUnit.splice( i, fixer.pass.staticDtorDecls ); 321 324 } catch( SemanticError &e ) { 322 325 e.set_location( (*i)->location ); … … 350 353 } 351 354 352 Expression * InsertImplicitCalls::mutate( ApplicationExpr * appExpr ) { 353 appExpr = dynamic_cast< ApplicationExpr * >( Parent::mutate( appExpr ) ); 355 Expression * InsertImplicitCalls::postmutate( ApplicationExpr * appExpr ) { 354 356 assert( appExpr ); 355 357 … … 393 395 } 394 396 395 Expression * InsertImplicitCalls::mutate( StmtExpr * stmtExpr ) {397 void InsertImplicitCalls::premutate( StmtExpr * stmtExpr ) { 396 398 assert( env ); 397 399 envMap[stmtExpr] = env; 398 return Parent::mutate( stmtExpr );399 400 } 400 401 401 402 bool ResolveCopyCtors::skipCopyConstruct( Type * type ) { 402 return dynamic_cast< VarArgsType * >( type ) || dynamic_cast< ReferenceType * >( type ) ||GenPoly::getFunctionType( type ) || Tuples::isTtype( type );403 return dynamic_cast< VarArgsType * >( type ) || GenPoly::getFunctionType( type ) || Tuples::isTtype( type ); 403 404 } 404 405 … … 696 697 } 697 698 698 DeclarationWithType *FixInit::mutate( ObjectDecl *objDecl ) { 699 // first recursively handle pieces of ObjectDecl so that they aren't missed by other visitors when the init 700 // is removed from the ObjectDecl 701 objDecl = dynamic_cast< ObjectDecl * >( Parent::mutate( objDecl ) ); 699 DeclarationWithType *FixInit::postmutate( ObjectDecl *objDecl ) { 700 // since this removes the init field from objDecl, it must occur after children are mutated (i.e. postmutate) 702 701 if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) { 703 702 // a decision should have been made by the resolver, so ctor and init are not both non-NULL … … 729 728 // static bool __objName_uninitialized = true 730 729 BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool ); 731 SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant ( boolType->clone(), "1" ) ), noDesignators);730 SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ) ); 732 731 ObjectDecl * isUninitializedVar = new ObjectDecl( objDecl->get_mangleName() + "_uninitialized", Type::StorageClasses( Type::Static ), LinkageSpec::Cforall, 0, boolType, boolInitExpr ); 733 732 isUninitializedVar->fixUniqueId(); … … 736 735 UntypedExpr * setTrue = new UntypedExpr( new NameExpr( "?=?" ) ); 737 736 setTrue->get_args().push_back( new VariableExpr( isUninitializedVar ) ); 738 setTrue->get_args().push_back( new ConstantExpr( Constant ( boolType->clone(), "0") ) );737 setTrue->get_args().push_back( new ConstantExpr( Constant::from_int( 0 ) ) ); 739 738 740 739 // generate body of if … … 750 749 751 750 Statement * dtor = ctorInit->get_dtor(); 752 objDecl->set_init( NULL);753 ctorInit->set_ctor( NULL);751 objDecl->set_init( nullptr ); 752 ctorInit->set_ctor( nullptr ); 754 753 ctorInit->set_dtor( nullptr ); 755 754 if ( dtor ) { … … 804 803 } else { 805 804 stmtsToAddAfter.push_back( ctor ); 806 objDecl->set_init( NULL);807 ctorInit->set_ctor( NULL);805 objDecl->set_init( nullptr ); 806 ctorInit->set_ctor( nullptr ); 808 807 } 809 808 } // if 810 809 } else if ( Initializer * init = ctorInit->get_init() ) { 811 810 objDecl->set_init( init ); 812 ctorInit->set_init( NULL);811 ctorInit->set_init( nullptr ); 813 812 } else { 814 813 // no constructor and no initializer, which is okay 815 objDecl->set_init( NULL);814 objDecl->set_init( nullptr ); 816 815 } // if 817 816 delete ctorInit; … … 821 820 822 821 void ObjDeclCollector::visit( CompoundStmt * compoundStmt ) { 823 std::set< ObjectDecl * >prevVars = curVars;822 ObjectSet prevVars = curVars; 824 823 Parent::visit( compoundStmt ); 825 824 curVars = prevVars; … … 829 828 // keep track of all variables currently in scope 830 829 if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) { 831 curVars. insert( objDecl );830 curVars.push_back( objDecl ); 832 831 } // if 833 832 Parent::visit( stmt ); … … 896 895 Parent::visit( compoundStmt ); 897 896 898 // add destructors for the current scope that we're exiting 897 // add destructors for the current scope that we're exiting, unless the last statement is a return, which 898 // causes unreachable code warnings 899 899 std::list< Statement * > & statements = compoundStmt->get_kids(); 900 insertDtors( reverseDeclOrder.front().begin(), reverseDeclOrder.front().end(), back_inserter( statements ) ); 900 if ( ! statements.empty() && ! dynamic_cast< ReturnStmt * >( statements.back() ) ) { 901 insertDtors( reverseDeclOrder.front().begin(), reverseDeclOrder.front().end(), back_inserter( statements ) ); 902 } 901 903 reverseDeclOrder.pop_front(); 902 904 } 903 905 904 void InsertDtors::visit( ReturnStmt * returnStmt ) {906 void InsertDtors::visit( __attribute((unused)) ReturnStmt * returnStmt ) { 905 907 // return exits all scopes, so dump destructors for all scopes 906 908 for ( OrderedDecls & od : reverseDeclOrder ) { … … 941 943 ) 942 944 if ( ! diff.empty() ) { 945 // create an auxilliary set for fast lookup -- can't make diff a set, because diff ordering should be consistent for error messages. 946 std::unordered_set<ObjectDecl *> needsDestructor( diff.begin(), diff.end() ); 947 943 948 // go through decl ordered list of objectdecl. for each element that occurs in diff, output destructor 944 949 OrderedDecls ordered; 945 950 for ( OrderedDecls & rdo : reverseDeclOrder ) { 946 951 // add elements from reverseDeclOrder into ordered if they occur in diff - it is key that this happens in reverse declaration order. 947 copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return diff.count( objDecl ); } );952 copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } ); 948 953 } // for 949 954 insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd ) );
Note:
See TracChangeset
for help on using the changeset viewer.