- Timestamp:
- Jul 5, 2017, 10:50:22 AM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 0614d14
- Parents:
- 11dbfe1 (diff), 307a732 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 6 added
- 1 deleted
- 57 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 12 12 #include "SynTree/Expression.h" 13 13 #include "SynTree/Constant.h" 14 #include "SynTree/TypeSubstitution.h" 14 15 15 16 #include "PassVisitor.proto.h" … … 26 27 // stmtsToAddBefore or stmtsToAddAfter respectively. 27 28 // | WithShortCircuiting - provides the ability to skip visiting child nodes; set visit_children to false in pre{visit,mutate} to skip visiting children 28 // | With Scopes - provides the ability to save/restore data like a LIFO stack; to save, call GuardValue with the variable to save, the variable29 // | WithGuards - provides the ability to save/restore data like a LIFO stack; to save, call GuardValue with the variable to save, the variable 29 30 // will automatically be restored to its previous value after the corresponding postvisit/postmutate teminates. 30 31 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- … … 32 33 class PassVisitor final : public Visitor, public Mutator { 33 34 public: 34 PassVisitor() = default;35 35 36 36 template< typename... Args > … … 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 … … 283 272 284 273 public: 285 TypeSubstitution * env ;274 TypeSubstitution * env = nullptr; 286 275 }; 287 276 … … 295 284 std::list< Statement* > stmtsToAddAfter; 296 285 }; 286 287 class WithDeclsToAdd { 288 protected: 289 WithDeclsToAdd() = default; 290 ~WithDeclsToAdd() = default; 291 292 public: 293 std::list< Declaration* > declsToAddBefore; 294 std::list< Declaration* > declsToAddAfter; 295 }; 296 297 297 class WithShortCircuiting { 298 298 protected: … … 304 304 }; 305 305 306 class With Scopes {307 protected: 308 With Scopes() = default;309 ~With Scopes() = default;306 class WithGuards { 307 protected: 308 WithGuards() = default; 309 ~WithGuards() = default; 310 310 311 311 public: … … 318 318 }, static_cast< void * >( & val ) ); 319 319 } 320 321 template< typename T > 322 void GuardScope( T& val ) { 323 val.beginScope(); 324 at_cleanup( []( void * val ) { 325 static_cast< T * >( val )->endScope(); 326 }, static_cast< void * >( & val ) ); 327 } 328 329 template< typename Func > 330 void GuardAction( Func func ) { 331 at_cleanup( [func](__attribute__((unused)) void *) { func(); }, nullptr ); 332 } 320 333 }; 321 334 … … 323 336 class WithVisitorRef { 324 337 protected: 325 WithVisitorRef() = default;326 ~WithVisitorRef() = default;327 328 public: 329 PassVisitor<pass_type> * const visitor ;338 WithVisitorRef() {} 339 ~WithVisitorRef() {} 340 341 public: 342 PassVisitor<pass_type> * const visitor = nullptr; 330 343 }; 331 344 -
src/Common/PassVisitor.impl.h
r11dbfe1 r67fa9f9 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 ); \ … … 68 68 for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) { 69 69 // splice in new declarations after previous decl 70 if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); } 70 if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); } 71 71 72 72 if ( i == decls.end() ) break; … … 88 88 for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) { 89 89 // splice in new declarations after previous decl 90 if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); } 90 if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); } 91 91 92 92 if ( i == decls.end() ) break; … … 104 104 void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) { 105 105 SemanticError errors; 106 107 // don't want statements from outer CompoundStmts to be added to this CompoundStmt 108 ValueGuardPtr< StmtList_t > oldBeforeStmts( get_beforeStmts() ); 109 ValueGuardPtr< StmtList_t > oldAfterStmts ( get_afterStmts () ); 110 ValueGuardPtr< DeclList_t > oldBeforeDecls( get_beforeDecls() ); 111 ValueGuardPtr< DeclList_t > oldAfterDecls ( get_afterDecls () ); 106 112 107 113 StmtList_t* beforeStmts = get_beforeStmts(); … … 181 187 Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) { 182 188 return handleStatement( stmt, [this]( Statement * stmt ) { 183 maybeAccept( stmt, *this ); 189 maybeAccept( stmt, *this ); 184 190 return stmt; 185 191 }); … … 212 218 expr->accept( *this ); 213 219 return expr; 214 }); 220 }); 215 221 } 216 222 … … 565 571 VISIT_START( node ); 566 572 573 // maybeAccept( node->get_env(), *this ); 574 maybeAccept( node->get_result(), *this ); 575 567 576 for ( auto expr : node->get_args() ) { 568 577 visitExpression( expr ); … … 575 584 Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) { 576 585 MUTATE_START( node ); 586 587 node->set_env( maybeMutate( node->get_env(), *this ) ); 588 node->set_result( maybeMutate( node->get_result(), *this ) ); 577 589 578 590 for ( auto& expr : node->get_args() ) { -
src/Common/PassVisitor.proto.h
r11dbfe1 r67fa9f9 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 { … … 56 62 // Deep magic (a.k.a template meta programming) to make the templated visitor work 57 63 // Basically the goal is to make 2 previsit_impl 58 // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 64 // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 59 65 // 'pass.previsit( node )' that compiles will be used for that node for that type 60 66 // This requires that this option only compile for passes that actually define an appropriate visit. -
src/Common/utility.h
r11dbfe1 r67fa9f9 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/ControlStruct/ExceptTranslate.cc
r11dbfe1 r67fa9f9 10 10 // Created On : Wed Jun 14 16:49:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Jun 22 15:57:00 201713 // Update Count : 012 // Last Modified On : Fri Jun 30 13:30:00 2017 13 // Update Count : 1 14 14 // 15 15 16 16 #include "ExceptTranslate.h" 17 17 #include "Common/PassVisitor.h" 18 19 namespace ControlFlow { 18 #include "SynTree/Statement.h" 19 #include "SynTree/Declaration.h" 20 #include "SynTree/Expression.h" 21 #include "SynTree/Type.h" 22 #include "SynTree/Attribute.h" 23 24 namespace ControlStruct { 20 25 21 26 // This (large) section could probably be moved out of the class … … 24 29 // Type(Qualifiers &, false, std::list<Attribute *> &) 25 30 26 // void (*function)() 27 static FunctionType void_func_t(Type::Qualifiers(), false);31 // void (*function)(); 32 static FunctionType try_func_t(Type::Qualifiers(), false); 28 33 // void (*function)(int, exception); 29 34 static FunctionType catch_func_t(Type::Qualifiers(), false); … … 32 37 // bool (*function)(exception); 33 38 static FunctionType handle_func_t(Type::Qualifiers(), false); 39 // void (*function)(__attribute__((unused)) void *); 40 static FunctionType finally_func_t(Type::Qualifiers(), false); 34 41 35 42 static void init_func_types() { 36 static init_complete = false;43 static bool init_complete = false; 37 44 if (init_complete) { 38 45 return; 39 46 } 40 47 ObjectDecl index_obj( 41 " index_t",48 "__handler_index", 42 49 Type::StorageClasses(), 43 50 LinkageSpec::Cforall, 44 51 /*bitfieldWidth*/ NULL, 45 new BasicType( emptyQualifiers, BasicType::UnsignedInt),52 new BasicType( emptyQualifiers, BasicType::SignedInt ), 46 53 /*init*/ NULL 47 );54 ); 48 55 ObjectDecl exception_obj( 49 " exception_t",56 "__exception_inst", 50 57 Type::StorageClasses(), 51 58 LinkageSpec::Cforall, 52 59 /*bitfieldWidth*/ NULL, 53 new BasicType(emptyQualifiers, BasicType::UnsignedInt), 60 new PointerType( 61 emptyQualifiers, 62 new BasicType( emptyQualifiers, BasicType::SignedInt ) 63 ), 54 64 /*init*/ NULL 55 );65 ); 56 66 ObjectDecl bool_obj( 57 " bool_t",67 "__ret_bool", 58 68 Type::StorageClasses(), 59 69 LinkageSpec::Cforall, … … 61 71 new BasicType(emptyQualifiers, BasicType::Bool), 62 72 /*init*/ NULL 63 ); 64 65 catch_func_t.get_parameters().push_back(index_obj.clone()); 66 catch_func_t.get_parameters().push_back(exception_obj.clone()); 67 match_func_t.get_returnVals().push_back(index_obj.clone()); 68 match_func_t.get_parameters().push_back(exception_obj.clone()); 69 handle_func_t.get_returnVals().push_back(bool_obj.clone()); 70 handle_func_t.get_parameters().push_back(exception_obj.clone()); 73 ); 74 ObjectDecl voidptr_obj( 75 "__hook", 76 Type::StorageClasses(), 77 LinkageSpec::Cforall, 78 NULL, 79 new PointerType( 80 emptyQualifiers, 81 new VoidType( 82 emptyQualifiers 83 ), 84 std::list<Attribute *>{new Attribute("unused")} 85 ), 86 NULL 87 ); 88 89 catch_func_t.get_parameters().push_back( index_obj.clone() ); 90 catch_func_t.get_parameters().push_back( exception_obj.clone() ); 91 match_func_t.get_returnVals().push_back( index_obj.clone() ); 92 match_func_t.get_parameters().push_back( exception_obj.clone() ); 93 handle_func_t.get_returnVals().push_back( bool_obj.clone() ); 94 handle_func_t.get_parameters().push_back( exception_obj.clone() ); 95 finally_func_t.get_parameters().push_back( voidptr_obj.clone() ); 71 96 72 97 init_complete = true; … … 78 103 79 104 void split( CatchList& allHandlers, CatchList& terHandlers, 80 105 CatchList& resHandlers ) { 81 106 while ( !allHandlers.empty() ) { 82 Statement * stmt = allHandlers.front();107 CatchStmt * stmt = allHandlers.front(); 83 108 allHandlers.pop_front(); 84 if (Ca seStmt::Terminate == stmt->get_kind()) {109 if (CatchStmt::Terminate == stmt->get_kind()) { 85 110 terHandlers.push_back(stmt); 86 111 } else { … … 92 117 template<typename T> 93 118 void free_all( std::list<T *> &list ) { 94 std::list<T *>::iterator it;119 typename std::list<T *>::iterator it; 95 120 for ( it = list.begin() ; it != list.end() ; ++it ) { 96 121 delete *it; … … 100 125 101 126 void appendDeclStmt( CompoundStmt * block, Declaration * item ) { 102 block->push_back(new DeclStmt(no _labels, item));103 } 104 105 Expression * nameOf( FunctionDecl * function) {106 return new VariableExpr( function);127 block->push_back(new DeclStmt(noLabels, item)); 128 } 129 130 Expression * nameOf( DeclarationWithType * decl ) { 131 return new VariableExpr( decl ); 107 132 } 108 133 109 134 // ThrowStmt Mutation Helpers 110 135 111 Statement * create_terminate_throw( ThrowStmt *throwStmt ) { 112 // __throw_terminate( EXPR ); 113 ApplicationExpr * call = new ApplicationExpr( /* ... */ ); 114 call->get_args.push_back( throwStmt->get_expr() ); 115 Statement * result = new ExprStmt( throwStmt->get_labels(), call ); 136 Statement * create_given_throw( 137 const char * throwFunc, ThrowStmt * throwStmt ) { 138 // { int NAME = EXPR; throwFunc( &NAME ); } 139 CompoundStmt * result = new CompoundStmt( noLabels ); 140 ObjectDecl * local = new ObjectDecl( 141 "__local_exception_copy", 142 Type::StorageClasses(), 143 LinkageSpec::Cforall, 144 NULL, 145 new BasicType( emptyQualifiers, BasicType::SignedInt ), 146 new SingleInit( throwStmt->get_expr() ) 147 ); 148 appendDeclStmt( result, local ); 149 UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) ); 150 call->get_args().push_back( new AddressExpr( nameOf( local ) ) ); 151 result->push_back( new ExprStmt( throwStmt->get_labels(), call ) ); 116 152 throwStmt->set_expr( nullptr ); 117 153 delete throwStmt; 118 154 return result; 119 155 } 156 157 Statement * create_terminate_throw( ThrowStmt *throwStmt ) { 158 // { int NAME = EXPR; __throw_terminate( &NAME ); } 159 return create_given_throw( "__cfaehm__throw_termination", throwStmt ); 160 } 120 161 Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) { 121 162 // __rethrow_terminate(); 163 assert( nullptr == throwStmt->get_expr() ); 122 164 Statement * result = new ExprStmt( 123 165 throwStmt->get_labels(), 124 new ApplicationExpr( /* ... */ );166 new UntypedExpr( new NameExpr( "__cfaehm__rethrow_termination" ) ) 125 167 ); 126 168 delete throwStmt; … … 129 171 Statement * create_resume_throw( ThrowStmt *throwStmt ) { 130 172 // __throw_resume( EXPR ); 131 ApplicationExpr * call = new ApplicationExpr( /* ... */ ); 132 call->get_args.push_back( throwStmt->get_expr() ); 133 Statement * result = new ExprStmt( throwStmt->get_labels(), call ); 134 throwStmt->set_expr( nullptr ); 135 delete throwStmt; 136 return result; 173 return create_given_throw( "__cfaehm__throw_resumption", throwStmt ); 137 174 } 138 175 Statement * create_resume_rethrow( ThrowStmt *throwStmt ) { … … 140 177 Statement * result = new ReturnStmt( 141 178 throwStmt->get_labels(), 142 new ConstantExpr( 143 Constant( 144 new BasicType( 145 Type::Qualifiers(), 146 BasicType::Bool 147 ), 148 "0") 149 ) 179 new ConstantExpr( Constant::from_bool( false ) ) 150 180 ); 151 181 delete throwStmt; … … 160 190 return block; 161 191 } 162 FunctionDecl * create_try_wrapper( TryStmt *tryStmt ) { 163 CompoundStmt * body = base_try->get_block(); 164 base_try->set_block(nullptr); 165 166 return new FunctionDecl("try", Type::StorageClasses(), 167 LinkageSpec::Cforall, void_func_t, body); 192 FunctionDecl * create_try_wrapper( CompoundStmt *body ) { 193 194 return new FunctionDecl( "try", Type::StorageClasses(), 195 LinkageSpec::Cforall, try_func_t.clone(), body ); 168 196 } 169 197 170 198 FunctionDecl * create_terminate_catch( CatchList &handlers ) { 171 199 std::list<CaseStmt *> handler_wrappers; 200 201 FunctionType *func_type = catch_func_t.clone(); 202 DeclarationWithType * index_obj = func_type->get_parameters().front(); 203 // DeclarationWithType * except_obj = func_type->get_parameters().back(); 172 204 173 205 // Index 1..{number of handlers} … … 178 210 CatchStmt * handler = *it; 179 211 180 std::list<Statement *> core; 181 if ( /*the exception is named*/ ) { 182 ObjectDecl * local_except = /* Dynamic case, same */; 183 core->push_back( new DeclStmt( noLabel, local_except ) ); 184 } 185 // Append the provided statement to the handler. 186 core->push_back( cur_handler->get_body() ); 187 // Append return onto the inner block? case stmt list? 188 CaseStmt * wrapper = new CaseStmt( 212 // INTEGERconstant Version 213 // case `index`: 214 // { 215 // `handler.body` 216 // } 217 // return; 218 std::list<Statement *> caseBody; 219 caseBody.push_back( handler->get_body() ); 220 handler->set_body( nullptr ); 221 caseBody.push_back( new ReturnStmt( noLabels, nullptr ) ); 222 223 handler_wrappers.push_back( new CaseStmt( 189 224 noLabels, 190 225 new ConstantExpr( Constant::from_int( index ) ), 191 core 192 ); 193 handler_wrappers.push_back(wrapper); 226 caseBody 227 ) ); 194 228 } 195 229 // TODO: Some sort of meaningful error on default perhaps? 230 231 std::list<Statement*> stmt_handlers; 232 while ( !handler_wrappers.empty() ) { 233 stmt_handlers.push_back( handler_wrappers.front() ); 234 handler_wrappers.pop_front(); 235 } 196 236 197 237 SwitchStmt * handler_lookup = new SwitchStmt( 198 238 noLabels, 199 /*parameter 0: index*/, 200 handler_wrappers, 201 false 239 nameOf( index_obj ), 240 stmt_handlers 202 241 ); 203 242 CompoundStmt * body = new CompoundStmt( noLabels ); … … 205 244 206 245 return new FunctionDecl("catch", Type::StorageClasses(), 207 LinkageSpec::Cforall, catch_func_t, body);246 LinkageSpec::Cforall, func_type, body); 208 247 } 209 248 210 249 // Create a single check from a moddified handler. 211 CompoundStmt *create_single_matcher( CatchStmt * modded_handler ) { 212 CompoundStmt * block = new CompoundStmt( noLables ); 213 214 appendDeclStmt( block, modded_handler->get_decl() ); 215 216 // TODO: This is not the actual check. 217 LogicalExpr * cond = new ConstantExpr( Constant::from_bool( false ) ); 250 // except_obj is referenced, modded_handler will be freed. 251 CompoundStmt *create_single_matcher( 252 DeclarationWithType * except_obj, CatchStmt * modded_handler ) { 253 CompoundStmt * block = new CompoundStmt( noLabels ); 254 255 // INTEGERconstant Version 256 assert( nullptr == modded_handler->get_decl() ); 257 ConstantExpr * number = 258 dynamic_cast<ConstantExpr*>( modded_handler->get_cond() ); 259 assert( number ); 260 modded_handler->set_cond( nullptr ); 261 262 Expression * cond; 263 { 264 std::list<Expression *> args; 265 args.push_back( number ); 266 267 std::list<Expression *> rhs_args; 268 rhs_args.push_back( nameOf( except_obj ) ); 269 Expression * rhs = new UntypedExpr( 270 new NameExpr( "*?" ), rhs_args ); 271 args.push_back( rhs ); 272 273 cond = new UntypedExpr( new NameExpr( "?==?" /*???*/), args ); 274 } 218 275 219 276 if ( modded_handler->get_cond() ) { 220 cond = new LogicalExpr( cond, modded_handler->get_cond() ) q277 cond = new LogicalExpr( cond, modded_handler->get_cond() ); 221 278 } 222 279 block->push_back( new IfStmt( noLabels, 223 cond, modded_handler->get_body() );280 cond, modded_handler->get_body(), nullptr ) ); 224 281 225 282 modded_handler->set_decl( nullptr ); … … 232 289 FunctionDecl * create_terminate_match( CatchList &handlers ) { 233 290 CompoundStmt * body = new CompoundStmt( noLabels ); 291 292 FunctionType * func_type = match_func_t.clone(); 293 DeclarationWithType * except_obj = func_type->get_parameters().back(); 234 294 235 295 // Index 1..{number of handlers} … … 240 300 CatchStmt * handler = *it; 241 301 242 // body should have been taken by create_terminate_catch. 243 // assert( nullptr == handler->get_body() ); 302 // Body should have been taken by create_terminate_catch. 303 assert( nullptr == handler->get_body() ); 304 305 // Create new body. 244 306 handler->set_body( new ReturnStmt( noLabels, 245 307 new ConstantExpr( Constant::from_int( index ) ) ) ); 246 308 247 body->push_back( create_single_matcher( handler ) ); 248 } 309 // Create the handler. 310 body->push_back( create_single_matcher( except_obj, handler ) ); 311 *it = nullptr; 312 } 313 314 body->push_back( new ReturnStmt( noLabels, new ConstantExpr( 315 Constant::from_int( 0 ) ) ) ); 249 316 250 317 return new FunctionDecl("match", Type::StorageClasses(), 251 LinkageSpec::Cforall, match_func_t, body);252 } 253 254 Statement * create_terminate_caller(318 LinkageSpec::Cforall, func_type, body); 319 } 320 321 CompoundStmt * create_terminate_caller( 255 322 FunctionDecl * try_wrapper, 256 323 FunctionDecl * terminate_catch, 257 324 FunctionDecl * terminate_match) { 258 325 259 ApplicationExpr * caller = new ApplicationExpr( /* ... */ ); 260 std::list<Expression *>& args = caller.get_args(); 326 UntypedExpr * caller = new UntypedExpr( new NameExpr( 327 "__cfaehm__try_terminate" ) ); 328 std::list<Expression *>& args = caller->get_args(); 261 329 args.push_back( nameOf( try_wrapper ) ); 262 330 args.push_back( nameOf( terminate_catch ) ); 263 331 args.push_back( nameOf( terminate_match ) ); 264 332 265 return new ExprStmt( noLabels, caller ); 333 CompoundStmt * callStmt = new CompoundStmt( noLabels ); 334 callStmt->push_back( new ExprStmt( noLabels, caller ) ); 335 return callStmt; 266 336 } 267 337 268 338 FunctionDecl * create_resume_handler( CatchList &handlers ) { 269 CompoundStmt * body = new CompountStmt( noLabels ); 339 CompoundStmt * body = new CompoundStmt( noLabels ); 340 341 FunctionType * func_type = match_func_t.clone(); 342 DeclarationWithType * except_obj = func_type->get_parameters().back(); 270 343 271 344 CatchList::iterator it; … … 280 353 handling_code->push_back( handler->get_body() ); 281 354 } 282 handling_code->push_back( new ReturnStmt( noLabel ,355 handling_code->push_back( new ReturnStmt( noLabels, 283 356 new ConstantExpr( Constant::from_bool( false ) ) ) ); 284 357 handler->set_body( handling_code ); 285 358 286 359 // Create the handler. 287 body->push_back( create_single_matcher( handler ) ); 360 body->push_back( create_single_matcher( except_obj, handler ) ); 361 *it = nullptr; 288 362 } 289 363 290 364 return new FunctionDecl("handle", Type::StorageClasses(), 291 LinkageSpec::Cforall, handle_func_t, body); 292 } 293 294 Statement * create_resume_wrapper( 365 LinkageSpec::Cforall, func_type, body); 366 } 367 368 CompoundStmt * create_resume_wrapper( 369 StructDecl * node_decl, 295 370 Statement * wraps, 296 371 FunctionDecl * resume_handler ) { 297 372 CompoundStmt * body = new CompoundStmt( noLabels ); 298 373 299 // struct node = {current top resume handler, call to resume_handler}; 300 // __attribute__((cleanup( ... ))); 301 // set top resume handler to node. 302 // The wrapped statement. 303 304 ListInit * node_init; 305 { 306 std::list<Initializer*> field_inits; 307 field_inits.push_back( new SingleInit( /* ... */ ) ); 308 field_inits.push_back( new SingleInit( nameOf( resume_handler ) ) ); 309 node_init = new ListInit( field_inits ); 310 } 374 // struct __try_resume_node __resume_node 375 // __attribute__((cleanup( __cfaehm__try_resume_cleanup ))); 376 // ** unwinding of the stack here could cause problems ** 377 // ** however I don't think that can happen currently ** 378 // __cfaehm__try_resume_setup( &__resume_node, resume_handler ); 311 379 312 380 std::list< Attribute * > attributes; 313 381 { 314 382 std::list< Expression * > attr_params; 315 attr_params.push_back( n ameOf( /* ... deconstructor ... */ ) );316 attrributes.push_back( new Attribute( "cleanup", attr_params) );317 }318 319 appendDeclStmt( body, 320 /**/ObjectDecl(321 " resume_node",383 attr_params.push_back( new NameExpr( 384 "__cfaehm__try_resume_cleanup" ) ); 385 attributes.push_back( new Attribute( "cleanup", attr_params ) ); 386 } 387 388 ObjectDecl * obj = new ObjectDecl( 389 "__resume_node", 322 390 Type::StorageClasses(), 323 391 LinkageSpec::Cforall, 324 392 nullptr, 325 /* Type* = resume_node */, 326 node_init, 393 new StructInstType( 394 Type::Qualifiers(), 395 node_decl 396 ), 397 nullptr, 327 398 attributes 328 ) 329 ); 399 ); 400 appendDeclStmt( body, obj ); 401 402 UntypedExpr *setup = new UntypedExpr( new NameExpr( 403 "__cfaehm__try_resume_setup" ) ); 404 setup->get_args().push_back( new AddressExpr( nameOf( obj ) ) ); 405 setup->get_args().push_back( nameOf( resume_handler ) ); 406 407 body->push_back( new ExprStmt( noLabels, setup ) ); 408 330 409 body->push_back( wraps ); 331 410 return body; … … 333 412 334 413 FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) { 335 CompoundStmt * body = tryStmt->get_finally(); 414 FinallyStmt * finally = tryStmt->get_finally(); 415 CompoundStmt * body = finally->get_block(); 416 finally->set_block( nullptr ); 417 delete finally; 336 418 tryStmt->set_finally( nullptr ); 337 419 338 420 return new FunctionDecl("finally", Type::StorageClasses(), 339 LinkageSpec::Cforall, void_func_t, body); 340 } 341 342 ObjectDecl * create_finally_hook( FunctionDecl * finally_wrapper ) { 343 // struct _cleanup_hook NAME __attribute__((cleanup( ... ))); 421 LinkageSpec::Cforall, finally_func_t.clone(), body); 422 } 423 424 ObjectDecl * create_finally_hook( 425 StructDecl * hook_decl, FunctionDecl * finally_wrapper ) { 426 // struct __cfaehm__cleanup_hook __finally_hook 427 // __attribute__((cleanup( finally_wrapper ))); 344 428 345 429 // Make Cleanup Attribute. … … 348 432 std::list< Expression * > attr_params; 349 433 attr_params.push_back( nameOf( finally_wrapper ) ); 350 attr ributes.push_back( new Attribute( "cleanup", attr_params ) );351 } 352 353 return ObjectDecl( /* ... */354 const std::string &name "finally_hook",434 attributes.push_back( new Attribute( "cleanup", attr_params ) ); 435 } 436 437 return new ObjectDecl( 438 "__finally_hook", 355 439 Type::StorageClasses(), 356 440 LinkageSpec::Cforall, 357 441 nullptr, 358 /* ... Type * ... */, 442 new StructInstType( 443 emptyQualifiers, 444 hook_decl 445 ), 359 446 nullptr, 360 447 attributes … … 363 450 364 451 365 class ExceptionMutatorCore : public With Scoping{452 class ExceptionMutatorCore : public WithGuards { 366 453 enum Context { NoHandler, TerHandler, ResHandler }; 367 454 … … 370 457 // loop, switch or the goto stays within the function. 371 458 372 Context cur Context;459 Context cur_context; 373 460 374 461 // We might not need this, but a unique base for each try block's … … 377 464 //unsigned int try_count = 0; 378 465 466 StructDecl *node_decl; 467 StructDecl *hook_decl; 379 468 380 469 public: 381 470 ExceptionMutatorCore() : 382 curContext(NoHandler) 471 cur_context(NoHandler), 472 node_decl(nullptr), hook_decl(nullptr) 383 473 {} 384 474 385 void premutate( CatchStmt *tryStmt ); 475 void premutate( CatchStmt *catchStmt ); 476 void premutate( StructDecl *structDecl ); 386 477 Statement * postmutate( ThrowStmt *throwStmt ); 387 478 Statement * postmutate( TryStmt *tryStmt ); … … 393 484 if ( throwStmt->get_expr() ) { 394 485 return create_terminate_throw( throwStmt ); 395 } else if ( TerHandler == cur Context ) {486 } else if ( TerHandler == cur_context ) { 396 487 return create_terminate_rethrow( throwStmt ); 397 488 } else { 398 489 assertf(false, "Invalid throw in %s at %i\n", 399 throwStmt->location.filename ,490 throwStmt->location.filename.c_str(), 400 491 throwStmt->location.linenumber); 401 492 return nullptr; … … 404 495 if ( throwStmt->get_expr() ) { 405 496 return create_resume_throw( throwStmt ); 406 } else if ( ResHandler == cur Context ) {497 } else if ( ResHandler == cur_context ) { 407 498 return create_resume_rethrow( throwStmt ); 408 499 } else { 409 500 assertf(false, "Invalid throwResume in %s at %i\n", 410 throwStmt->location.filename ,501 throwStmt->location.filename.c_str(), 411 502 throwStmt->location.linenumber); 412 503 return nullptr; … … 416 507 417 508 Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) { 509 assert( node_decl ); 510 assert( hook_decl ); 511 418 512 // Generate a prefix for the function names? 419 513 420 CompoundStmt * block = new CompoundStmt( );421 Statement * inner = take_try_block( tryStmt );514 CompoundStmt * block = new CompoundStmt( noLabels ); 515 CompoundStmt * inner = take_try_block( tryStmt ); 422 516 423 517 if ( tryStmt->get_finally() ) { … … 427 521 appendDeclStmt( block, finally_block ); 428 522 // Create and add the finally cleanup hook. 429 appendDeclStmt( block, create_finally_hook( finally_block ) ); 430 } 431 432 StatementList termination_handlers; 433 StatementList resumption_handlers; 434 split( tryStmt->get_handlers(), 435 termination_handlers, resumption_handlers ); 436 437 if ( resumeption_handlers.size() ) { 523 appendDeclStmt( block, 524 create_finally_hook( hook_decl, finally_block ) ); 525 } 526 527 CatchList termination_handlers; 528 CatchList resumption_handlers; 529 split( tryStmt->get_catchers(), 530 termination_handlers, resumption_handlers ); 531 532 if ( resumption_handlers.size() ) { 438 533 // Define the helper function. 439 534 FunctionDecl * resume_handler = … … 441 536 appendDeclStmt( block, resume_handler ); 442 537 // Prepare hooks 443 inner = create_resume_wrapper( inner, resume_handler );538 inner = create_resume_wrapper( node_decl, inner, resume_handler ); 444 539 } 445 540 … … 462 557 block->push_back( inner ); 463 558 464 free_all( termination_handlers );465 free_all( resumption_handlers );559 //free_all( termination_handlers ); 560 //free_all( resumption_handlers ); 466 561 467 562 return block; … … 469 564 470 565 void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) { 471 GuardValue( cur Context );472 if ( CatchStmt::Terminat ion== catchStmt->get_kind() ) {473 cur Context = TerHandler;566 GuardValue( cur_context ); 567 if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 568 cur_context = TerHandler; 474 569 } else { 475 curContext = ResHandler; 476 } 477 } 478 479 void translateEHM( std::list< Declaration *> & translationUnit ) { 570 cur_context = ResHandler; 571 } 572 } 573 574 void ExceptionMutatorCore::premutate( StructDecl *structDecl ) { 575 if ( !structDecl->has_body() ) { 576 // Skip children? 577 return; 578 } else if ( structDecl->get_name() == "__cfaehm__try_resume_node" ) { 579 assert( nullptr == node_decl ); 580 node_decl = structDecl; 581 } else if ( structDecl->get_name() == "__cfaehm__cleanup_hook" ) { 582 assert( nullptr == hook_decl ); 583 hook_decl = structDecl; 584 } 585 // Later we might get the exception type as well. 586 } 587 588 void translateEHM( std::list< Declaration *> & translationUnit ) { 589 init_func_types(); 590 480 591 PassVisitor<ExceptionMutatorCore> translator; 481 592 for ( Declaration * decl : translationUnit ) { 482 decl-> mutate( translator );593 decl->acceptMutator( translator ); 483 594 } 484 595 } -
src/ControlStruct/ExceptTranslate.h
r11dbfe1 r67fa9f9 10 10 // Created On : Tus Jun 06 10:13:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Jun 22 15:57:00 201713 // Update Count : 012 // Last Modified On : Fri Jun 30 10:20:00 2017 13 // Update Count : 2 14 14 // 15 15 … … 17 17 #define EXCEPT_TRANSLATE_H 18 18 19 namespace ControlFlow { 19 #include <list> 20 #include "SynTree/SynTree.h" 21 22 namespace ControlStruct { 20 23 void translateEHM( std::list< Declaration *> & translationUnit ); 21 24 /* Converts exception handling structures into their underlying C code. -
src/ControlStruct/module.mk
r11dbfe1 r67fa9f9 10 10 ## Author : Richard C. Bilson 11 11 ## Created On : Mon Jun 1 17:49:17 2015 12 ## Last Modified By : Peter A. Buhr13 ## Last Modified On : Thu Aug 4 11:38:06 201614 ## Update Count : 312 ## Last Modified By : Andrew Beach 13 ## Last Modified On : Wed Jun 28 16:15:00 2017 14 ## Update Count : 4 15 15 ############################################################################### 16 16 17 17 SRC += ControlStruct/LabelGenerator.cc \ 18 18 ControlStruct/LabelFixer.cc \ 19 19 ControlStruct/MLEMutator.cc \ 20 20 ControlStruct/Mutate.cc \ 21 ControlStruct/ForExprMutator.cc 22 21 ControlStruct/ForExprMutator.cc \ 22 ControlStruct/ExceptTranslate.cc -
src/GenPoly/Box.cc
r11dbfe1 r67fa9f9 504 504 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 505 505 if ( functionDecl->get_statements() ) { // empty routine body ? 506 // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl; 506 507 doBeginScope(); 507 508 scopeTyVars.beginScope(); … … 548 549 retval = oldRetval; 549 550 doEndScope(); 551 // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl; 550 552 } // if 551 553 return functionDecl; … … 1116 1118 1117 1119 Expression *Pass1::mutate( ApplicationExpr *appExpr ) { 1118 // std::cerr << "mutate appExpr: " ;1120 // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl; 1119 1121 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { 1120 1122 // std::cerr << i->first << " "; … … 1141 1143 ReferenceToType *dynRetType = isDynRet( function, exprTyVars ); 1142 1144 1145 // std::cerr << function << std::endl; 1146 // std::cerr << "scopeTyVars: "; 1147 // printTyVarMap( std::cerr, scopeTyVars ); 1148 // std::cerr << "exprTyVars: "; 1149 // printTyVarMap( std::cerr, exprTyVars ); 1150 // std::cerr << "env: " << *env << std::endl; 1151 // std::cerr << needsAdapter( function, scopeTyVars ) << ! needsAdapter( function, exprTyVars) << std::endl; 1152 1143 1153 // NOTE: addDynRetParam needs to know the actual (generated) return type so it can make a temp variable, so pass the result type from the appExpr 1144 1154 // passTypeVars needs to know the program-text return type (i.e. the distinction between _conc_T30 and T3(int)) 1145 1155 // concRetType may not be a good name in one or both of these places. A more appropriate name change is welcome. 1146 1156 if ( dynRetType ) { 1157 // std::cerr << "dynRetType: " << dynRetType << std::endl; 1147 1158 Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result(); 1148 1159 ret = addDynRetParam( appExpr, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType -
src/GenPoly/InstantiateGeneric.cc
r11dbfe1 r67fa9f9 22 22 #include "InstantiateGeneric.h" 23 23 24 #include "DeclMutator.h"25 24 #include "GenPoly.h" 26 25 #include "ScopedSet.h" 27 26 #include "ScrubTyVars.h" 28 #include "PolyMutator.h" 27 28 #include "Common/PassVisitor.h" 29 #include "Common/ScopedMap.h" 30 #include "Common/UniqueName.h" 31 #include "Common/utility.h" 29 32 30 33 #include "ResolvExpr/typeops.h" … … 34 37 #include "SynTree/Type.h" 35 38 36 #include "Common/ScopedMap.h" 37 #include " Common/UniqueName.h"38 #include "Common/utility.h" 39 40 #include "InitTweak/InitTweak.h" 41 39 42 40 43 namespace GenPoly { … … 153 156 } 154 157 155 // collect the environments of each TypeInstType so that type variables can be replaced156 // xxx - possibly temporary solution. Access to type environments is required in GenericInstantiator, but it needs to be a DeclMutator which does not provide easy access to the type environments.157 class EnvFinder final : public GenPoly::PolyMutator {158 public:159 using GenPoly::PolyMutator::mutate;160 virtual Type * mutate( TypeInstType * inst ) override {161 if ( env ) envMap[inst] = env;162 return inst;163 }164 165 // don't want to associate an environment with TypeInstTypes that occur in function types - this may actually only apply to function types belonging to DeclarationWithTypes (or even just FunctionDecl)?166 virtual Type * mutate( FunctionType * ftype ) override {167 return ftype;168 }169 std::unordered_map< ReferenceToType *, TypeSubstitution * > envMap;170 };171 172 158 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 173 class GenericInstantiator final : public DeclMutator{159 struct GenericInstantiator final : public WithTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards { 174 160 /// Map of (generic type, parameter list) pairs to concrete type instantiations 175 161 InstantiationMap< AggregateDecl, AggregateDecl > instantiations; … … 178 164 /// Namer for concrete types 179 165 UniqueName typeNamer; 180 /// Reference to mapping of environments 181 const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap; 182 public: 183 GenericInstantiator( const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_"), envMap( envMap ) {} 184 185 using DeclMutator::mutate; 186 virtual Type* mutate( StructInstType *inst ) override; 187 virtual Type* mutate( UnionInstType *inst ) override; 188 189 virtual void doBeginScope() override; 190 virtual void doEndScope() override; 166 /// Should not make use of type environment to replace types of function parameter and return values. 167 bool inFunctionType = false; 168 GenericInstantiator() : instantiations(), dtypeStatics(), typeNamer("_conc_") {} 169 170 Type* postmutate( StructInstType *inst ); 171 Type* postmutate( UnionInstType *inst ); 172 173 void premutate( FunctionType * ftype ) { 174 GuardValue( inFunctionType ); 175 inFunctionType = true; 176 } 177 178 void beginScope(); 179 void endScope(); 191 180 private: 192 181 /// Wrap instantiation lookup for structs … … 207 196 208 197 void instantiateGeneric( std::list< Declaration* > &translationUnit ) { 209 EnvFinder finder; 210 mutateAll( translationUnit, finder ); 211 GenericInstantiator instantiator( finder.envMap ); 212 instantiator.mutateDeclarationList( translationUnit ); 198 PassVisitor<GenericInstantiator> instantiator; 199 mutateAll( translationUnit, instantiator ); 213 200 } 214 201 … … 306 293 Type *GenericInstantiator::replaceWithConcrete( Type *type, bool doClone ) { 307 294 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 308 if ( envMap.count( typeInst ) ) { 309 TypeSubstitution * env = envMap.at( typeInst ); 295 if ( env && ! inFunctionType ) { 310 296 Type *concrete = env->lookup( typeInst->get_name() ); 311 297 if ( concrete ) { … … 331 317 332 318 333 Type* GenericInstantiator::mutate( StructInstType *inst ) { 334 // mutate subtypes 335 Type *mutated = Mutator::mutate( inst ); 336 inst = dynamic_cast< StructInstType* >( mutated ); 337 if ( ! inst ) return mutated; 338 319 Type* GenericInstantiator::postmutate( StructInstType *inst ) { 339 320 // exit early if no need for further mutation 340 321 if ( inst->get_parameters().empty() ) return inst; … … 368 349 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 369 350 insert( inst, typeSubs, concDecl ); // must insert before recursion 370 concDecl->acceptMutator( * this); // recursively instantiate members371 DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first351 concDecl->acceptMutator( *visitor ); // recursively instantiate members 352 declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first 372 353 } 373 354 StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() ); … … 388 369 } 389 370 390 Type* GenericInstantiator::mutate( UnionInstType *inst ) { 391 // mutate subtypes 392 Type *mutated = Mutator::mutate( inst ); 393 inst = dynamic_cast< UnionInstType* >( mutated ); 394 if ( ! inst ) return mutated; 395 371 Type* GenericInstantiator::postmutate( UnionInstType *inst ) { 396 372 // exit early if no need for further mutation 397 373 if ( inst->get_parameters().empty() ) return inst; … … 423 399 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 424 400 insert( inst, typeSubs, concDecl ); // must insert before recursion 425 concDecl->acceptMutator( * this); // recursively instantiate members426 DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first401 concDecl->acceptMutator( *visitor ); // recursively instantiate members 402 declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first 427 403 } 428 404 UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() ); … … 442 418 } 443 419 444 void GenericInstantiator::doBeginScope() { 445 DeclMutator::doBeginScope(); 420 void GenericInstantiator::beginScope() { 446 421 instantiations.beginScope(); 447 422 dtypeStatics.beginScope(); 448 423 } 449 424 450 void GenericInstantiator::doEndScope() { 451 DeclMutator::doEndScope(); 425 void GenericInstantiator::endScope() { 452 426 instantiations.endScope(); 453 427 dtypeStatics.endScope(); -
src/InitTweak/FixInit.cc
r11dbfe1 r67fa9f9 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/GenInit.cc
r11dbfe1 r67fa9f9 44 44 } 45 45 46 class ReturnFixer : public WithStmtsToAdd, public WithScopes { 47 public: 46 struct ReturnFixer : public WithStmtsToAdd, public WithGuards { 48 47 /// consistently allocates a temporary variable for the return value 49 48 /// of a function so that anything which the resolver decides can be constructed … … 59 58 }; 60 59 61 class CtorDtor final : public GenPoly::PolyMutator { 62 public: 63 typedef GenPoly::PolyMutator Parent; 64 using Parent::mutate; 60 struct CtorDtor : public WithGuards, public WithShortCircuiting { 65 61 /// create constructor and destructor statements for object declarations. 66 62 /// the actual call statements will be added in after the resolver has run … … 69 65 static void generateCtorDtor( std::list< Declaration * > &translationUnit ); 70 66 71 virtual DeclarationWithType * mutate( ObjectDecl * ) override; 72 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override; 67 void previsit( ObjectDecl * ); 68 void previsit( FunctionDecl *functionDecl ); 69 73 70 // should not traverse into any of these declarations to find objects 74 71 // that need to be constructed or destructed 75 v irtual Declaration* mutate( StructDecl *aggregateDecl ) override;76 v irtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; }77 v irtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; }78 v irtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; }79 v irtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; }80 v irtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; }81 82 v irtual Type * mutate( FunctionType *funcType ) override { return funcType; }83 84 v irtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override;72 void previsit( StructDecl *aggregateDecl ); 73 void previsit( UnionDecl *aggregateDecl ) { visit_children = false; } 74 void previsit( EnumDecl *aggregateDecl ) { visit_children = false; } 75 void previsit( TraitDecl *aggregateDecl ) { visit_children = false; } 76 void previsit( TypeDecl *typeDecl ) { visit_children = false; } 77 void previsit( TypedefDecl *typeDecl ) { visit_children = false; } 78 79 void previsit( FunctionType *funcType ) { visit_children = false; } 80 81 void previsit( CompoundStmt * compoundStmt ); 85 82 86 83 private: … … 211 208 212 209 void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) { 213 CtorDtorctordtor;214 mutateAll( translationUnit, ctordtor );210 PassVisitor<CtorDtor> ctordtor; 211 acceptAll( translationUnit, ctordtor ); 215 212 } 216 213 … … 289 286 } 290 287 291 DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {288 void CtorDtor::previsit( ObjectDecl * objDecl ) { 292 289 handleDWT( objDecl ); 293 290 // hands off if @=, extern, builtin, etc. … … 301 298 objDecl->set_init( genCtorInit( objDecl ) ); 302 299 } 303 return Parent::mutate( objDecl ); 304 } 305 306 DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) { 307 ValueGuard< bool > oldInFunc = inFunction; 300 } 301 302 void CtorDtor::previsit( FunctionDecl *functionDecl ) { 303 GuardValue( inFunction ); 308 304 inFunction = true; 309 305 310 306 handleDWT( functionDecl ); 311 307 312 managedTypes.beginScope();308 GuardScope( managedTypes ); 313 309 // go through assertions and recursively add seen ctor/dtors 314 310 for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) { … … 317 313 } 318 314 } 319 // parameters should not be constructed and destructed, so don't mutate FunctionType 320 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) ); 321 322 managedTypes.endScope(); 323 return functionDecl; 324 } 325 326 Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) { 315 316 PassVisitor<CtorDtor> newCtorDtor; 317 newCtorDtor.pass = *this; 318 maybeAccept( functionDecl->get_statements(), newCtorDtor ); 319 visit_children = false; // do not try and construct parameters or forall parameters - must happen after maybeAccept 320 } 321 322 void CtorDtor::previsit( StructDecl *aggregateDecl ) { 323 visit_children = false; // do not try to construct and destruct aggregate members 324 327 325 // don't construct members, but need to take note if there is a managed member, 328 326 // because that means that this type is also managed … … 336 334 } 337 335 } 338 return aggregateDecl; 339 } 340 341 CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) { 342 managedTypes.beginScope(); 343 CompoundStmt * stmt = Parent::mutate( compoundStmt ); 344 managedTypes.endScope(); 345 return stmt; 346 } 347 336 } 337 338 void CtorDtor::previsit( CompoundStmt * compoundStmt ) { 339 GuardScope( managedTypes ); 340 } 348 341 } // namespace InitTweak 349 342 -
src/InitTweak/InitTweak.cc
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 119 119 ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT) \ 120 120 ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT) \ 121 ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT) \ 121 122 GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \ 122 123 GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \ … … 161 162 ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) \ 162 163 ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \ 164 ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) \ 163 165 SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \ 164 166 SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \ … … 394 396 ControlStruct/LabelGenerator.cc ControlStruct/LabelFixer.cc \ 395 397 ControlStruct/MLEMutator.cc ControlStruct/Mutate.cc \ 396 ControlStruct/ForExprMutator.cc GenPoly/Box.cc \ 398 ControlStruct/ForExprMutator.cc \ 399 ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \ 397 400 GenPoly/GenPoly.cc GenPoly/PolyMutator.cc \ 398 401 GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \ … … 414 417 ResolvExpr/RenameVars.cc ResolvExpr/FindOpenVars.cc \ 415 418 ResolvExpr/PolyCost.cc ResolvExpr/Occurs.cc \ 416 ResolvExpr/TypeEnvironment.cc SymTab/Indexer.cc \417 SymTab/ Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \418 SymTab/ ImplementationType.cc SymTab/TypeEquality.cc \419 SymTab/ Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \420 SynTree/ BasicType.cc SynTree/PointerType.cc \421 SynTree/ ArrayType.cc SynTree/FunctionType.cc \422 SynTree/ ReferenceToType.cc SynTree/TupleType.cc \423 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 \ 424 427 SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \ 425 428 SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \ … … 592 595 ControlStruct/$(DEPDIR)/$(am__dirstamp) 593 596 ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT): \ 597 ControlStruct/$(am__dirstamp) \ 598 ControlStruct/$(DEPDIR)/$(am__dirstamp) 599 ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT): \ 594 600 ControlStruct/$(am__dirstamp) \ 595 601 ControlStruct/$(DEPDIR)/$(am__dirstamp) … … 721 727 ResolvExpr/$(am__dirstamp) \ 722 728 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 729 ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT): \ 730 ResolvExpr/$(am__dirstamp) \ 731 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 723 732 SymTab/$(am__dirstamp): 724 733 @$(MKDIR_P) SymTab … … 853 862 -rm -f Common/driver_cfa_cpp-UniqueName.$(OBJEXT) 854 863 -rm -f Concurrency/driver_cfa_cpp-Keywords.$(OBJEXT) 864 -rm -f ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT) 855 865 -rm -f ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT) 856 866 -rm -f ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT) … … 890 900 -rm -f ResolvExpr/driver_cfa_cpp-CommonType.$(OBJEXT) 891 901 -rm -f ResolvExpr/driver_cfa_cpp-ConversionCost.$(OBJEXT) 902 -rm -f ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) 892 903 -rm -f ResolvExpr/driver_cfa_cpp-FindOpenVars.$(OBJEXT) 893 904 -rm -f ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) … … 965 976 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Po@am__quote@ 966 977 @AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Po@am__quote@ 978 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po@am__quote@ 967 979 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Po@am__quote@ 968 980 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po@am__quote@ … … 1002 1014 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Po@am__quote@ 1003 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@ 1004 1017 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po@am__quote@ 1005 1018 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po@am__quote@ … … 1355 1368 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.obj `if test -f 'ControlStruct/ForExprMutator.cc'; then $(CYGPATH_W) 'ControlStruct/ForExprMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ForExprMutator.cc'; fi` 1356 1369 1370 ControlStruct/driver_cfa_cpp-ExceptTranslate.o: ControlStruct/ExceptTranslate.cc 1371 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ExceptTranslate.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.o `test -f 'ControlStruct/ExceptTranslate.cc' || echo '$(srcdir)/'`ControlStruct/ExceptTranslate.cc 1372 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po 1373 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/ExceptTranslate.cc' object='ControlStruct/driver_cfa_cpp-ExceptTranslate.o' libtool=no @AMDEPBACKSLASH@ 1374 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1375 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.o `test -f 'ControlStruct/ExceptTranslate.cc' || echo '$(srcdir)/'`ControlStruct/ExceptTranslate.cc 1376 1377 ControlStruct/driver_cfa_cpp-ExceptTranslate.obj: ControlStruct/ExceptTranslate.cc 1378 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ExceptTranslate.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.obj `if test -f 'ControlStruct/ExceptTranslate.cc'; then $(CYGPATH_W) 'ControlStruct/ExceptTranslate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ExceptTranslate.cc'; fi` 1379 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po 1380 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ControlStruct/ExceptTranslate.cc' object='ControlStruct/driver_cfa_cpp-ExceptTranslate.obj' libtool=no @AMDEPBACKSLASH@ 1381 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1382 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.obj `if test -f 'ControlStruct/ExceptTranslate.cc'; then $(CYGPATH_W) 'ControlStruct/ExceptTranslate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ExceptTranslate.cc'; fi` 1383 1357 1384 GenPoly/driver_cfa_cpp-Box.o: GenPoly/Box.cc 1358 1385 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Box.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo -c -o GenPoly/driver_cfa_cpp-Box.o `test -f 'GenPoly/Box.cc' || echo '$(srcdir)/'`GenPoly/Box.cc … … 1942 1969 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1943 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` 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` 1944 1985 1945 1986 SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc -
src/Parser/InitializerNode.cc
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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/Parser/parser.yy
r11dbfe1 r67fa9f9 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Jun 28 22:11:22201713 // Update Count : 241 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jun 30 15:38:00 2017 13 // Update Count : 2415 14 14 // 15 15 … … 104 104 std::string * str; 105 105 bool flag; 106 CatchStmt::Kind catch_kind; 106 107 } 107 108 … … 192 193 %type<sn> switch_clause_list_opt switch_clause_list choose_clause_list_opt choose_clause_list 193 194 %type<sn> /* handler_list */ handler_clause finally_clause 195 %type<catch_kind> handler_key 194 196 195 197 // declarations … … 958 960 handler_clause: 959 961 // TEMPORARY, TEST EXCEPTIONS 960 CATCH '(' push push INTEGERconstant pop ')' compound_statement pop 961 { $$ = new StatementNode( build_catch( CatchStmt::Terminate, nullptr, new ExpressionNode( build_constantInteger( *$5 ) ), $8 ) ); } 962 | handler_clause CATCH '(' push push INTEGERconstant pop ')' compound_statement pop 963 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( CatchStmt::Terminate, nullptr, new ExpressionNode( build_constantInteger( *$6 ) ), $9 ) ) ); } 964 965 | CATCH '(' push push exception_declaration pop ')' compound_statement pop 966 { $$ = new StatementNode( build_catch( CatchStmt::Terminate, $5, nullptr, $8 ) ); } 967 | handler_clause CATCH '(' push push exception_declaration pop ')' compound_statement pop 968 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( CatchStmt::Terminate, $6, nullptr, $9 ) ) ); } 969 | CATCHRESUME '(' push push exception_declaration pop ')' compound_statement pop 970 { $$ = new StatementNode( build_catch( CatchStmt::Resume, $5, nullptr, $8 ) ); } 971 | handler_clause CATCHRESUME '(' push push exception_declaration pop ')' compound_statement pop 972 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( CatchStmt::Resume, $6, nullptr, $9 ) ) ); } 962 handler_key '(' push push INTEGERconstant pop ')' compound_statement pop 963 { $$ = new StatementNode( build_catch( $1, nullptr, new ExpressionNode( build_constantInteger( *$5 ) ), $8 ) ); } 964 | handler_clause handler_key '(' push push INTEGERconstant pop ')' compound_statement pop 965 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, nullptr, new ExpressionNode( build_constantInteger( *$6 ) ), $9 ) ) ); } 966 967 | handler_key '(' push push exception_declaration pop ')' compound_statement pop 968 { $$ = new StatementNode( build_catch( $1, $5, nullptr, $8 ) ); } 969 | handler_clause handler_key '(' push push exception_declaration pop ')' compound_statement pop 970 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $6, nullptr, $9 ) ) ); } 971 ; 972 973 handler_key: 974 CATCH 975 { $$ = CatchStmt::Terminate; } 976 | CATCHRESUME 977 { $$ = CatchStmt::Resume; } 973 978 ; 974 979 -
src/ResolvExpr/AlternativeFinder.cc
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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 } … … 64 70 virtual void visit( BranchStmt *branchStmt ) override; 65 71 virtual void visit( ReturnStmt *returnStmt ) override; 72 virtual void visit( ThrowStmt *throwStmt ) override; 66 73 67 74 virtual void visit( SingleInit *singleInit ) override; … … 79 86 80 87 Type * functionReturn = nullptr; 81 Type *initContext = nullptr;88 CurrentObject currentObject = nullptr; 82 89 bool inEnumDecl = false; 83 90 }; … … 186 193 // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting 187 194 // the RHS. 188 Type *temp = initContext;189 initContext = new_type;190 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext) ) {195 ValueGuard<CurrentObject> temp( currentObject ); 196 currentObject = CurrentObject( objectDecl->get_type() ); 197 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) { 191 198 // enumerator initializers should not use the enum type to initialize, since 192 199 // the enum type is still incomplete at this point. Use signed int instead. 193 initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt);200 currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 194 201 } 195 202 Parent::visit( objectDecl ); 196 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext) ) {203 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) { 197 204 // delete newly created signed int type 198 delete initContext; 199 } 200 initContext = temp; 205 // delete currentObject.getType(); 206 } 201 207 } 202 208 … … 315 321 316 322 void Resolver::visit( SwitchStmt *switchStmt ) { 317 ValueGuard< Type * > oldInitContext( initContext );323 ValueGuard< CurrentObject > oldCurrentObject( currentObject ); 318 324 Expression *newExpr; 319 325 newExpr = findIntegralExpression( switchStmt->get_condition(), *this ); … … 321 327 switchStmt->set_condition( newExpr ); 322 328 323 initContext = newExpr->get_result();329 currentObject = CurrentObject( newExpr->get_result() ); 324 330 Parent::visit( switchStmt ); 325 331 } … … 327 333 void Resolver::visit( CaseStmt *caseStmt ) { 328 334 if ( caseStmt->get_condition() ) { 329 assert( initContext ); 330 CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initContext->clone() ); 335 std::list< InitAlternative > initAlts = currentObject.getOptions(); 336 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." ); 337 CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() ); 331 338 Expression * newExpr = findSingleExpression( castExpr, *this ); 332 339 castExpr = safe_dynamic_cast< CastExpr * >( newExpr ); … … 360 367 } 361 368 369 void Resolver::visit( ThrowStmt *throwStmt ) { 370 if ( throwStmt->get_expr() ) { 371 Expression * wrapped = new CastExpr( throwStmt->get_expr(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 372 Expression * newExpr = findSingleExpression( wrapped, *this ); 373 throwStmt->set_expr( newExpr ); 374 } 375 } 376 362 377 template< typename T > 363 378 bool isCharType( T t ) { … … 370 385 371 386 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 } 387 // resolve initialization using the possibilities as determined by the currentObject cursor 388 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() ); 389 Expression * newExpr = findSingleExpression( untyped, *this ); 390 InitExpr * initExpr = safe_dynamic_cast< InitExpr * >( newExpr ); 391 392 // move cursor to the object that is actually initialized 393 currentObject.setNext( initExpr->get_designation() ); 394 395 // discard InitExpr wrapper and retain relevant pieces 396 newExpr = initExpr->get_expr(); 397 newExpr->set_env( initExpr->get_env() ); 398 initExpr->set_expr( nullptr ); 399 initExpr->set_env( nullptr ); 400 delete initExpr; 401 402 // get the actual object's type (may not exactly match what comes back from the resolver due to conversions) 403 Type * initContext = currentObject.getCurrentType(); 404 405 // check if actual object's type is char[] 406 if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) { 407 if ( isCharType( at->get_base() ) ) { 408 // check if the resolved type is char * 409 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) { 410 if ( isCharType( pt->get_base() ) ) { 411 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 412 CastExpr *ce = safe_dynamic_cast< CastExpr * >( newExpr ); 413 newExpr = ce->get_arg(); 414 ce->set_arg( nullptr ); 415 delete ce; 419 416 } 420 417 } 421 418 } 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 419 } 420 421 // set initializer expr to resolved express 422 singleInit->set_value( newExpr ); 423 424 // move cursor to next object in preparation for next initializer 425 currentObject.increment(); 486 426 } 487 427 488 428 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 429 // move cursor into brace-enclosed initializer-list 430 currentObject.enterListInit(); 431 // xxx - fix this so that the list isn't copied, iterator should be used to change current element 432 std::list<Designation *> newDesignations; 433 for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) { 434 // iterate designations and initializers in pairs, moving the cursor to the current designated object and resolving 435 // the initializer against that object. 436 Designation * des = std::get<0>(p); 437 Initializer * init = std::get<1>(p); 438 newDesignations.push_back( currentObject.findNext( des ) ); 439 init->accept( *this ); 440 } 441 // set the set of 'resolved' designations and leave the brace-enclosed initializer-list 442 listInit->get_designations() = newDesignations; // xxx - memory management 443 currentObject.exitListInit(); 444 445 // xxx - this part has not be folded into CurrentObject yet 446 // } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) { 447 // Type * base = tt->get_baseType()->get_base(); 448 // if ( base ) { 449 // // know the implementation type, so try using that as the initContext 450 // ObjectDecl tmpObj( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, base->clone(), nullptr ); 451 // currentObject = &tmpObj; 452 // visit( listInit ); 453 // } else { 454 // // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context 455 // Parent::visit( listInit ); 456 // } 457 // } else { 573 458 } 574 459 -
src/ResolvExpr/Unify.cc
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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/SymTab/Indexer.cc
r11dbfe1 r67fa9f9 652 652 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 653 653 // check for C decls with the same name, skipping those with a compatible type (by mangleName) 654 if ( decl->second->get_linkage() == LinkageSpec::C&& decl->first != mangleName ) return true;654 if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first != mangleName ) return true; 655 655 } 656 656 } … … 669 669 // check for C decls with the same name, skipping 670 670 // those with an incompatible type (by mangleName) 671 if ( decl->second->get_linkage() == LinkageSpec::C&& decl->first == mangleName ) return true;671 if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first == mangleName ) return true; 672 672 } 673 673 } … … 724 724 // new definition shadows the autogenerated one, even at the same scope 725 725 return false; 726 } else if ( added->get_linkage() != LinkageSpec::C|| ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) {726 } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) { 727 727 // typesCompatible doesn't really do the right thing here. When checking compatibility of function types, 728 728 // we should ignore outermost pointer qualifiers, except _Atomic? … … 765 765 766 766 // this ensures that no two declarations with the same unmangled name at the same scope both have C linkage 767 if ( decl->get_linkage() == LinkageSpec::C) {767 if ( ! LinkageSpec::isMangled( decl->get_linkage() ) ) { 768 768 // NOTE this is broken in Richard's original code in such a way that it never triggers (it 769 769 // doesn't check decls that have the same manglename, and all C-linkage decls are defined to -
src/SymTab/Validate.cc
r11dbfe1 r67fa9f9 106 106 107 107 /// Fix return types so that every function returns exactly one value 108 class ReturnTypeFixer { 109 public: 108 struct ReturnTypeFixer { 110 109 static void fix( std::list< Declaration * > &translationUnit ); 111 110 … … 115 114 116 115 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 117 class EnumAndPointerDecay { 118 public: 116 struct EnumAndPointerDecay { 119 117 void previsit( EnumDecl *aggregateDecl ); 120 118 void previsit( FunctionType *func ); … … 159 157 }; 160 158 161 class ReturnChecker : public WithScopes { 162 public: 159 struct ReturnChecker : public WithGuards { 163 160 /// Checks that return statements return nothing if their return type is void 164 161 /// and return something if the return type is non-void. 165 162 static void checkFunctionReturns( std::list< Declaration * > & translationUnit ); 166 private: 163 167 164 void previsit( FunctionDecl * functionDecl ); 168 165 void previsit( ReturnStmt * returnStmt ); … … 205 202 }; 206 203 207 class VerifyCtorDtorAssign { 208 public: 204 struct VerifyCtorDtorAssign { 209 205 /// ensure that constructors, destructors, and assignment have at least one 210 206 /// parameter, the first of which must be a pointer, and that ctor/dtors have no … … 216 212 217 213 /// ensure that generic types have the correct number of type arguments 218 class ValidateGenericParameters { 219 public: 214 struct ValidateGenericParameters { 220 215 void previsit( StructInstType * inst ); 221 216 void previsit( UnionInstType * inst ); 222 217 }; 223 218 224 class ArrayLength { 225 public: 219 struct ArrayLength { 226 220 /// for array types without an explicit length, compute the length and store it so that it 227 221 /// is known to the rest of the phases. For example, … … 236 230 }; 237 231 238 class CompoundLiteral final : public GenPoly::DeclMutator{232 struct CompoundLiteral final : public WithDeclsToAdd, public WithVisitorRef<CompoundLiteral> { 239 233 Type::StorageClasses storageClasses; 240 234 241 using GenPoly::DeclMutator::mutate; 242 DeclarationWithType * mutate( ObjectDecl *objectDecl ) final; 243 Expression *mutate( CompoundLiteralExpr *compLitExpr ) final; 235 void premutate( ObjectDecl *objectDecl ); 236 Expression * postmutate( CompoundLiteralExpr *compLitExpr ); 244 237 }; 245 238 … … 248 241 LinkReferenceToTypes lrt( doDebug, 0 ); 249 242 ForallPointerDecay fpd( 0 ); 250 CompoundLiteralcompoundliteral;243 PassVisitor<CompoundLiteral> compoundliteral; 251 244 PassVisitor<ValidateGenericParameters> genericParams; 252 245 … … 263 256 Concurrency::implementThreadStarter( translationUnit ); 264 257 ReturnChecker::checkFunctionReturns( translationUnit ); 265 compoundliteral.mutateDeclarationList( translationUnit);258 mutateAll( translationUnit, compoundliteral ); 266 259 acceptAll( translationUnit, fpd ); 267 260 ArrayLength::computeLength( translationUnit ); … … 883 876 } 884 877 885 DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {878 void CompoundLiteral::premutate( ObjectDecl *objectDecl ) { 886 879 storageClasses = objectDecl->get_storageClasses(); 887 DeclarationWithType * temp = Mutator::mutate( objectDecl ); 888 return temp; 889 } 890 891 Expression *CompoundLiteral::mutate( CompoundLiteralExpr *compLitExpr ) { 880 } 881 882 Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) { 892 883 // transform [storage_class] ... (struct S){ 3, ... }; 893 884 // into [storage_class] struct S temp = { 3, ... }; 894 885 static UniqueName indexName( "_compLit" ); 895 886 896 ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, 0, compLitExpr->get_result(), compLitExpr->get_initializer() );897 compLitExpr->set_result( 0);898 compLitExpr->set_initializer( 0);887 ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() ); 888 compLitExpr->set_result( nullptr ); 889 compLitExpr->set_initializer( nullptr ); 899 890 delete compLitExpr; 900 DeclarationWithType * newtempvar = mutate( tempvar ); 901 addDeclaration( newtempvar ); // add modified temporary to current block 902 return new VariableExpr( newtempvar ); 891 declsToAddBefore.push_back( tempvar ); // add modified temporary to current block 892 return new VariableExpr( tempvar ); 903 893 } 904 894 -
src/SynTree/Constant.cc
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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
r11dbfe1 r67fa9f9 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 -
src/libcfa/Makefile.am
r11dbfe1 r67fa9f9 50 50 51 51 libobjs = ${headers:=.o} 52 libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} 52 libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} exception.c 53 53 54 54 # not all platforms support concurrency, add option do disable it -
src/libcfa/Makefile.in
r11dbfe1 r67fa9f9 102 102 containers/pair.c containers/result.c containers/vector.c \ 103 103 concurrency/coroutine.c concurrency/thread.c \ 104 concurrency/kernel.c concurrency/monitor.c \104 concurrency/kernel.c concurrency/monitor.c exception.c \ 105 105 concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \ 106 106 concurrency/invoke.c concurrency/preemption.c … … 126 126 libcfa_d_a-interpose.$(OBJEXT) \ 127 127 libhdr/libcfa_d_a-libdebug.$(OBJEXT) $(am__objects_2) \ 128 $(am__objects_3)128 libcfa_d_a-exception.$(OBJEXT) $(am__objects_3) 129 129 am_libcfa_d_a_OBJECTS = $(am__objects_4) 130 130 libcfa_d_a_OBJECTS = $(am_libcfa_d_a_OBJECTS) … … 136 136 containers/pair.c containers/result.c containers/vector.c \ 137 137 concurrency/coroutine.c concurrency/thread.c \ 138 concurrency/kernel.c concurrency/monitor.c \138 concurrency/kernel.c concurrency/monitor.c exception.c \ 139 139 concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \ 140 140 concurrency/invoke.c concurrency/preemption.c … … 158 158 libcfa_a-interpose.$(OBJEXT) \ 159 159 libhdr/libcfa_a-libdebug.$(OBJEXT) $(am__objects_6) \ 160 $(am__objects_7)160 libcfa_a-exception.$(OBJEXT) $(am__objects_7) 161 161 am_libcfa_a_OBJECTS = $(am__objects_8) 162 162 libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS) … … 328 328 libobjs = ${headers:=.o} 329 329 libsrc = libcfa-prelude.c interpose.c libhdr/libdebug.c ${headers:=.c} \ 330 $(am__append_4)330 exception.c $(am__append_4) 331 331 libcfa_a_SOURCES = ${libsrc} 332 332 libcfa_a_CFLAGS = -nodebug -O2 … … 514 514 515 515 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-assert.Po@am__quote@ 516 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-exception.Po@am__quote@ 516 517 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-fstream.Po@am__quote@ 517 518 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-interpose.Po@am__quote@ … … 524 525 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-stdlib.Po@am__quote@ 525 526 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-assert.Po@am__quote@ 527 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-exception.Po@am__quote@ 526 528 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-fstream.Po@am__quote@ 527 529 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-interpose.Po@am__quote@ … … 850 852 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_d_a-monitor.obj `if test -f 'concurrency/monitor.c'; then $(CYGPATH_W) 'concurrency/monitor.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/monitor.c'; fi` 851 853 854 libcfa_d_a-exception.obj: exception.c 855 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-exception.obj -MD -MP -MF $(DEPDIR)/libcfa_d_a-exception.Tpo -c -o libcfa_d_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi` 856 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-exception.Tpo $(DEPDIR)/libcfa_d_a-exception.Po 857 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='exception.c' object='libcfa_d_a-exception.obj' libtool=no @AMDEPBACKSLASH@ 858 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 859 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libcfa_d_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi` 860 852 861 concurrency/libcfa_d_a-alarm.o: concurrency/alarm.c 853 862 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT concurrency/libcfa_d_a-alarm.o -MD -MP -MF concurrency/$(DEPDIR)/libcfa_d_a-alarm.Tpo -c -o concurrency/libcfa_d_a-alarm.o `test -f 'concurrency/alarm.c' || echo '$(srcdir)/'`concurrency/alarm.c … … 1143 1152 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1144 1153 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_a-monitor.obj `if test -f 'concurrency/monitor.c'; then $(CYGPATH_W) 'concurrency/monitor.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/monitor.c'; fi` 1154 1155 libcfa_a-exception.obj: exception.c 1156 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libcfa_a-exception.obj -MD -MP -MF $(DEPDIR)/libcfa_a-exception.Tpo -c -o libcfa_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi` 1157 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-exception.Tpo $(DEPDIR)/libcfa_a-exception.Po 1158 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='exception.c' object='libcfa_a-exception.obj' libtool=no @AMDEPBACKSLASH@ 1159 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1160 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi` 1145 1161 1146 1162 concurrency/libcfa_a-alarm.o: concurrency/alarm.c -
src/libcfa/exception.c
r11dbfe1 r67fa9f9 44 44 // RESUMPTION ================================================================ 45 45 46 void __cfaehm__throw_resum e(exceptionexcept) {47 48 // DEBUG 49 printf("Throwing resumption exception %d\n", except);50 51 struct __ try_resume_node * original_head = shared_stack.current_resume;52 struct __ try_resume_node * current =46 void __cfaehm__throw_resumption(exception * except) { 47 48 // DEBUG 49 printf("Throwing resumption exception %d\n", *except); 50 51 struct __cfaehm__try_resume_node * original_head = shared_stack.current_resume; 52 struct __cfaehm__try_resume_node * current = 53 53 (original_head) ? original_head->next : shared_stack.top_resume; 54 54 55 55 for ( ; current ; current = current->next) { 56 56 shared_stack.current_resume = current; 57 if (current-> try_to_handle(except)) {57 if (current->handler(except)) { 58 58 shared_stack.current_resume = original_head; 59 59 return; … … 61 61 } 62 62 63 printf("Unhandled exception %d\n", except);63 printf("Unhandled exception %d\n", *except); 64 64 shared_stack.current_resume = original_head; 65 65 66 66 // Fall back to termination: 67 __cfaehm__throw_terminat e(except);67 __cfaehm__throw_termination(except); 68 68 // TODO: Default handler for resumption. 69 69 } … … 73 73 * after the node is built but before it is made the top node. 74 74 */ 75 void __ try_resume_setup(struct__try_resume_node * node,76 bool (*handler)(exceptionexcept)) {75 void __cfaehm__try_resume_setup(struct __cfaehm__try_resume_node * node, 76 int (*handler)(exception * except)) { 77 77 node->next = shared_stack.top_resume; 78 node-> try_to_handle= handler;78 node->handler = handler; 79 79 shared_stack.top_resume = node; 80 80 } 81 81 82 void __ try_resume_cleanup(struct__try_resume_node * node) {82 void __cfaehm__try_resume_cleanup(struct __cfaehm__try_resume_node * node) { 83 83 shared_stack.top_resume = node->next; 84 84 } … … 111 111 } 112 112 113 void __cfaehm__throw_terminat e( intval ) {113 void __cfaehm__throw_termination( exception * val ) { 114 114 // Store the current exception 115 shared_stack.current_exception = val;116 117 // DEBUG 118 printf("Throwing termination exception %d\n", val);115 shared_stack.current_exception = *val; 116 117 // DEBUG 118 printf("Throwing termination exception %d\n", *val); 119 119 120 120 // Call stdlibc to raise the exception … … 147 147 148 148 // Nesting this the other way would probably be faster. 149 void __cfaehm__rethrow_terminat e(void) {149 void __cfaehm__rethrow_termination(void) { 150 150 // DEBUG 151 151 printf("Rethrowing termination exception\n"); 152 152 153 __cfaehm__throw_terminat e(shared_stack.current_exception);153 __cfaehm__throw_termination(&shared_stack.current_exception); 154 154 } 155 155 … … 322 322 // for details 323 323 __attribute__((noinline)) 324 void __ try_terminate(void (*try_block)(),325 void (*catch_block)(int index, exception except),326 __attribute__((unused)) int (*match_block)(exception except)) {324 void __cfaehm__try_terminate(void (*try_block)(), 325 void (*catch_block)(int index, exception * except), 326 __attribute__((unused)) int (*match_block)(exception * except)) { 327 327 //! volatile int xy = 0; 328 328 //! printf("%p %p %p %p\n", &try_block, &catch_block, &match_block, &xy); … … 364 364 // Exception handler 365 365 catch_block(shared_stack.current_handler_index, 366 shared_stack.current_exception);366 &shared_stack.current_exception); 367 367 } 368 368 … … 384 384 // Body uses language specific data and therefore could be modified arbitrarily 385 385 ".LLSDACSBCFA2:\n" // BODY start 386 " .uleb128 .TRYSTART-__ try_terminate\n" // Handled area start (relative to start of function)386 " .uleb128 .TRYSTART-__cfaehm__try_terminate\n" // Handled area start (relative to start of function) 387 387 " .uleb128 .TRYEND-.TRYSTART\n" // Handled area length 388 " .uleb128 .CATCH-__ try_terminate\n" // Hanlder landing pad adress (relative to start of function)388 " .uleb128 .CATCH-__cfaehm__try_terminate\n" // Hanlder landing pad adress (relative to start of function) 389 389 " .uleb128 1\n" // Action code, gcc seems to use always 0 390 390 ".LLSDACSECFA2:\n" // BODY end 391 391 " .text\n" // TABLE footer 392 " .size __ try_terminate, .-__try_terminate\n"392 " .size __cfaehm__try_terminate, .-__cfaehm__try_terminate\n" 393 393 " .ident \"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n" 394 394 // " .section .note.GNU-stack,\"x\",@progbits\n" -
src/libcfa/exception.h
r11dbfe1 r67fa9f9 38 38 // Data structure creates a list of resume handlers. 39 39 struct __cfaehm__try_resume_node { 40 __cfaehm__try_resume_node * next;40 struct __cfaehm__try_resume_node * next; 41 41 int (*handler)(exception * except); 42 42 }; 43 43 44 44 void __cfaehm__try_resume_setup( 45 __cfaehm__try_resume_node * node,45 struct __cfaehm__try_resume_node * node, 46 46 int (*handler)(exception * except)); 47 47 void __cfaehm__try_resume_cleanup( 48 __cfaehm__try_resume_node * node);48 struct __cfaehm__try_resume_node * node); 49 49 50 50 // Check for a standard way to call fake deconstructors. -
src/libcfa/fstream
r11dbfe1 r67fa9f9 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 15 18:11:09201713 // Update Count : 1 0412 // Last Modified On : Sat Jul 1 16:37:53 2017 13 // Update Count : 112 14 14 // 15 15 … … 24 24 _Bool sepDefault; 25 25 _Bool sepOnOff; 26 _Bool lastSepOn; 26 27 const char * sepCur; 27 28 char separator[separateSize]; … … 35 36 const char * sepGetCur( ofstream * ); 36 37 void sepSetCur( ofstream *, const char * ); 38 _Bool lastSepOn( ofstream * ); 37 39 38 40 // public -
src/libcfa/fstream.c
r11dbfe1 r67fa9f9 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 15 18:11:11201713 // Update Count : 2 3412 // Last Modified On : Sat Jul 1 16:37:54 2017 13 // Update Count : 242 14 14 // 15 15 … … 33 33 this->sepDefault = sepDefault; 34 34 this->sepOnOff = sepOnOff; 35 this->lastSepOn = false; 35 36 sepSet( this, separator ); 36 37 sepSetCur( this, sepGet( this ) ); … … 39 40 40 41 // private 41 _Bool sepPrt( ofstream * os ) { return os->sepOnOff; } 42 _Bool lastSepOn( ofstream * os ) { return os->lastSepOn; } 43 _Bool sepPrt( ofstream * os ) { os->lastSepOn = false; return os->sepOnOff; } 42 44 void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; } 43 45 void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; } … … 46 48 47 49 // public 48 void sepOn( ofstream * os ) { os-> sepOnOff = 1; }49 void sepOff( ofstream * os ) { os-> sepOnOff = 0; }50 void sepOn( ofstream * os ) { os->lastSepOn = true; os->sepOnOff = true; } 51 void sepOff( ofstream * os ) { os->lastSepOn = false; os->sepOnOff = 0; } 50 52 51 53 _Bool sepDisable( ofstream *os ) { 52 54 _Bool temp = os->sepDefault; 53 55 os->sepDefault = false; 56 os->lastSepOn = false; 54 57 sepReset( os ); 55 58 return temp; … … 92 95 exit( EXIT_FAILURE ); 93 96 } // if 94 ?{}( os, file, 1, 0, " ", ", " );97 ?{}( os, file, true, false, " ", ", " ); 95 98 } // open 96 99 … … 132 135 } // fmt 133 136 134 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), 1, 0, " ", ", " };137 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), true, false, " ", ", " }; 135 138 ofstream *sout = &soutFile; 136 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), 1, 0, " ", ", " };139 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), true, false, " ", ", " }; 137 140 ofstream *serr = &serrFile; 138 141 -
src/libcfa/iostream
r11dbfe1 r67fa9f9 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 15 18:08:44201713 // Update Count : 1 0512 // Last Modified On : Sun Jul 2 08:42:56 2017 13 // Update Count : 110 14 14 // 15 15 … … 26 26 const char * sepGetCur( ostype * ); // get current separator string 27 27 void sepSetCur( ostype *, const char * ); // set current separator string 28 _Bool lastSepOn( ostype * ); // last manipulator is setOn (context sensitive) 28 29 // public 29 30 void sepOn( ostype * ); // turn separator state on … … 43 44 ostype * write( ostype *, const char *, unsigned long int ); 44 45 int fmt( ostype *, const char fmt[], ... ); 45 }; 46 }; // ostream 46 47 47 48 trait writeable( otype T ) { 48 49 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, T ); 49 }; 50 }; // writeable 50 51 51 52 // implement writable for intrinsic types … … 103 104 istype * ungetc( istype *, char ); 104 105 int fmt( istype *, const char fmt[], ... ); 105 }; 106 }; // istream 106 107 107 108 trait readable( otype T ) { 108 109 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, T ); 109 }; 110 }; // readable 110 111 111 112 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, char * ); -
src/libcfa/iostream.c
r11dbfe1 r67fa9f9 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 8 18:24:23201713 // Update Count : 3 6912 // Last Modified On : Sun Jul 2 08:54:02 2017 13 // Update Count : 375 14 14 // 15 15 … … 201 201 forall( dtype ostype, otype T, ttype Params | ostream( ostype ) | writeable( T ) | { ostype * ?|?( ostype *, Params ); } ) 202 202 ostype * ?|?( ostype * os, T arg, Params rest ) { 203 os | arg; // print first argument 203 204 sepSetCur( os, sepGetTuple( os ) ); // switch to tuple separator 204 os | arg; // print first argument205 205 os | rest; // print remaining arguments 206 206 sepSetCur( os, sepGet( os ) ); // switch to regular separator … … 217 217 forall( dtype ostype | ostream( ostype ) ) 218 218 ostype * endl( ostype * os ) { 219 if ( lastSepOn( os ) ) fmt( os, "%s", sepGetCur( os ) ); 219 220 os | '\n'; 220 221 flush( os ); -
src/main.cc
r11dbfe1 r67fa9f9 11 11 // Created On : Fri May 15 23:12:02 2015 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Wed Jun 28 21:56:47201714 // Update Count : 44 013 // Last Modified On : Thu Jun 29 12:46:50 2017 14 // Update Count : 441 15 15 // 16 16 … … 39 39 #include "CodeTools/TrackLoc.h" 40 40 #include "ControlStruct/Mutate.h" 41 #include "ControlStruct/ExceptTranslate.h" 41 42 #include "SymTab/Validate.h" 42 43 #include "ResolvExpr/AlternativePrinter.h" … … 290 291 Tuples::expandUniqueExpr( translationUnit ); 291 292 293 OPTPRINT( "translateEHM" ); 294 ControlStruct::translateEHM( translationUnit ); 295 292 296 OPTPRINT( "convertSpecializations" ) // needs to happen before tuple types are expanded 293 297 GenPoly::convertSpecializations( translationUnit ); … … 481 485 break; 482 486 case '?': 483 assertf( false, "Unknown option: '%c'\n", (char)optopt ); 487 if ( optopt ) { // short option ? 488 assertf( false, "Unknown option: -%c\n", (char)optopt ); 489 } else { 490 assertf( false, "Unknown option: %s\n", argv[optind - 1] ); 491 } // if 484 492 default: 485 493 abort(); -
src/prelude/Makefile.am
r11dbfe1 r67fa9f9 23 23 noinst_DATA = ../libcfa/libcfa-prelude.c 24 24 25 CC = ${abs_top_srcdir}/src/driver/cfa 26 25 27 $(DEPDIR) : 26 28 mkdir $(DEPDIR) … … 45 47 46 48 # create forward declarations for cfa builtins 47 builtins.cf : builtins.c 48 ${AM_V_GEN} @BACKEND_CC@-E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po49 builtins.cf : builtins.c ${CC} 50 ${AM_V_GEN}${CC} -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po 49 51 ${AM_V_at}sed -i 's/builtins.o/builtins.cf/g' $(DEPDIR)/builtins.Po 50 52 -
src/prelude/Makefile.in
r11dbfe1 r67fa9f9 95 95 AWK = @AWK@ 96 96 BACKEND_CC = @BACKEND_CC@ 97 CC = @CC@97 CC = ${abs_top_srcdir}/src/driver/cfa 98 98 CCAS = @CCAS@ 99 99 CCASDEPMODE = @CCASDEPMODE@ … … 444 444 445 445 # create forward declarations for cfa builtins 446 builtins.cf : builtins.c 447 ${AM_V_GEN} @BACKEND_CC@-E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po446 builtins.cf : builtins.c ${CC} 447 ${AM_V_GEN}${CC} -E -P ${<} -o ${@} -MD -MP -MF $(DEPDIR)/builtins.Po 448 448 ${AM_V_at}sed -i 's/builtins.o/builtins.cf/g' $(DEPDIR)/builtins.Po 449 449 -
src/tests/.expect/io.txt
r11dbfe1 r67fa9f9 4 4 123 5 5 6 opening delimiters 6 7 x (1 x [2 x {3 x =4 x $5 x £6 x ¥7 x ¡8 x ¿9 x «10 7 1, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x 8 9 closing delimiters 10 1, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x 11 12 opening/closing delimiters 8 13 x`1`x'2'x"3"x:4:x 5 x 6 x 9 14 7 … … 14 19 x 15 20 10 16 x 21 x 22 23 override opening/closing delimiters 17 24 x ( 1 ) x 2 , x 3 :x: 4 25 26 input bacis types 27 28 output basic types 18 29 A 19 30 1 2 3 4 5 6 7 8 … … 21 32 1.1+2.3i 1.1-2.3i 1.1-2.3i 22 33 34 tuples 35 1, 2, 3 3, 4, 5 36 37 toggle separator 23 38 1.11.21.3 24 39 1.1+2.3i1.1-2.3i1.1-2.3i 25 abcxyz 26 abcxyz 40 abcxyz 41 abcxyz 27 42 43 change separator 44 from " "to " , $" 28 45 1.1, $1.2, $1.3 29 46 1.1+2.3i, $1.1-2.3i, $1.1-2.3i 30 abc, $xyz 47 abc, $xyz, $ 48 1, 2, 3, $3, 4, 5 31 49 32 1, 2, 3, 4 33 1, $2, $3 ", $" 34 1 2 3 " " 50 from ", $"to " " 51 1.1 1.2 1.3 52 1.1+2.3i 1.1-2.3i 1.1-2.3i 53 abc xyz 54 1, 2, 3 3, 4, 5 55 56 1 2 3 57 12 3 35 58 1 2 3 36 12 3 59 1 2 3 60 1 2 3 61 37 62 123 38 63 1 23 39 64 1 2 3 40 1 2 3 4 " " 41 1, 2, 3, 4 ", " 42 1, 2, 3, 4 65 123 66 1 2 3 67 123 68 1 2 3 69 70 1 2 3 3 4 5 " " 71 1, 2, 3 3, 4, 5 ", " 72 1, 2, 3 3, 4, 5 73 43 74 3, 4, a, 7.2 44 75 3, 4, a, 7.2 45 76 3 4 a 7.2 46 77 3 4 a 7.234a7.23 4 a 7.2 47 3-4-a-7.2^3^4 -3-4-a-7.278 3-4-a-7.2^3^4^3-4-a-7.2 -
src/tests/io.c
r11dbfe1 r67fa9f9 10 10 // Created On : Wed Mar 2 16:56:02 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jun 8 09:52:10201713 // Update Count : 5112 // Last Modified On : Sun Jul 2 09:40:58 2017 13 // Update Count : 68 14 14 // 15 15 … … 42 42 sout | endl; 43 43 44 sout | "opening delimiters" | endl; 44 45 sout 45 // opening delimiters46 46 | "x (" | 1 47 47 | "x [" | 2 … … 54 54 | "x ¿" | 9 55 55 | "x «" | 10 56 | endl; 56 | endl | endl; 57 58 sout | "closing delimiters" | endl; 57 59 sout 58 // closing delimiters59 60 | 1 | ", x" 60 61 | 2 | ". x" … … 68 69 | 10 | "] x" 69 70 | 11 | "} x" 70 | endl; 71 | endl | endl; 72 73 sout | "opening/closing delimiters" | endl; 71 74 sout 72 // opening-closing delimiters73 75 | "x`" | 1 | "`x'" | 2 74 76 | "'x\"" | 3 | "\"x:" | 4 … … 76 78 | "\tx\f" | 7 | "\fx\v" | 8 77 79 | "\vx\n" | 9 | "\nx\r" | 10 78 | "\rx" | 79 endl; 80 | "\rx" 81 | endl | endl; 82 83 sout | "override opening/closing delimiters" | endl; 80 84 sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4 | endl; 85 sout | endl; 81 86 82 87 ifstream in; // create / open file 83 88 open( &in, "io.data", "r" ); 84 89 90 sout | "input bacis types" | endl; 85 91 &in | &c // character 86 92 | &si | &usi | &i | &ui | &li | &uli | &lli | &ulli // integral … … 88 94 | &fc | &dc | &ldc // floating-point complex 89 95 | cstr( s1 ) | cstr( s2, size ); // C string, length unchecked and checked 96 sout | endl; 90 97 98 sout | "output basic types" | endl; 91 99 sout | c | ' ' | endl // character 92 100 | si | usi | i | ui | li | uli | lli | ulli | endl // integral … … 94 102 | fc | dc | ldc | endl; // complex 95 103 sout | endl; 104 105 sout | "tuples" | endl; 106 [int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 3, [ 4, 5 ] ]; 107 sout | t1 | t2 | endl; // print tuple 108 sout | endl; 109 110 sout | "toggle separator" | endl; 96 111 sout | f | "" | d | "" | ld | endl // floating point without separator 97 112 | sepDisable | fc | dc | ldc | sepEnable | endl // complex without separator … … 100 115 sout | endl; 101 116 117 sout | "change separator" | endl; 118 sout | "from \" " | sepGet( sout ) | "\""; 102 119 sepSet( sout, ", $" ); // change separator, maximum of 15 characters 120 sout | "to \" " | sepGet( sout ) | "\"" | endl; 103 121 sout | f | d | ld | endl 104 122 | fc | dc | ldc | endl 105 | s1 | s2 | endl; 123 | s1 | s2 | endl 124 | t1 | t2 | endl; // print tuple 125 sout | endl; 126 sout | "from \"" | sepGet( sout ) | "\""; 127 sepSet( sout, " " ); // restore separator 128 sout | "to \"" | sepGet( sout ) | "\"" | endl; 129 sout | f | d | ld | endl 130 | fc | dc | ldc | endl 131 | s1 | s2 | endl 132 | t1 | t2 | endl; // print tuple 106 133 sout | endl; 107 134 108 [int, int] t1 = [1, 2], t2 = [3, 4]; 109 sout | t1 | t2 | endl; // print tuple 110 111 sepSet( sout, " " ); 112 sepSet( sout, ", $" ); // set separator from " " to ", $" 113 sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl; 114 sepSet( sout, " " ); // reset separator to " " 115 sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl; 116 117 sout | sepOn | 1 | 2 | 3 | sepOn | endl; // separator at start of line 135 sout | sepOn | 1 | 2 | 3 | sepOn | endl; // separator at start/end of line 118 136 sout | 1 | sepOff | 2 | 3 | endl; // locally turn off implicit separator 137 sout | sepOn | 1 | 2 | 3 | sepOn | sepOff | endl; // separator at start of line 138 sout | 1 | 2 | 3 | endl | sepOn; // separator at start of next line 139 sout | 1 | 2 | 3 | endl; 140 sout | endl; 119 141 120 142 sout | sepDisable | 1 | 2 | 3 | endl; // globally turn off implicit separation 121 143 sout | 1 | sepOn | 2 | 3 | endl; // locally turn on implicit separator 122 sout | sepEnable | 1 | 2 | 3 | endl; // globally turn on implicit separation 144 sout | sepEnable | 1 | 2 | 3 | endl | sepDisable; // globally turn on/off implicit separation 145 sout | 1 | 2 | 3 | endl | sepEnable; // globally turn on implicit separation 146 sout | 1 | 2 | 3 | sepOn | sepDisable | endl; // ignore seperate at end of line 147 sout | 1 | 2 | 3 | sepOn | sepEnable | endl; // separator at end of line 148 sout | 1 | 2 | 3 | endl; 149 sout | endl; 123 150 124 151 sepSetTuple( sout, " " ); // set tuple separator from ", " to " " … … 126 153 sepSetTuple( sout, ", " ); // reset tuple separator to ", " 127 154 sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"" | endl; 128 129 155 sout | t1 | t2 | endl; // print tuple 156 sout | endl; 130 157 131 158 [int, int, const char *, double] t3 = { 3, 4, "a", 7.2 };
Note:
See TracChangeset
for help on using the changeset viewer.