Changes in / [1abc5ab:a12d5aa]
- Location:
- src
- Files:
-
- 4 added
- 35 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r1abc5ab ra12d5aa 288 288 } 289 289 290 void CodeGenerator:: printDesignators( std::list< Expression * > & designators) {291 typedef std::list< Expression * > DesignatorList;290 void CodeGenerator::visit( Designation * designation ) { 291 std::list< Expression * > designators = designation->get_designators(); 292 292 if ( designators.size() == 0 ) return; 293 for ( DesignatorList::iterator iter = designators.begin(); iter != designators.end(); ++iter) {294 if ( dynamic_cast< NameExpr * >( *iter) ) {295 // if expression is a name, then initializing aggregate member293 for ( Expression * des : designators ) { 294 if ( dynamic_cast< NameExpr * >( des ) || dynamic_cast< VariableExpr * >( des ) ) { 295 // if expression is a NameExpr or VariableExpr, then initializing aggregate member 296 296 output << "."; 297 (*iter)->accept( *this );297 des->accept( *this ); 298 298 } else { 299 // if not a simple name, it has to be a constant expression, i.e. an array designator299 // otherwise, it has to be a ConstantExpr or CastExpr, initializing array eleemnt 300 300 output << "["; 301 (*iter)->accept( *this );301 des->accept( *this ); 302 302 output << "]"; 303 303 } // if … … 307 307 308 308 void CodeGenerator::visit( SingleInit * init ) { 309 printDesignators( init->get_designators() );310 309 init->get_value()->accept( *this ); 311 310 } 312 311 313 312 void CodeGenerator::visit( ListInit * init ) { 314 printDesignators( init->get_designators() ); 313 auto initBegin = init->begin(); 314 auto initEnd = init->end(); 315 auto desigBegin = init->get_designations().begin(); 316 auto desigEnd = init->get_designations().end(); 317 315 318 output << "{ "; 316 genCommaList( init->begin(), init->end() ); 319 for ( ; initBegin != initEnd && desigBegin != desigEnd; ) { 320 (*desigBegin)->accept( *this ); 321 (*initBegin)->accept( *this ); 322 ++initBegin, ++desigBegin; 323 if ( initBegin != initEnd ) { 324 output << ", "; 325 } 326 } 317 327 output << " }"; 328 assertf( initBegin == initEnd && desigBegin == desigEnd, "Initializers and designators not the same length. %s", toString( init ).c_str() ); 318 329 } 319 330 … … 716 727 717 728 void CodeGenerator::visit( TypeExpr * typeExpr ) { 718 assertf( ! genC, "TypeExpr should not reach code generation." ); 719 output<< genType( typeExpr->get_type(), "", pretty, genC ); 729 // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl; 730 // assertf( ! genC, "TypeExpr should not reach code generation." ); 731 if ( ! genC ) { 732 output<< genType( typeExpr->get_type(), "", pretty, genC ); 733 } 720 734 } 721 735 -
src/CodeGen/CodeGenerator.h
r1abc5ab ra12d5aa 47 47 48 48 //*** Initializer 49 virtual void visit( Designation * ); 49 50 virtual void visit( SingleInit * ); 50 51 virtual void visit( ListInit * ); … … 137 138 bool lineMarks = false; 138 139 139 void printDesignators( std::list< Expression * > & );140 140 void handleStorageClass( DeclarationWithType *decl ); 141 141 void handleAggregate( AggregateDecl *aggDecl, const std::string & kind ); -
src/Common/PassVisitor.h
r1abc5ab ra12d5aa 257 257 258 258 void set_visit_children( bool& ref ) { bool_ref * ptr = visit_children_impl(pass, 0); if(ptr) ptr->set( ref ); } 259 260 guard_value_impl init_guard() {261 guard_value_impl guard;262 auto at_cleanup = at_cleanup_impl(pass, 0);263 if( at_cleanup ) {264 *at_cleanup = [&guard]( cleanup_func_t && func, void* val ) {265 guard.push( std::move( func ), val );266 };267 }268 return guard;269 }270 259 }; 271 260 -
src/Common/PassVisitor.impl.h
r1abc5ab ra12d5aa 3 3 #define VISIT_START( node ) \ 4 4 __attribute__((unused)) \ 5 const auto & guard = init_guard();\5 guard_value_impl guard( at_cleanup_impl(pass, 0) ); \ 6 6 bool visit_children = true; \ 7 7 set_visit_children( visit_children ); \ … … 15 15 #define MUTATE_START( node ) \ 16 16 __attribute__((unused)) \ 17 const auto & guard = init_guard();\17 guard_value_impl guard( at_cleanup_impl(pass, 0) ); \ 18 18 bool visit_children = true; \ 19 19 set_visit_children( visit_children ); \ -
src/Common/PassVisitor.proto.h
r1abc5ab ra12d5aa 5 5 6 6 typedef std::function<void( void * )> cleanup_func_t; 7 typedef std::function< void( cleanup_func_t, void * ) > at_cleanup_t; 7 8 8 9 class guard_value_impl { 9 10 public: 10 guard_value_impl() = default; 11 guard_value_impl( at_cleanup_t * at_cleanup ) { 12 if( at_cleanup ) { 13 *at_cleanup = [this]( cleanup_func_t && func, void* val ) { 14 push( std::move( func ), val ); 15 }; 16 } 17 } 11 18 12 19 ~guard_value_impl() { … … 33 40 }; 34 41 35 typedef std::function< void( cleanup_func_t, void * ) > at_cleanup_t;36 42 37 43 class bool_ref { -
src/Common/utility.h
r1abc5ab ra12d5aa 305 305 // for ( val : group_iterate( container1, container2, ... ) ) {} 306 306 // syntax to have a for each that iterates multiple containers of the same length 307 // TODO: update to use variadic arguments 307 // TODO: update to use variadic arguments, perfect forwarding 308 308 309 309 template< typename T1, typename T2 > -
src/InitTweak/FixInit.cc
r1abc5ab ra12d5aa 104 104 typedef AddStmtVisitor Parent; 105 105 using Parent::visit; 106 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; 107 108 virtual void visit( CompoundStmt *compoundStmt ) override; 108 109 virtual void visit( DeclStmt *stmt ) override; … … 116 117 117 118 // debug 118 struct printSet {119 typedef ObjDeclCollector::ObjectSet ObjectSet;120 printSet( const ObjectSet & objs ) : objs( objs ) {}119 template<typename ObjectSet> 120 struct PrintSet { 121 PrintSet( const ObjectSet & objs ) : objs( objs ) {} 121 122 const ObjectSet & objs; 122 123 }; 123 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) { 124 128 out << "{ "; 125 129 for ( ObjectDecl * obj : set.objs ) { … … 724 728 // static bool __objName_uninitialized = true 725 729 BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool ); 726 SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ) , noDesignators);730 SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ) ); 727 731 ObjectDecl * isUninitializedVar = new ObjectDecl( objDecl->get_mangleName() + "_uninitialized", Type::StorageClasses( Type::Static ), LinkageSpec::Cforall, 0, boolType, boolInitExpr ); 728 732 isUninitializedVar->fixUniqueId(); … … 745 749 746 750 Statement * dtor = ctorInit->get_dtor(); 747 objDecl->set_init( NULL);748 ctorInit->set_ctor( NULL);751 objDecl->set_init( nullptr ); 752 ctorInit->set_ctor( nullptr ); 749 753 ctorInit->set_dtor( nullptr ); 750 754 if ( dtor ) { … … 799 803 } else { 800 804 stmtsToAddAfter.push_back( ctor ); 801 objDecl->set_init( NULL);802 ctorInit->set_ctor( NULL);805 objDecl->set_init( nullptr ); 806 ctorInit->set_ctor( nullptr ); 803 807 } 804 808 } // if 805 809 } else if ( Initializer * init = ctorInit->get_init() ) { 806 810 objDecl->set_init( init ); 807 ctorInit->set_init( NULL);811 ctorInit->set_init( nullptr ); 808 812 } else { 809 813 // no constructor and no initializer, which is okay 810 objDecl->set_init( NULL);814 objDecl->set_init( nullptr ); 811 815 } // if 812 816 delete ctorInit; … … 816 820 817 821 void ObjDeclCollector::visit( CompoundStmt * compoundStmt ) { 818 std::set< ObjectDecl * >prevVars = curVars;822 ObjectSet prevVars = curVars; 819 823 Parent::visit( compoundStmt ); 820 824 curVars = prevVars; … … 824 828 // keep track of all variables currently in scope 825 829 if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) { 826 curVars. insert( objDecl );830 curVars.push_back( objDecl ); 827 831 } // if 828 832 Parent::visit( stmt ); … … 939 943 ) 940 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 941 948 // go through decl ordered list of objectdecl. for each element that occurs in diff, output destructor 942 949 OrderedDecls ordered; 943 950 for ( OrderedDecls & rdo : reverseDeclOrder ) { 944 951 // add elements from reverseDeclOrder into ordered if they occur in diff - it is key that this happens in reverse declaration order. 945 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 ); } ); 946 953 } // for 947 954 insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd ) ); -
src/InitTweak/InitTweak.cc
r1abc5ab ra12d5aa 14 14 public: 15 15 bool hasDesignations = false; 16 template<typename Init> 17 void handleInit( Init * init ) { 18 if ( ! init->get_designators().empty() ) hasDesignations = true; 19 else Visitor::visit( init ); 20 } 21 virtual void visit( SingleInit * singleInit ) { handleInit( singleInit); } 22 virtual void visit( ListInit * listInit ) { handleInit( listInit); } 16 virtual void visit( Designation * des ) { 17 if ( ! des->get_designators().empty() ) hasDesignations = true; 18 else Visitor::visit( des ); 19 } 23 20 }; 24 21 -
src/MakeLibCfa.cc
r1abc5ab ra12d5aa 92 92 assert( ! objDecl->get_init() ); 93 93 std::list< Expression* > noDesignators; 94 objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators,false ) ); // cannot be constructed94 objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), false ) ); // cannot be constructed 95 95 newDecls.push_back( objDecl ); 96 96 } -
src/Makefile.in
r1abc5ab ra12d5aa 162 162 ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) \ 163 163 ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \ 164 ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) \ 164 165 SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \ 165 166 SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \ … … 416 417 ResolvExpr/RenameVars.cc ResolvExpr/FindOpenVars.cc \ 417 418 ResolvExpr/PolyCost.cc ResolvExpr/Occurs.cc \ 418 ResolvExpr/TypeEnvironment.cc SymTab/Indexer.cc \419 SymTab/ Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \420 SymTab/ ImplementationType.cc SymTab/TypeEquality.cc \421 SymTab/ Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \422 SynTree/ BasicType.cc SynTree/PointerType.cc \423 SynTree/ ArrayType.cc SynTree/FunctionType.cc \424 SynTree/ ReferenceToType.cc SynTree/TupleType.cc \425 SynTree/T ypeofType.cc SynTree/AttrType.cc \419 ResolvExpr/TypeEnvironment.cc ResolvExpr/CurrentObject.cc \ 420 SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \ 421 SymTab/FixFunction.cc SymTab/ImplementationType.cc \ 422 SymTab/TypeEquality.cc SymTab/Autogen.cc SynTree/Type.cc \ 423 SynTree/VoidType.cc SynTree/BasicType.cc \ 424 SynTree/PointerType.cc SynTree/ArrayType.cc \ 425 SynTree/FunctionType.cc SynTree/ReferenceToType.cc \ 426 SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \ 426 427 SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \ 427 428 SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \ … … 726 727 ResolvExpr/$(am__dirstamp) \ 727 728 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 729 ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT): \ 730 ResolvExpr/$(am__dirstamp) \ 731 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 728 732 SymTab/$(am__dirstamp): 729 733 @$(MKDIR_P) SymTab … … 896 900 -rm -f ResolvExpr/driver_cfa_cpp-CommonType.$(OBJEXT) 897 901 -rm -f ResolvExpr/driver_cfa_cpp-ConversionCost.$(OBJEXT) 902 -rm -f ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) 898 903 -rm -f ResolvExpr/driver_cfa_cpp-FindOpenVars.$(OBJEXT) 899 904 -rm -f ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) … … 1009 1014 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Po@am__quote@ 1010 1015 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po@am__quote@ 1016 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po@am__quote@ 1011 1017 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po@am__quote@ 1012 1018 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po@am__quote@ … … 1964 1970 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj `if test -f 'ResolvExpr/TypeEnvironment.cc'; then $(CYGPATH_W) 'ResolvExpr/TypeEnvironment.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/TypeEnvironment.cc'; fi` 1965 1971 1972 ResolvExpr/driver_cfa_cpp-CurrentObject.o: ResolvExpr/CurrentObject.cc 1973 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc 1974 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po 1975 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.o' libtool=no @AMDEPBACKSLASH@ 1976 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1977 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc 1978 1979 ResolvExpr/driver_cfa_cpp-CurrentObject.obj: ResolvExpr/CurrentObject.cc 1980 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi` 1981 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po 1982 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.obj' libtool=no @AMDEPBACKSLASH@ 1983 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1984 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi` 1985 1966 1986 SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc 1967 1987 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Indexer.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo -c -o SymTab/driver_cfa_cpp-Indexer.o `test -f 'SymTab/Indexer.cc' || echo '$(srcdir)/'`SymTab/Indexer.cc -
src/Parser/InitializerNode.cc
r1abc5ab ra12d5aa 74 74 75 75 InitializerNode *moreInit; 76 if ( get_next() != 0 && ((moreInit = dynamic_cast< InitializerNode * >( get_next() ) ) != 0) )76 if ( (moreInit = dynamic_cast< InitializerNode * >( get_next() ) ) ) { 77 77 moreInit->printOneLine( os ); 78 } 78 79 } 79 80 80 81 Initializer *InitializerNode::build() const { 81 82 if ( aggregate ) { 83 // steal designators from children 84 std::list< Designation * > designlist; 85 InitializerNode * child = next_init(); 86 for ( ; child != nullptr; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) { 87 std::list< Expression * > desList; 88 buildList< Expression, ExpressionNode >( child->designator, desList ); 89 designlist.push_back( new Designation( desList ) ); 90 } // for 82 91 std::list< Initializer * > initlist; 83 92 buildList< Initializer, InitializerNode >( next_init(), initlist ); 84 85 std::list< Expression * > designlist;86 87 if ( designator != 0 ) {88 buildList< Expression, ExpressionNode >( designator, designlist );89 } // if90 91 93 return new ListInit( initlist, designlist, maybeConstructed ); 92 94 } else { 93 std::list< Expression * > designators; 94 95 if ( designator != 0 ) 96 buildList< Expression, ExpressionNode >( designator, designators ); 97 98 if ( get_expression() != 0) 99 return new SingleInit( maybeBuild< Expression >( get_expression() ), designators, maybeConstructed ); 95 if ( get_expression() != 0) { 96 return new SingleInit( maybeBuild< Expression >( get_expression() ), maybeConstructed ); 97 } 100 98 } // if 101 102 99 return 0; 103 100 } -
src/Parser/TypeData.cc
r1abc5ab ra12d5aa 760 760 if ( cur->has_enumeratorValue() ) { 761 761 ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members); 762 member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) , list< Expression * >()) );762 member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) ); 763 763 } // if 764 764 } // for … … 777 777 TupleType * buildTuple( const TypeData * td ) { 778 778 assert( td->kind == TypeData::Tuple ); 779 TupleType * ret = new TupleType( buildQualifiers( td ) ); 780 buildTypeList( td->tuple, ret->get_types() ); 779 std::list< Type * > types; 780 buildTypeList( td->tuple, types ); 781 TupleType * ret = new TupleType( buildQualifiers( td ), types ); 781 782 buildForall( td->forall, ret->get_forall() ); 782 783 return ret; -
src/ResolvExpr/AlternativeFinder.cc
r1abc5ab ra12d5aa 604 604 // ) 605 605 SymTab::Indexer decls( indexer ); 606 PRINT(607 std::cerr << "============= original indexer" << std::endl;608 indexer.print( std::cerr );609 std::cerr << "============= new indexer" << std::endl;610 decls.print( std::cerr );611 )606 // PRINT( 607 // std::cerr << "============= original indexer" << std::endl; 608 // indexer.print( std::cerr ); 609 // std::cerr << "============= new indexer" << std::endl; 610 // decls.print( std::cerr ); 611 // ) 612 612 addToIndexer( have, decls ); 613 613 AssertionSet newNeed; … … 809 809 } 810 810 811 Expression * restructureCast( Expression * argExpr, Type * toType ) { 812 if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() ) { 813 // Argument expression is a tuple and the target type is not void. Cast each member of the tuple 814 // to its corresponding target type, producing the tuple of those cast expressions. If there are 815 // more components of the tuple than components in the target type, then excess components do not 816 // come out in the result expression (but UniqueExprs ensure that side effects will still be done). 817 if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) { 818 // expressions which may contain side effects require a single unique instance of the expression. 819 argExpr = new UniqueExpr( argExpr ); 820 } 821 std::list< Expression * > componentExprs; 822 for ( unsigned int i = 0; i < toType->size(); i++ ) { 823 // cast each component 824 TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i ); 825 componentExprs.push_back( restructureCast( idx, toType->getComponent( i ) ) ); 826 } 827 delete argExpr; 828 assert( componentExprs.size() > 0 ); 829 // produce the tuple of casts 830 return new TupleExpr( componentExprs ); 831 } else { 832 // handle normally 833 return new CastExpr( argExpr, toType->clone() ); 834 } 835 } 836 811 837 void AlternativeFinder::visit( CastExpr *castExpr ) { 812 838 Type *& toType = castExpr->get_result(); … … 840 866 thisCost += Cost( 0, 0, discardedValues ); 841 867 842 Expression * argExpr = i->expr->clone(); 843 if ( argExpr->get_result()->size() > 1 && ! castExpr->get_result()->isVoid() ) { 844 // Argument expression is a tuple and the target type is not void. Cast each member of the tuple 845 // to its corresponding target type, producing the tuple of those cast expressions. If there are 846 // more components of the tuple than components in the target type, then excess components do not 847 // come out in the result expression (but UniqueExprs ensure that side effects will still be done). 848 if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) { 849 // expressions which may contain side effects require a single unique instance of the expression. 850 argExpr = new UniqueExpr( argExpr ); 851 } 852 std::list< Expression * > componentExprs; 853 for ( unsigned int i = 0; i < castExpr->get_result()->size(); i++ ) { 854 // cast each component 855 TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i ); 856 componentExprs.push_back( new CastExpr( idx, castExpr->get_result()->getComponent( i )->clone() ) ); 857 } 858 delete argExpr; 859 assert( componentExprs.size() > 0 ); 860 // produce the tuple of casts 861 candidates.push_back( Alternative( new TupleExpr( componentExprs ), i->env, i->cost, thisCost ) ); 862 } else { 863 // handle normally 864 candidates.push_back( Alternative( new CastExpr( argExpr->clone(), toType->clone() ), i->env, i->cost, thisCost ) ); 865 } 868 candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) ); 866 869 } // if 867 870 } // for … … 1182 1185 } 1183 1186 1187 void AlternativeFinder::visit( UntypedInitExpr *initExpr ) { 1188 // handle each option like a cast 1189 AltList candidates; 1190 PRINT( std::cerr << "untyped init expr: " << initExpr << std::endl; ) 1191 // O(N^2) checks of d-types with e-types 1192 for ( InitAlternative & initAlt : initExpr->get_initAlts() ) { 1193 Type * toType = resolveTypeof( initAlt.type, indexer ); 1194 SymTab::validateType( toType, &indexer ); 1195 adjustExprType( toType, env, indexer ); 1196 // Ideally the call to findWithAdjustment could be moved out of the loop, but unfortunately it currently has to occur inside or else 1197 // polymorphic return types are not properly bound to the initialization type, since return type variables are only open for the duration of resolving 1198 // the UntypedExpr. This is only actually an issue in initialization contexts that allow more than one possible initialization type, but it is still suboptimal. 1199 AlternativeFinder finder( indexer, env ); 1200 finder.targetType = toType; 1201 finder.findWithAdjustment( initExpr->get_expr() ); 1202 for ( Alternative & alt : finder.get_alternatives() ) { 1203 TypeEnvironment newEnv( alt.env ); 1204 AssertionSet needAssertions, haveAssertions; 1205 OpenVarSet openVars; // find things in env that don't have a "representative type" and claim those are open vars? 1206 PRINT( std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; ) 1207 // It's possible that a cast can throw away some values in a multiply-valued expression. (An example is a 1208 // cast-to-void, which casts from one value to zero.) Figure out the prefix of the subexpression results 1209 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 1210 // to. 1211 int discardedValues = alt.expr->get_result()->size() - toType->size(); 1212 if ( discardedValues < 0 ) continue; 1213 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not 1214 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 1215 // unification run for side-effects 1216 unify( toType, alt.expr->get_result(), newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type?? 1217 1218 Cost thisCost = castCost( alt.expr->get_result(), toType, indexer, newEnv ); 1219 if ( thisCost != Cost::infinity ) { 1220 // count one safe conversion for each value that is thrown away 1221 thisCost += Cost( 0, 0, discardedValues ); 1222 candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) ); 1223 } 1224 } 1225 } 1226 1227 // findMinCost selects the alternatives with the lowest "cost" members, but has the side effect of copying the 1228 // cvtCost member to the cost member (since the old cost is now irrelevant). Thus, calling findMinCost twice 1229 // selects first based on argument cost, then on conversion cost. 1230 AltList minArgCost; 1231 findMinCost( candidates.begin(), candidates.end(), std::back_inserter( minArgCost ) ); 1232 findMinCost( minArgCost.begin(), minArgCost.end(), std::back_inserter( alternatives ) ); 1233 } 1184 1234 } // namespace ResolvExpr 1185 1235 -
src/ResolvExpr/AlternativeFinder.h
r1abc5ab ra12d5aa 73 73 virtual void visit( UniqueExpr *unqExpr ); 74 74 virtual void visit( StmtExpr *stmtExpr ); 75 virtual void visit( UntypedInitExpr *initExpr ); 75 76 /// Runs a new alternative finder on each element in [begin, end) 76 77 /// and writes each alternative finder to out. -
src/ResolvExpr/Resolver.cc
r1abc5ab ra12d5aa 14 14 // 15 15 16 #include <iostream> 17 18 #include "Alternative.h" 19 #include "AlternativeFinder.h" 20 #include "CurrentObject.h" 21 #include "RenameVars.h" 16 22 #include "Resolver.h" 17 #include "AlternativeFinder.h"18 #include "Alternative.h"19 #include "RenameVars.h"20 23 #include "ResolveTypeof.h" 21 24 #include "typeops.h" 25 26 #include "SynTree/Expression.h" 27 #include "SynTree/Initializer.h" 22 28 #include "SynTree/Statement.h" 23 29 #include "SynTree/Type.h" 24 #include "SynTree/Expression.h" 25 #include "Sy nTree/Initializer.h"30 31 #include "SymTab/Autogen.h" 26 32 #include "SymTab/Indexer.h" 27 #include "SymTab/Autogen.h" 33 28 34 #include "Common/utility.h" 35 29 36 #include "InitTweak/InitTweak.h" 30 37 31 #include <iostream>32 38 using namespace std; 33 39 … … 39 45 if ( const Resolver * res = dynamic_cast< const Resolver * >( &other ) ) { 40 46 functionReturn = res->functionReturn; 41 initContext = res->initContext;47 currentObject = res->currentObject; 42 48 inEnumDecl = res->inEnumDecl; 43 49 } … … 79 85 80 86 Type * functionReturn = nullptr; 81 Type *initContext = nullptr;87 CurrentObject currentObject = nullptr; 82 88 bool inEnumDecl = false; 83 89 }; … … 186 192 // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting 187 193 // the RHS. 188 Type *temp = initContext;189 initContext = new_type;190 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext) ) {194 ValueGuard<CurrentObject> temp( currentObject ); 195 currentObject = CurrentObject( objectDecl->get_type() ); 196 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) { 191 197 // enumerator initializers should not use the enum type to initialize, since 192 198 // the enum type is still incomplete at this point. Use signed int instead. 193 initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt);199 currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 194 200 } 195 201 Parent::visit( objectDecl ); 196 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext) ) {202 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) { 197 203 // delete newly created signed int type 198 delete initContext; 199 } 200 initContext = temp; 204 // delete currentObject.getType(); 205 } 201 206 } 202 207 … … 315 320 316 321 void Resolver::visit( SwitchStmt *switchStmt ) { 317 ValueGuard< Type * > oldInitContext( initContext );322 ValueGuard< CurrentObject > oldCurrentObject( currentObject ); 318 323 Expression *newExpr; 319 324 newExpr = findIntegralExpression( switchStmt->get_condition(), *this ); … … 321 326 switchStmt->set_condition( newExpr ); 322 327 323 initContext = newExpr->get_result();328 currentObject = CurrentObject( newExpr->get_result() ); 324 329 Parent::visit( switchStmt ); 325 330 } … … 327 332 void Resolver::visit( CaseStmt *caseStmt ) { 328 333 if ( caseStmt->get_condition() ) { 329 assert( initContext ); 330 CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initContext->clone() ); 334 std::list< InitAlternative > initAlts = currentObject.getOptions(); 335 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." ); 336 CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() ); 331 337 Expression * newExpr = findSingleExpression( castExpr, *this ); 332 338 castExpr = safe_dynamic_cast< CastExpr * >( newExpr ); … … 370 376 371 377 void Resolver::visit( SingleInit *singleInit ) { 372 if ( singleInit->get_value() ) { 373 // // find all the d's 374 // std::list<Expression *> &designators = singleInit->get_designators(); 375 // std::list<Type *> types1{ initContext }, types2; 376 // for ( Expression * expr: designators ) { 377 // cerr << expr << endl; 378 // if ( NameExpr * nexpr = dynamic_cast<NameExpr *>( expr ) ) { 379 // for ( Type * type: types1 ) { 380 // cerr << type << endl; 381 // ReferenceToType * fred = dynamic_cast<ReferenceToType *>(type); 382 // std::list<Declaration *> members; 383 // if ( fred ) { 384 // fred->lookup( nexpr->get_name(), members ); // concatenate identical field name 385 // for ( Declaration * mem: members ) { 386 // if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>(mem) ) { 387 // types2.push_back( dwt->get_type() ); 388 // } // if 389 // } // for 390 // } // if 391 // } // for 392 // types1 = types2; 393 // types2.clear(); 394 // } // if 395 // } // for 396 // // for ( Type * type: types1 ) { 397 // // cerr << type << endl; 398 // // } // for 399 400 // // O(N^2) checks of d-types with f-types 401 // // find the minimum cost 402 CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() ); 403 Expression *newExpr = findSingleExpression( castExpr, *this ); 404 delete castExpr; 405 singleInit->set_value( newExpr ); 406 407 // check if initializing type is char[] 408 if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) { 409 if ( isCharType( at->get_base() ) ) { 410 // check if the resolved type is char * 411 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) { 412 if ( isCharType( pt->get_base() ) ) { 413 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 414 CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ); 415 singleInit->set_value( ce->get_arg() ); 416 ce->set_arg( NULL ); 417 delete ce; 418 } 378 // resolve initialization using the possibilities as determined by the currentObject cursor 379 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() ); 380 Expression * newExpr = findSingleExpression( untyped, *this ); 381 InitExpr * initExpr = safe_dynamic_cast< InitExpr * >( newExpr ); 382 383 // move cursor to the object that is actually initialized 384 currentObject.setNext( initExpr->get_designation() ); 385 386 // discard InitExpr wrapper and retain relevant pieces 387 newExpr = initExpr->get_expr(); 388 singleInit->get_value()->set_env( initExpr->get_env() ); 389 initExpr->set_expr( nullptr ); 390 initExpr->set_env( nullptr ); 391 delete initExpr; 392 393 // get the actual object's type (may not exactly match what comes back from the resolver due to conversions) 394 Type * initContext = currentObject.getCurrentType(); 395 396 // check if actual object's type is char[] 397 if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) { 398 if ( isCharType( at->get_base() ) ) { 399 // check if the resolved type is char * 400 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) { 401 if ( isCharType( pt->get_base() ) ) { 402 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 403 CastExpr *ce = safe_dynamic_cast< CastExpr * >( newExpr ); 404 newExpr = ce->get_arg(); 405 ce->set_arg( nullptr ); 406 delete ce; 419 407 } 420 408 } 421 409 } 422 } // if 423 } 424 425 template< typename AggrInst > 426 TypeSubstitution makeGenericSubstitutuion( AggrInst * inst ) { 427 assert( inst ); 428 assert( inst->get_baseParameters() ); 429 std::list< TypeDecl * > baseParams = *inst->get_baseParameters(); 430 std::list< Expression * > typeSubs = inst->get_parameters(); 431 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() ); 432 return subs; 433 } 434 435 ReferenceToType * isStructOrUnion( Type * type ) { 436 if ( StructInstType * sit = dynamic_cast< StructInstType * >( type ) ) { 437 return sit; 438 } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( type ) ) { 439 return uit; 440 } 441 return nullptr; 442 } 443 444 void Resolver::resolveSingleAggrInit( Declaration * dcl, InitIterator & init, InitIterator & initEnd, TypeSubstitution sub ) { 445 DeclarationWithType * dt = dynamic_cast< DeclarationWithType * >( dcl ); 446 assert( dt ); 447 // need to substitute for generic types, so that casts are to concrete types 448 initContext = dt->get_type()->clone(); 449 sub.apply( initContext ); 450 451 try { 452 if ( init == initEnd ) return; // stop when there are no more initializers 453 (*init)->accept( *this ); 454 ++init; // made it past an initializer 455 } catch( SemanticError & ) { 456 // need to delve deeper, if you can 457 if ( ReferenceToType * type = isStructOrUnion( initContext ) ) { 458 resolveAggrInit( type, init, initEnd ); 459 } else { 460 // member is not an aggregate type, so can't go any deeper 461 462 // might need to rethink what is being thrown 463 throw; 464 } // if 465 } 466 } 467 468 void Resolver::resolveAggrInit( ReferenceToType * inst, InitIterator & init, InitIterator & initEnd ) { 469 if ( StructInstType * sit = dynamic_cast< StructInstType * >( inst ) ) { 470 TypeSubstitution sub = makeGenericSubstitutuion( sit ); 471 StructDecl * st = sit->get_baseStruct(); 472 if(st->get_members().empty()) return; 473 // want to resolve each initializer to the members of the struct, 474 // but if there are more initializers than members we should stop 475 list< Declaration * >::iterator it = st->get_members().begin(); 476 for ( ; it != st->get_members().end(); ++it) { 477 resolveSingleAggrInit( *it, init, initEnd, sub ); 478 } 479 } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( inst ) ) { 480 TypeSubstitution sub = makeGenericSubstitutuion( uit ); 481 UnionDecl * un = uit->get_baseUnion(); 482 if(un->get_members().empty()) return; 483 // only resolve to the first member of a union 484 resolveSingleAggrInit( *un->get_members().begin(), init, initEnd, sub ); 485 } // if 410 } 411 412 // set initializer expr to resolved express 413 singleInit->set_value( newExpr ); 414 415 // move cursor to next object in preparation for next initializer 416 currentObject.increment(); 486 417 } 487 418 488 419 void Resolver::visit( ListInit * listInit ) { 489 InitIterator iter = listInit->begin(); 490 InitIterator end = listInit->end(); 491 492 if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) { 493 // resolve each member to the base type of the array 494 for ( ; iter != end; ++iter ) { 495 initContext = at->get_base(); 496 (*iter)->accept( *this ); 497 } // for 498 } else if ( TupleType * tt = dynamic_cast< TupleType * > ( initContext ) ) { 499 for ( Type * t : *tt ) { 500 if ( iter == end ) break; 501 initContext = t; 502 (*iter++)->accept( *this ); 503 } 504 } else if ( ReferenceToType * type = isStructOrUnion( initContext ) ) { 505 resolveAggrInit( type, iter, end ); 506 } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) { 507 Type * base = tt->get_baseType()->get_base(); 508 if ( base ) { 509 // know the implementation type, so try using that as the initContext 510 initContext = base; 511 visit( listInit ); 512 } else { 513 // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context 514 Parent::visit( listInit ); 515 } 516 } else { 517 assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext ) 518 || dynamic_cast< ZeroType * >( initContext ) || dynamic_cast< OneType * >( initContext ) || dynamic_cast < EnumInstType * > ( initContext ) ); 519 // basic types are handled here 520 Parent::visit( listInit ); 521 } 522 523 #if 0 524 if ( ArrayType *at = dynamic_cast<ArrayType*>(initContext) ) { 525 std::list<Initializer *>::iterator iter( listInit->begin_initializers() ); 526 for ( ; iter != listInit->end_initializers(); ++iter ) { 527 initContext = at->get_base(); 528 (*iter)->accept( *this ); 529 } // for 530 } else if ( StructInstType *st = dynamic_cast<StructInstType*>(initContext) ) { 531 StructDecl *baseStruct = st->get_baseStruct(); 532 std::list<Declaration *>::iterator iter1( baseStruct->get_members().begin() ); 533 std::list<Initializer *>::iterator iter2( listInit->begin_initializers() ); 534 for ( ; iter1 != baseStruct->get_members().end() && iter2 != listInit->end_initializers(); ++iter2 ) { 535 if ( (*iter2)->get_designators().empty() ) { 536 DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *iter1 ); 537 initContext = dt->get_type(); 538 (*iter2)->accept( *this ); 539 ++iter1; 540 } else { 541 StructDecl *st = baseStruct; 542 iter1 = st->get_members().begin(); 543 std::list<Expression *>::iterator iter3( (*iter2)->get_designators().begin() ); 544 for ( ; iter3 != (*iter2)->get_designators().end(); ++iter3 ) { 545 NameExpr *key = dynamic_cast<NameExpr *>( *iter3 ); 546 assert( key ); 547 for ( ; iter1 != st->get_members().end(); ++iter1 ) { 548 if ( key->get_name() == (*iter1)->get_name() ) { 549 (*iter1)->print( cout ); 550 cout << key->get_name() << endl; 551 ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 ); 552 assert( fred ); 553 StructInstType *mary = dynamic_cast<StructInstType*>( fred->get_type() ); 554 assert( mary ); 555 st = mary->get_baseStruct(); 556 iter1 = st->get_members().begin(); 557 break; 558 } // if 559 } // for 560 } // for 561 ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 ); 562 assert( fred ); 563 initContext = fred->get_type(); 564 (*listInit->begin_initializers())->accept( *this ); 565 } // if 566 } // for 567 } else if ( UnionInstType *st = dynamic_cast<UnionInstType*>(initContext) ) { 568 DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *st->get_baseUnion()->get_members().begin() ); 569 initContext = dt->get_type(); 570 (*listInit->begin_initializers())->accept( *this ); 571 } // if 572 #endif 420 // move cursor into brace-enclosed initializer-list 421 currentObject.enterListInit(); 422 // xxx - fix this so that the list isn't copied, iterator should be used to change current element 423 std::list<Designation *> newDesignations; 424 for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) { 425 // iterate designations and initializers in pairs, moving the cursor to the current designated object and resolving 426 // the initializer against that object. 427 Designation * des = std::get<0>(p); 428 Initializer * init = std::get<1>(p); 429 newDesignations.push_back( currentObject.findNext( des ) ); 430 init->accept( *this ); 431 } 432 // set the set of 'resolved' designations and leave the brace-enclosed initializer-list 433 listInit->get_designations() = newDesignations; // xxx - memory management 434 currentObject.exitListInit(); 435 436 // xxx - this part has not be folded into CurrentObject yet 437 // } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) { 438 // Type * base = tt->get_baseType()->get_base(); 439 // if ( base ) { 440 // // know the implementation type, so try using that as the initContext 441 // ObjectDecl tmpObj( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, base->clone(), nullptr ); 442 // currentObject = &tmpObj; 443 // visit( listInit ); 444 // } else { 445 // // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context 446 // Parent::visit( listInit ); 447 // } 448 // } else { 573 449 } 574 450 -
src/ResolvExpr/Unify.cc
r1abc5ab ra12d5aa 606 606 } else if ( tupleParam ) { 607 607 // bundle other parameters into tuple to match 608 TupleType* binder = new TupleType{ paramTy->get_qualifiers() };608 std::list< Type * > binderTypes; 609 609 610 610 do { 611 binder ->get_types().push_back( otherParam->get_type()->clone() );611 binderTypes.push_back( otherParam->get_type()->clone() ); 612 612 ++jt; 613 613 … … 618 618 } while (true); 619 619 620 otherParamTy = binder;620 otherParamTy = new TupleType{ paramTy->get_qualifiers(), binderTypes }; 621 621 ++it; // skip ttype parameter for break 622 622 } else if ( otherTupleParam ) { 623 623 // bundle parameters into tuple to match other 624 TupleType* binder = new TupleType{ otherParamTy->get_qualifiers() };624 std::list< Type * > binderTypes; 625 625 626 626 do { 627 binder ->get_types().push_back( param->get_type()->clone() );627 binderTypes.push_back( param->get_type()->clone() ); 628 628 ++it; 629 629 … … 634 634 } while (true); 635 635 636 paramTy = binder;636 paramTy = new TupleType{ otherParamTy->get_qualifiers(), binderTypes }; 637 637 ++jt; // skip ttype parameter for break 638 638 } … … 756 756 return function->get_returnVals().front()->get_type()->clone(); 757 757 } else { 758 TupleType * tupleType = new TupleType( Type::Qualifiers() );758 std::list< Type * > types; 759 759 for ( DeclarationWithType * decl : function->get_returnVals() ) { 760 t upleType->get_types().push_back( decl->get_type()->clone() );760 types.push_back( decl->get_type()->clone() ); 761 761 } // for 762 return tupleType;762 return new TupleType( Type::Qualifiers(), types ); 763 763 } 764 764 } -
src/ResolvExpr/module.mk
r1abc5ab ra12d5aa 6 6 ## file "LICENCE" distributed with Cforall. 7 7 ## 8 ## module.mk -- 8 ## module.mk -- 9 9 ## 10 10 ## Author : Richard C. Bilson … … 31 31 ResolvExpr/PolyCost.cc \ 32 32 ResolvExpr/Occurs.cc \ 33 ResolvExpr/TypeEnvironment.cc 33 ResolvExpr/TypeEnvironment.cc \ 34 ResolvExpr/CurrentObject.cc -
src/SymTab/Autogen.h
r1abc5ab ra12d5aa 25 25 26 26 namespace SymTab { 27 28 27 /// Generates assignment operators, constructors, and destructor for aggregate types as required 28 void autogenerateRoutines( std::list< Declaration * > &translationUnit ); 29 29 30 31 30 /// returns true if obj's name is the empty string and it has a bitfield width 31 bool isUnnamedBitfield( ObjectDecl * obj ); 32 32 33 34 35 33 /// size_t type - set when size_t typedef is seen. Useful in a few places, 34 /// such as in determining array dimension type 35 extern Type * SizeType; 36 36 37 38 37 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 38 template< typename OutputIterator > 39 39 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true ); 40 40 41 42 43 41 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. 42 /// optionally returns a statement which must be inserted prior to the containing loop, if there is one 43 template< typename OutputIterator > 44 44 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) { 45 45 // want to be able to generate assignment, ctor, and dtor generically, … … 50 50 dstParam = new AddressExpr( dstParam ); 51 51 if ( addCast ) { 52 // cast to T* with qualifiers removed, so that qualified objects can be constructed 53 // and destructed with the same functions as non-qualified objects. 54 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument 55 // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever 56 // remove lvalue as a qualifier, this can change to 57 // type->get_qualifiers() = Type::Qualifiers(); 58 assert( type ); 59 Type * castType = type->clone(); 60 // castType->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, false); 61 castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic ); 62 castType->set_lvalue( true ); // xxx - might not need this 63 dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) ); 52 // cast to T* with qualifiers removed, so that qualified objects can be constructed 53 // and destructed with the same functions as non-qualified objects. 54 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument 55 // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever 56 // remove lvalue as a qualifier, this can change to 57 // type->get_qualifiers() = Type::Qualifiers(); 58 assert( type ); 59 Type * castType = type->clone(); 60 castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic ); 61 castType->set_lvalue( true ); // xxx - might not need this 62 dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) ); 64 63 } 65 64 fExpr->get_args().push_back( dstParam ); … … 75 74 76 75 return listInit; 77 }78 79 /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.80 /// If forward is true, loop goes from 0 to N-1, else N-1 to 081 template< typename OutputIterator >82 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {83 static UniqueName indexName( "_index" );84 85 // for a flexible array member nothing is done -- user must define own assignment86 if ( ! array->get_dimension() ) return ;87 88 Expression * begin, * end, * update, * cmp;89 if ( forward ) {90 // generate: for ( int i = 0; i < N; ++i )91 begin = new ConstantExpr( Constant::from_int( 0 ) );92 end = array->get_dimension()->clone();93 cmp = new NameExpr( "?<?" );94 update = new NameExpr( "++?" );95 } else {96 // generate: for ( int i = N-1; i >= 0; --i )97 begin = new UntypedExpr( new NameExpr( "?-?" ) );98 ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );99 ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );100 end = new ConstantExpr( Constant::from_int( 0 ) );101 cmp = new NameExpr( "?>=?" );102 update = new NameExpr( "--?" );103 76 } 104 77 105 ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin, std::list<Expression*>() ) ); 78 /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments. 79 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 80 template< typename OutputIterator > 81 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) { 82 static UniqueName indexName( "_index" ); 106 83 107 UntypedExpr *cond = new UntypedExpr( cmp ); 108 cond->get_args().push_back( new VariableExpr( index ) ); 109 cond->get_args().push_back( end ); 84 // for a flexible array member nothing is done -- user must define own assignment 85 if ( ! array->get_dimension() ) return ; 110 86 111 UntypedExpr *inc = new UntypedExpr( update ); 112 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 87 Expression * begin, * end, * update, * cmp; 88 if ( forward ) { 89 // generate: for ( int i = 0; i < N; ++i ) 90 begin = new ConstantExpr( Constant::from_int( 0 ) ); 91 end = array->get_dimension()->clone(); 92 cmp = new NameExpr( "?<?" ); 93 update = new NameExpr( "++?" ); 94 } else { 95 // generate: for ( int i = N-1; i >= 0; --i ) 96 begin = new UntypedExpr( new NameExpr( "?-?" ) ); 97 ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() ); 98 ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) ); 99 end = new ConstantExpr( Constant::from_int( 0 ) ); 100 cmp = new NameExpr( "?>=?" ); 101 update = new NameExpr( "--?" ); 102 } 113 103 114 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 115 dstIndex->get_args().push_back( dstParam ); 116 dstIndex->get_args().push_back( new VariableExpr( index ) ); 117 dstParam = dstIndex; 104 ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin ) ); 118 105 119 // srcParam must keep track of the array indices to build the120 // source parameter and/or array list initializer121 srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone());106 UntypedExpr *cond = new UntypedExpr( cmp ); 107 cond->get_args().push_back( new VariableExpr( index ) ); 108 cond->get_args().push_back( end ); 122 109 123 // for stmt's body, eventually containing call 124 CompoundStmt * body = new CompoundStmt( noLabels ); 125 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward ); 110 UntypedExpr *inc = new UntypedExpr( update ); 111 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 126 112 127 // block containing for stmt and index variable 128 std::list<Statement *> initList; 129 CompoundStmt * block = new CompoundStmt( noLabels ); 130 block->get_kids().push_back( new DeclStmt( noLabels, index ) ); 131 if ( listInit ) block->get_kids().push_back( listInit ); 132 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) ); 113 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 114 dstIndex->get_args().push_back( dstParam ); 115 dstIndex->get_args().push_back( new VariableExpr( index ) ); 116 dstParam = dstIndex; 133 117 134 *out++ = block; 135 } 118 // srcParam must keep track of the array indices to build the 119 // source parameter and/or array list initializer 120 srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() ); 136 121 137 template< typename OutputIterator > 122 // for stmt's body, eventually containing call 123 CompoundStmt * body = new CompoundStmt( noLabels ); 124 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward ); 125 126 // block containing for stmt and index variable 127 std::list<Statement *> initList; 128 CompoundStmt * block = new CompoundStmt( noLabels ); 129 block->get_kids().push_back( new DeclStmt( noLabels, index ) ); 130 if ( listInit ) block->get_kids().push_back( listInit ); 131 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) ); 132 133 *out++ = block; 134 } 135 136 template< typename OutputIterator > 138 137 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) { 139 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 140 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); 141 return 0; 142 } else { 143 return genScalarCall( srcParam, dstParam, fname, out, type, addCast ); 138 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 139 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); 140 return 0; 141 } else { 142 return genScalarCall( srcParam, dstParam, fname, out, type, addCast ); 143 } 144 144 } 145 }146 145 147 148 149 150 151 146 /// inserts into out a generated call expression to function fname with arguments dstParam 147 /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the 148 /// object being constructed. The function wraps constructor and destructor calls in an 149 /// ImplicitCtorDtorStmt node. 150 template< typename OutputIterator > 152 151 void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) { 153 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );154 assert( obj );155 // unnamed bit fields are not copied as they cannot be accessed156 if ( isUnnamedBitfield( obj ) ) return;152 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl ); 153 assert( obj ); 154 // unnamed bit fields are not copied as they cannot be accessed 155 if ( isUnnamedBitfield( obj ) ) return; 157 156 158 bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );159 std::list< Statement * > stmts;160 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );157 bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ); 158 std::list< Statement * > stmts; 159 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward ); 161 160 162 // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call 163 assert( stmts.size() <= 1 ); 164 if ( stmts.size() == 1 ) { 165 Statement * callStmt = stmts.front(); 166 if ( addCast ) { 167 // implicitly generated ctor/dtor calls should be wrapped 168 // so that later passes are aware they were generated. 169 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield, 170 // because this causes the address to be taken at codegen, which is illegal in C. 171 callStmt = new ImplicitCtorDtorStmt( callStmt ); 172 } 173 *out++ = callStmt; 161 // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call 162 assert( stmts.size() <= 1 ); 163 if ( stmts.size() == 1 ) { 164 Statement * callStmt = stmts.front(); 165 if ( addCast ) { 166 // implicitly generated ctor/dtor calls should be wrapped 167 // so that later passes are aware they were generated. 168 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield, 169 // because this causes the address to be taken at codegen, which is illegal in C. 170 callStmt = new ImplicitCtorDtorStmt( callStmt ); 171 } 172 *out++ = callStmt; 173 } 174 174 } 175 }176 175 } // namespace SymTab 177 176 #endif // AUTOGEN_H -
src/SymTab/ImplementationType.cc
r1abc5ab ra12d5aa 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // ImplementationType.cc -- 7 // ImplementationType.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 92 92 93 93 void ImplementationType::visit(TupleType *tupleType) { 94 TupleType *newType = new TupleType( Type::Qualifiers() );94 std::list< Type * > types; 95 95 for ( std::list< Type* >::iterator i = tupleType->get_types().begin(); i != tupleType->get_types().end(); ++i ) { 96 96 Type *implType = implementationType( *i, indexer ); 97 97 implType->get_qualifiers() |= tupleType->get_qualifiers(); 98 newType->get_types().push_back( implType );98 types.push_back( implType ); 99 99 } // for 100 result = new Type;100 result = new TupleType( Type::Qualifiers(), types ); 101 101 } 102 102 -
src/SynTree/Constant.cc
r1abc5ab ra12d5aa 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Constant.cc -- 7 // Constant.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 46 46 } 47 47 48 unsigned long long Constant::get_ival() const { 49 assertf( safe_dynamic_cast<BasicType*>(type)->isInteger(), "Attempt to retrieve ival from non-integer constant." ); 50 return val.ival; 51 } 52 53 double Constant::get_dval() const { 54 assertf( ! safe_dynamic_cast<BasicType*>(type)->isInteger(), "Attempt to retrieve dval from integer constant." ); 55 return val.dval; 56 } 57 48 58 void Constant::print( std::ostream &os ) const { 49 59 os << "(" << rep << " " << val.ival; -
src/SynTree/Constant.h
r1abc5ab ra12d5aa 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Constant.h -- 7 // Constant.h -- 8 8 // 9 9 // Author : Richard C. Bilson … … 32 32 std::string & get_value() { return rep; } 33 33 void set_value( std::string newValue ) { rep = newValue; } 34 unsigned long long get_ival() const; 35 double get_dval() const; 34 36 35 37 /// generates a boolean constant of the given bool -
src/SynTree/Expression.cc
r1abc5ab ra12d5aa 21 21 #include <iterator> 22 22 23 #include "Declaration.h" 24 #include "Expression.h" 25 #include "Initializer.h" 26 #include "Statement.h" 23 27 #include "Type.h" 24 #include "Initializer.h"25 #include "Expression.h"26 #include "Declaration.h"27 #include "Statement.h"28 28 #include "TypeSubstitution.h" 29 #include "VarExprReplacer.h" 30 29 31 #include "Common/utility.h" 32 #include "Common/PassVisitor.h" 33 30 34 #include "InitTweak/InitTweak.h" 31 35 … … 92 96 93 97 Declaration *decl = get_var(); 94 // if ( decl != 0) decl->print(os, indent + 2);95 98 if ( decl != 0) decl->printShort(os, indent + 2); 96 99 os << std::endl; … … 657 660 } 658 661 662 InitAlternative::InitAlternative( Type * type, Designation * designation ) : type( type ), designation( designation ) {} 663 InitAlternative::InitAlternative( const InitAlternative & other ) : type( maybeClone( other.type ) ), designation( maybeClone( other.designation ) ) {} 664 InitAlternative::~InitAlternative() { 665 delete type; 666 delete designation; 667 } 668 669 UntypedInitExpr::UntypedInitExpr( Expression * expr, const std::list<InitAlternative> & initAlts ) : expr( expr ), initAlts( initAlts ) {} 670 UntypedInitExpr::UntypedInitExpr( const UntypedInitExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), initAlts( other.initAlts ) {} 671 UntypedInitExpr::~UntypedInitExpr() { 672 delete expr; 673 } 674 675 void UntypedInitExpr::print( std::ostream & os, int indent ) const { 676 os << "Untyped Init Expression" << std::endl << std::string( indent+2, ' ' ); 677 expr->print( os, indent+2 ); 678 if ( ! initAlts.empty() ) { 679 for ( const InitAlternative & alt : initAlts ) { 680 os << std::string( indent+2, ' ' ) << "InitAlternative: "; 681 alt.type->print( os, indent+2 ); 682 alt.designation->print( os, indent+2 ); 683 } 684 } 685 } 686 687 InitExpr::InitExpr( Expression * expr, Designation * designation ) : expr( expr ), designation( designation ) { 688 set_result( expr->get_result()->clone() ); 689 } 690 InitExpr::InitExpr( const InitExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), designation( maybeClone( other.designation) ) {} 691 InitExpr::~InitExpr() { 692 delete expr; 693 delete designation; 694 } 695 696 void InitExpr::print( std::ostream & os, int indent ) const { 697 os << "Init Expression" << std::endl << std::string( indent+2, ' ' ); 698 expr->print( os, indent+2 ); 699 os << std::string( indent+2, ' ' ) << "with designation: "; 700 designation->print( os, indent+2 ); 701 } 702 703 659 704 std::ostream & operator<<( std::ostream & out, const Expression * expr ) { 660 705 if ( expr ) { -
src/SynTree/Expression.h
r1abc5ab ra12d5aa 744 744 }; 745 745 746 struct InitAlternative { 747 public: 748 Type * type = nullptr; 749 Designation * designation = nullptr; 750 InitAlternative( Type * type, Designation * designation ); 751 InitAlternative( const InitAlternative & other ); 752 InitAlternative & operator=( const Initializer & other ) = delete; // at the moment this isn't used, and I don't want to implement it 753 ~InitAlternative(); 754 }; 755 756 class UntypedInitExpr : public Expression { 757 public: 758 UntypedInitExpr( Expression * expr, const std::list<InitAlternative> & initAlts ); 759 UntypedInitExpr( const UntypedInitExpr & other ); 760 ~UntypedInitExpr(); 761 762 Expression * get_expr() const { return expr; } 763 UntypedInitExpr * set_expr( Expression * newValue ) { expr = newValue; return this; } 764 765 std::list<InitAlternative> & get_initAlts() { return initAlts; } 766 767 virtual UntypedInitExpr * clone() const { return new UntypedInitExpr( * this ); } 768 virtual void accept( Visitor & v ) { v.visit( this ); } 769 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 770 virtual void print( std::ostream & os, int indent = 0 ) const; 771 private: 772 Expression * expr; 773 std::list<InitAlternative> initAlts; 774 }; 775 776 class InitExpr : public Expression { 777 public: 778 InitExpr( Expression * expr, Designation * designation ); 779 InitExpr( const InitExpr & other ); 780 ~InitExpr(); 781 782 Expression * get_expr() const { return expr; } 783 InitExpr * set_expr( Expression * newValue ) { expr = newValue; return this; } 784 785 Designation * get_designation() const { return designation; } 786 InitExpr * set_designation( Designation * newValue ) { designation = newValue; return this; } 787 788 virtual InitExpr * clone() const { return new InitExpr( * this ); } 789 virtual void accept( Visitor & v ) { v.visit( this ); } 790 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 791 virtual void print( std::ostream & os, int indent = 0 ) const; 792 private: 793 Expression * expr; 794 Designation * designation; 795 }; 796 797 746 798 std::ostream & operator<<( std::ostream & out, const Expression * expr ); 747 799 -
src/SynTree/Initializer.cc
r1abc5ab ra12d5aa 19 19 #include "Common/utility.h" 20 20 21 Designation::Designation( const std::list< Expression * > & designators ) : designators( designators ) {} 22 Designation::Designation( const Designation & other ) : BaseSyntaxNode( other ) { 23 // std::cerr << "cloning designation" << std::endl; 24 cloneAll( other.designators, designators ); 25 // std::cerr << "finished cloning designation" << std::endl; 26 } 27 28 Designation::~Designation() { 29 // std::cerr << "destroying designation" << std::endl; 30 deleteAll( designators ); 31 // std::cerr << "finished destroying designation" << std::endl; 32 } 33 34 void Designation::print( std::ostream &os, int indent ) const { 35 if ( ! designators.empty() ) { 36 os << std::string(indent + 2, ' ' ) << "designated by: " << std::endl; 37 for ( std::list < Expression * >::const_iterator i = designators.begin(); i != designators.end(); i++ ) { 38 os << std::string(indent + 4, ' ' ); 39 ( *i )->print(os, indent + 4 ); 40 } 41 os << std::endl; 42 } // if 43 } 44 21 45 Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {} 22 46 Initializer::Initializer( const Initializer & other ) : BaseSyntaxNode( other ), maybeConstructed( other.maybeConstructed ) { 23 47 } 24 25 26 48 Initializer::~Initializer() {} 27 49 28 std::string Initializer::designator_name( Expression *des ) { 29 if ( NameExpr *n = dynamic_cast<NameExpr *>(des) ) 30 return n->get_name(); 31 else 32 throw 0; 33 } 34 35 // void Initializer::print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent ) {} 36 37 SingleInit::SingleInit( Expression *v, const std::list< Expression *> &_designators, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ), designators( _designators ) { 50 SingleInit::SingleInit( Expression *v, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ) { 38 51 } 39 52 40 53 SingleInit::SingleInit( const SingleInit &other ) : Initializer(other), value ( maybeClone( other.value ) ) { 41 cloneAll(other.designators, designators );42 54 } 43 55 44 56 SingleInit::~SingleInit() { 45 57 delete value; 46 deleteAll(designators);47 58 } 48 59 49 void SingleInit::print( std::ostream &os, int indent ) {50 os << std:: endl << std::string(indent, ' ' ) << "Simple Initializer: " << std::endl;60 void SingleInit::print( std::ostream &os, int indent ) const { 61 os << std::string(indent, ' ' ) << "Simple Initializer: " << std::endl; 51 62 os << std::string(indent+4, ' ' ); 52 63 value->print( os, indent+4 ); 53 54 if ( ! designators.empty() ) {55 os << std::endl << std::string(indent + 2, ' ' ) << "designated by: " << std::endl;56 for ( std::list < Expression * >::iterator i = designators.begin(); i != designators.end(); i++ ) {57 os << std::string(indent + 4, ' ' );58 ( *i )->print(os, indent + 4 );59 }60 } // if61 64 } 62 65 63 ListInit::ListInit( const std::list<Initializer*> &_initializers, const std::list<Expression *> &_designators, bool maybeConstructed ) 64 : Initializer( maybeConstructed ), initializers( _initializers ), designators( _designators ) { 66 67 ListInit::ListInit( const std::list<Initializer*> &inits, const std::list<Designation *> &des, bool maybeConstructed ) 68 : Initializer( maybeConstructed ), initializers( inits ), designations( des ) { 69 // handle the common case where a ListInit is created without designations by making a list of empty designations with the same length as the initializer 70 if ( designations.empty() ) { 71 for ( auto & i : initializers ) { 72 (void)i; 73 designations.push_back( new Designation( {} ) ); 74 } 75 } 76 assertf( initializers.size() == designations.size(), "Created ListInit with mismatching initializers (%d) and designations (%d)", initializers.size(), designations.size() ); 65 77 } 66 78 67 79 ListInit::ListInit( const ListInit & other ) : Initializer( other ) { 68 80 cloneAll( other.initializers, initializers ); 69 cloneAll( other.designat ors, designators );81 cloneAll( other.designations, designations ); 70 82 } 71 72 83 73 84 ListInit::~ListInit() { 74 85 deleteAll( initializers ); 75 deleteAll( designat ors );86 deleteAll( designations ); 76 87 } 77 88 78 void ListInit::print( std::ostream &os, int indent ) { 79 os << std::endl << std::string(indent, ' ') << "Compound initializer: "; 80 if ( ! designators.empty() ) { 81 os << std::string(indent + 2, ' ' ) << "designated by: ["; 82 for ( std::list < Expression * >::iterator i = designators.begin(); 83 i != designators.end(); i++ ) { 84 ( *i )->print(os, indent + 4 ); 85 } // for 89 void ListInit::print( std::ostream &os, int indent ) const { 90 os << std::string(indent, ' ') << "Compound initializer: " << std::endl; 91 for ( Designation * d : designations ) { 92 d->print( os, indent + 2 ); 93 } 86 94 87 os << std::string(indent + 2, ' ' ) << "]"; 88 } // if 89 90 for ( std::list<Initializer *>::iterator i = initializers.begin(); i != initializers.end(); i++ ) 91 (*i)->print( os, indent + 2 ); 95 for ( const Initializer * init : initializers ) { 96 init->print( os, indent + 2 ); 97 os << std::endl; 98 } 92 99 } 93 100 … … 103 110 } 104 111 105 void ConstructorInit::print( std::ostream &os, int indent ) {112 void ConstructorInit::print( std::ostream &os, int indent ) const { 106 113 os << std::endl << std::string(indent, ' ') << "Constructor initializer: " << std::endl; 107 114 if ( ctor ) { … … 124 131 } 125 132 126 std::ostream & operator<<( std::ostream & out, Initializer * init ) { 127 init->print( out ); 133 std::ostream & operator<<( std::ostream & out, const Initializer * init ) { 134 if ( init ) { 135 init->print( out ); 136 } else { 137 out << "nullptr"; 138 } 139 return out; 140 } 141 142 std::ostream & operator<<( std::ostream & out, const Designation * des ) { 143 if ( des ) { 144 des->print( out ); 145 } else { 146 out << "nullptr"; 147 } 128 148 return out; 129 149 } -
src/SynTree/Initializer.h
r1abc5ab ra12d5aa 25 25 #include "Visitor.h" 26 26 27 const std::list<Expression*> noDesignators; 27 // Designation: list of designator (NameExpr, VariableExpr, and ConstantExpr) expressions that specify an object being initialized. 28 class Designation : public BaseSyntaxNode { 29 public: 30 Designation( const std::list< Expression * > & designators ); 31 Designation( const Designation & other ); 32 virtual ~Designation(); 33 34 std::list< Expression * > & get_designators() { return designators; } 35 36 virtual Designation * clone() const { return new Designation( *this ); }; 37 virtual void accept( Visitor &v ) { v.visit( this ); } 38 virtual Designation * acceptMutator( Mutator &m ) { return m.mutate( this ); } 39 virtual void print( std::ostream &os, int indent = 0 ) const; 40 private: 41 std::list< Expression * > designators; 42 }; 43 44 const std::list<Designation *> noDesignators; 28 45 29 46 // Initializer: base class for object initializers (provide default values) 30 47 class Initializer : public BaseSyntaxNode { 31 48 public: 32 // Initializer( std::string _name = std::string(""), int _pos = 0 );33 49 Initializer( bool maybeConstructed ); 34 50 Initializer( const Initializer & other ); 35 51 virtual ~Initializer(); 36 37 static std::string designator_name( Expression *designator );38 39 // void set_name( std::string newValue ) { name = newValue; }40 // std::string get_name() const { return name; }41 42 // void set_pos( int newValue ) { pos = newValue; }43 // int get_pos() const { return pos; }44 virtual void set_designators( std::list<Expression *> & ) { assert(false); }45 virtual std::list<Expression *> &get_designators() {46 assert(false);47 std::list<Expression *> *ret = 0; return *ret; // never reached48 }49 52 50 53 bool get_maybeConstructed() { return maybeConstructed; } … … 53 56 virtual void accept( Visitor &v ) = 0; 54 57 virtual Initializer *acceptMutator( Mutator &m ) = 0; 55 virtual void print( std::ostream &os, int indent = 0 ) = 0;58 virtual void print( std::ostream &os, int indent = 0 ) const = 0; 56 59 private: 57 // std::string name;58 // int pos;59 60 bool maybeConstructed; 60 61 }; … … 63 64 class SingleInit : public Initializer { 64 65 public: 65 SingleInit( Expression *value, const std::list< Expression *> &designators = std::list< Expression * >(),bool maybeConstructed = false );66 SingleInit( Expression *value, bool maybeConstructed = false ); 66 67 SingleInit( const SingleInit &other ); 67 68 virtual ~SingleInit(); … … 70 71 void set_value( Expression *newValue ) { value = newValue; } 71 72 72 std::list<Expression *> &get_designators() { return designators; }73 void set_designators( std::list<Expression *> &newValue ) { designators = newValue; }74 75 73 virtual SingleInit *clone() const { return new SingleInit( *this); } 76 74 virtual void accept( Visitor &v ) { v.visit( this ); } 77 75 virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); } 78 virtual void print( std::ostream &os, int indent = 0 ) ;76 virtual void print( std::ostream &os, int indent = 0 ) const; 79 77 private: 80 78 //Constant *value; 81 79 Expression *value; // has to be a compile-time constant 82 std::list< Expression * > designators;83 80 }; 84 81 … … 88 85 public: 89 86 ListInit( const std::list<Initializer*> &initializers, 90 const std::list< Expression *> &designators = std::list< Expression * >(), bool maybeConstructed = false );87 const std::list<Designation *> &designators = {}, bool maybeConstructed = false ); 91 88 ListInit( const ListInit & other ); 92 89 virtual ~ListInit(); 93 90 94 void set_designators( std::list<Expression *> &newValue ) { designators = newValue; } 95 std::list<Expression *> &get_designators() { return designators; } 96 void set_initializers( std::list<Initializer*> &newValue ) { initializers = newValue; } 97 std::list<Initializer*> &get_initializers() { return initializers; } 91 std::list<Designation *> & get_designations() { return designations; } 92 std::list<Initializer *> & get_initializers() { return initializers; } 98 93 99 94 typedef std::list<Initializer*>::iterator iterator; 95 typedef std::list<Initializer*>::const_iterator const_iterator; 100 96 iterator begin() { return initializers.begin(); } 101 97 iterator end() { return initializers.end(); } 98 const_iterator begin() const { return initializers.begin(); } 99 const_iterator end() const { return initializers.end(); } 102 100 103 101 virtual ListInit *clone() const { return new ListInit( *this ); } 104 102 virtual void accept( Visitor &v ) { v.visit( this ); } 105 103 virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); } 106 virtual void print( std::ostream &os, int indent = 0 ) ;104 virtual void print( std::ostream &os, int indent = 0 ) const; 107 105 private: 108 std::list<Initializer *> initializers; // order *is* important109 std::list< Expression *> designators;106 std::list<Initializer *> initializers; // order *is* important 107 std::list<Designation *> designations; // order/length is consistent with initializers 110 108 }; 111 109 … … 130 128 virtual void accept( Visitor &v ) { v.visit( this ); } 131 129 virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); } 132 virtual void print( std::ostream &os, int indent = 0 ) ;130 virtual void print( std::ostream &os, int indent = 0 ) const; 133 131 134 132 private: … … 140 138 }; 141 139 142 std::ostream & operator<<( std::ostream & out, Initializer * init ); 140 std::ostream & operator<<( std::ostream & out, const Initializer * init ); 141 std::ostream & operator<<( std::ostream & out, const Designation * des ); 143 142 144 143 #endif // INITIALIZER_H -
src/SynTree/Mutator.cc
r1abc5ab ra12d5aa 433 433 } 434 434 435 Expression *Mutator::mutate( UntypedInitExpr * initExpr ) { 436 initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) ); 437 initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) ); 438 initExpr->set_expr( maybeMutate( initExpr->get_expr(), *this ) ); 439 // not currently mutating initAlts, but this doesn't matter since this node is only used in the resolver. 440 return initExpr; 441 } 442 443 Expression *Mutator::mutate( InitExpr * initExpr ) { 444 initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) ); 445 initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) ); 446 initExpr->set_expr( maybeMutate( initExpr->get_expr(), *this ) ); 447 initExpr->set_designation( maybeMutate( initExpr->get_designation(), *this ) ); 448 return initExpr; 449 } 450 435 451 436 452 Type *Mutator::mutate( VoidType *voidType ) { … … 499 515 mutateAll( tupleType->get_forall(), *this ); 500 516 mutateAll( tupleType->get_types(), *this ); 517 mutateAll( tupleType->get_members(), *this ); 501 518 return tupleType; 502 519 } … … 535 552 536 553 554 Designation *Mutator::mutate( Designation * designation ) { 555 mutateAll( designation->get_designators(), *this ); 556 return designation; 557 } 558 537 559 Initializer *Mutator::mutate( SingleInit *singleInit ) { 538 560 singleInit->set_value( singleInit->get_value()->acceptMutator( *this ) ); … … 541 563 542 564 Initializer *Mutator::mutate( ListInit *listInit ) { 543 mutateAll( listInit->get_designat ors(), *this );565 mutateAll( listInit->get_designations(), *this ); 544 566 mutateAll( listInit->get_initializers(), *this ); 545 567 return listInit; -
src/SynTree/Mutator.h
r1abc5ab ra12d5aa 85 85 virtual Expression* mutate( StmtExpr * stmtExpr ); 86 86 virtual Expression* mutate( UniqueExpr * uniqueExpr ); 87 virtual Expression* mutate( UntypedInitExpr * initExpr ); 88 virtual Expression* mutate( InitExpr * initExpr ); 87 89 88 90 virtual Type* mutate( VoidType *basicType ); … … 103 105 virtual Type* mutate( OneType *oneType ); 104 106 107 virtual Designation* mutate( Designation *designation ); 105 108 virtual Initializer* mutate( SingleInit *singleInit ); 106 109 virtual Initializer* mutate( ListInit *listInit ); -
src/SynTree/SynTree.h
r1abc5ab ra12d5aa 93 93 class StmtExpr; 94 94 class UniqueExpr; 95 class UntypedInitExpr; 96 class InitExpr; 95 97 96 98 class Type; … … 113 115 class OneType; 114 116 117 class Designation; 115 118 class Initializer; 116 119 class SingleInit; -
src/SynTree/TupleType.cc
r1abc5ab ra12d5aa 14 14 // 15 15 16 #include "Declaration.h" 17 #include "Initializer.h" 16 18 #include "Type.h" 17 19 #include "Common/utility.h" 20 #include "Parser/LinkageSpec.h" 18 21 19 22 TupleType::TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types, const std::list< Attribute * > & attributes ) : Type( tq, attributes ), types( types ) { 23 for ( Type * t : *this ) { 24 // xxx - this is very awkward. TupleTypes should contain objects so that members can be named, but if they don't have an initializer node then 25 // they end up getting constructors, which end up being inserted causing problems. This happens because the object decls have to be visited so that 26 // their types are kept in sync with the types list here. Ultimately, the types list here should be eliminated and perhaps replaced with a list-view 27 // of the object types list, but I digress. The temporary solution here is to make a ListInit with maybeConstructed = false, that way even when the 28 // object is visited, it is never constructed. Ultimately, a better solution might be either: 29 // a) to separate TupleType from its declarations, into TupleDecl and Tuple{Inst?}Type, ala StructDecl and StructInstType 30 // b) separate initializer nodes better, e.g. add a MaybeConstructed node that is replaced by genInit, rather than what currently exists in a bool 31 members.push_back( new ObjectDecl( "" , Type::StorageClasses(), LinkageSpec::Cforall, nullptr, t->clone(), new ListInit( {}, {}, false ) ) ); 32 } 20 33 } 21 34 22 35 TupleType::TupleType( const TupleType& other ) : Type( other ) { 23 36 cloneAll( other.types, types ); 37 cloneAll( other.members, members ); 24 38 } 25 39 26 40 TupleType::~TupleType() { 27 41 deleteAll( types ); 42 deleteAll( members ); 28 43 } 29 44 -
src/SynTree/Type.h
r1abc5ab ra12d5aa 481 481 class TupleType : public Type { 482 482 public: 483 TupleType( const Type::Qualifiers & tq, const std::list< Type * > & types = std::list< Type * >(), const std::list< Attribute * > & attributes = std::list< Attribute * >() );483 TupleType( const Type::Qualifiers & tq, const std::list< Type * > & types, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 484 484 TupleType( const TupleType& ); 485 485 virtual ~TupleType(); … … 488 488 typedef value_type::iterator iterator; 489 489 490 std::list<Type *>& get_types() { return types; }490 std::list<Type *> & get_types() { return types; } 491 491 virtual unsigned size() const { return types.size(); }; 492 493 // For now, this is entirely synthetic -- tuple types always have unnamed members. 494 // Eventually, we may allow named tuples, in which case members should subsume types 495 std::list<Declaration *> & get_members() { return members; } 492 496 493 497 iterator begin() { return types.begin(); } … … 506 510 virtual void print( std::ostream & os, int indent = 0 ) const; 507 511 private: 508 std::list<Type*> types; 512 std::list<Type *> types; 513 std::list<Declaration *> members; 509 514 }; 510 515 -
src/SynTree/VarExprReplacer.cc
r1abc5ab ra12d5aa 14 14 // 15 15 16 #include "Declaration.h" 16 17 #include "Expression.h" 17 18 #include "VarExprReplacer.h" 18 19 19 VarExprReplacer::VarExprReplacer( const DeclMap & declMap ) : declMap( declMap) {}20 VarExprReplacer::VarExprReplacer( const DeclMap & declMap, bool debug ) : declMap( declMap ), debug( debug ) {} 20 21 21 22 // replace variable with new node from decl map 22 23 void VarExprReplacer::visit( VariableExpr * varExpr ) { 23 // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are) 24 if ( declMap.count( varExpr->get_var() ) ) { 25 varExpr->set_var( declMap.at( varExpr->get_var() ) ); 26 } 24 // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are) 25 if ( declMap.count( varExpr->get_var() ) ) { 26 if ( debug ) { 27 std::cerr << "replacing variable reference: " << (void*)varExpr->get_var() << " " << varExpr->get_var() << " with " << (void*)declMap.at( varExpr->get_var() ) << " " << declMap.at( varExpr->get_var() ) << std::endl; 28 } 29 varExpr->set_var( declMap.at( varExpr->get_var() ) ); 30 } 27 31 } -
src/SynTree/VarExprReplacer.h
r1abc5ab ra12d5aa 27 27 private: 28 28 const DeclMap & declMap; 29 bool debug; 29 30 public: 30 VarExprReplacer( const DeclMap & declMap );31 VarExprReplacer( const DeclMap & declMap, bool debug = false ); 31 32 32 33 // replace variable with new node from decl map -
src/SynTree/Visitor.cc
r1abc5ab ra12d5aa 340 340 } 341 341 342 void Visitor::visit( UntypedInitExpr * initExpr ) { 343 maybeAccept( initExpr->get_result(), *this ); 344 maybeAccept( initExpr->get_expr(), *this ); 345 // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver. 346 } 347 348 void Visitor::visit( InitExpr * initExpr ) { 349 maybeAccept( initExpr->get_result(), *this ); 350 maybeAccept( initExpr->get_expr(), *this ); 351 maybeAccept( initExpr->get_designation(), *this ); 352 } 353 342 354 343 355 void Visitor::visit( VoidType *voidType ) { … … 395 407 acceptAll( tupleType->get_forall(), *this ); 396 408 acceptAll( tupleType->get_types(), *this ); 409 acceptAll( tupleType->get_members(), *this ); 397 410 } 398 411 … … 424 437 } 425 438 439 void Visitor::visit( Designation * designation ) { 440 acceptAll( designation->get_designators(), *this ); 441 } 426 442 427 443 void Visitor::visit( SingleInit *singleInit ) { … … 430 446 431 447 void Visitor::visit( ListInit *listInit ) { 432 acceptAll( listInit->get_designat ors(), *this );448 acceptAll( listInit->get_designations(), *this ); 433 449 acceptAll( listInit->get_initializers(), *this ); 434 450 } -
src/SynTree/Visitor.h
r1abc5ab ra12d5aa 88 88 virtual void visit( StmtExpr * stmtExpr ); 89 89 virtual void visit( UniqueExpr * uniqueExpr ); 90 virtual void visit( UntypedInitExpr * initExpr ); 91 virtual void visit( InitExpr * initExpr ); 90 92 91 93 virtual void visit( VoidType *basicType ); … … 106 108 virtual void visit( OneType *oneType ); 107 109 110 virtual void visit( Designation *designation ); 108 111 virtual void visit( SingleInit *singleInit ); 109 112 virtual void visit( ListInit *listInit ); -
src/Tuples/TupleExpansion.cc
r1abc5ab ra12d5aa 192 192 } 193 193 ObjectDecl * finished = new ObjectDecl( toString( "_unq", id, "_finished_" ), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::Bool ), 194 new SingleInit( new ConstantExpr( Constant::from_int( 0 ) ) , noDesignators) );194 new SingleInit( new ConstantExpr( Constant::from_int( 0 ) ) ) ); 195 195 addDeclaration( finished ); 196 196 // (finished ? _unq_expr_N : (_unq_expr_N = <unqExpr->get_expr()>, finished = 1, _unq_expr_N)) … … 310 310 Type * makeTupleType( const std::list< Expression * > & exprs ) { 311 311 // produce the TupleType which aggregates the types of the exprs 312 TupleType *tupleType = new TupleType( Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Lvalue | Type::Atomic | Type::Mutex ) );313 Type::Qualifiers &qualifiers = tupleType->get_qualifiers();312 std::list< Type * > types; 313 Type::Qualifiers qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Lvalue | Type::Atomic | Type::Mutex ); 314 314 for ( Expression * expr : exprs ) { 315 315 assert( expr->get_result() ); 316 316 if ( expr->get_result()->isVoid() ) { 317 317 // if the type of any expr is void, the type of the entire tuple is void 318 delete tupleType;319 318 return new VoidType( Type::Qualifiers() ); 320 319 } 321 320 Type * type = expr->get_result()->clone(); 322 t upleType->get_types().push_back( type );321 types.push_back( type ); 323 322 // the qualifiers on the tuple type are the qualifiers that exist on all component types 324 323 qualifiers &= type->get_qualifiers(); 325 324 } // for 326 325 if ( exprs.empty() ) qualifiers = Type::Qualifiers(); 327 return tupleType;326 return new TupleType( qualifiers, types ); 328 327 } 329 328
Note: See TracChangeset
for help on using the changeset viewer.