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