Changeset 87d13cd for src/Concurrency/Keywords.cc
- Timestamp:
- Mar 21, 2017, 10:07:52 PM (7 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:
- cb91437
- Parents:
- 829c907 (diff), a53e10a (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Keywords.cc
r829c907 r87d13cd 17 17 #include "Concurrency/Keywords.h" 18 18 19 #include "SymTab/AddVisit.h" 19 20 #include "SynTree/Declaration.h" 20 21 #include "SynTree/Expression.h" … … 29 30 namespace { 30 31 const std::list<Label> noLabels; 32 const std::list< Attribute * > noAttributes; 31 33 Type::StorageClasses noStorage; 32 34 Type::Qualifiers noQualifiers; … … 63 65 // void main( MyCoroutine * this ); 64 66 // 65 class CoroutineKeyword final : public Mutator { 67 class CoroutineKeyword final : public Visitor { 68 template< typename Visitor > 69 friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor ); 66 70 public: 67 71 68 static void implement( std::list< Declaration * > & translationUnit ) {} 72 using Visitor::visit; 73 virtual void visit( StructDecl * decl ) override final; 74 75 void handle( StructDecl * ); 76 Declaration * addField( StructDecl * ); 77 void addRoutines( StructDecl *, Declaration * ); 78 79 static void implement( std::list< Declaration * > & translationUnit ) { 80 CoroutineKeyword impl; 81 SymTab::acceptAndAdd( translationUnit, impl ); 82 } 83 84 private: 85 std::list< Declaration * > declsToAdd, declsToAddAfter; 86 StructDecl* coroutine_decl = nullptr; 69 87 }; 70 88 … … 97 115 98 116 using Visitor::visit; 99 virtual void visit( FunctionDecl * functionDecl ) override final;100 virtual void visit( StructDecl * functionDecl ) override final;117 virtual void visit( FunctionDecl * decl ) override final; 118 virtual void visit( StructDecl * decl ) override final; 101 119 102 120 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* ); … … 111 129 private: 112 130 StructDecl* monitor_decl = nullptr; 131 StructDecl* guard_decl = nullptr; 113 132 }; 114 133 … … 124 143 125 144 //============================================================================================= 145 // Coroutine keyword implementation 146 //============================================================================================= 147 void CoroutineKeyword::visit(StructDecl * decl) { 148 if( decl->get_name() == "coroutine_desc" ) { 149 assert( !coroutine_decl ); 150 coroutine_decl = decl; 151 } 152 else if ( decl->is_coroutine() ) { 153 handle( decl ); 154 } 155 156 } 157 158 void CoroutineKeyword::handle( StructDecl * decl ) { 159 if( ! decl->has_body() ) return; 160 161 if( !coroutine_decl ) throw SemanticError( "coroutine keyword requires coroutines to be in scope, add #include <coroutine>", decl ); 162 163 Declaration * field = addField( decl ); 164 addRoutines( decl, field ); 165 } 166 167 Declaration * CoroutineKeyword::addField( StructDecl * decl ) { 168 Declaration * cor = new ObjectDecl( 169 "__cor", 170 noStorage, 171 LinkageSpec::Cforall, 172 nullptr, 173 new StructInstType( 174 noQualifiers, 175 coroutine_decl 176 ), 177 nullptr 178 ); 179 180 decl->get_members().push_back( cor ); 181 182 return cor; 183 } 184 185 void CoroutineKeyword::addRoutines( StructDecl * decl, Declaration * field ) { 186 FunctionType * type = new FunctionType( noQualifiers, false ); 187 type->get_parameters().push_back( 188 new ObjectDecl( 189 "this", 190 noStorage, 191 LinkageSpec::Cforall, 192 nullptr, 193 new PointerType( 194 noQualifiers, 195 new StructInstType( 196 noQualifiers, 197 decl 198 ) 199 ), 200 nullptr 201 ) 202 ); 203 type->get_returnVals().push_back( 204 new ObjectDecl( 205 "ret", 206 noStorage, 207 LinkageSpec::Cforall, 208 nullptr, 209 new PointerType( 210 noQualifiers, 211 new StructInstType( 212 noQualifiers, 213 coroutine_decl 214 ) 215 ), 216 nullptr 217 ) 218 ); 219 220 CompoundStmt * statement = new CompoundStmt( noLabels ); 221 statement->push_back( 222 new ReturnStmt( 223 noLabels, 224 new AddressExpr( 225 new UntypedMemberExpr( 226 new NameExpr( "__cor" ), 227 new UntypedExpr( 228 new NameExpr( "*?" ), 229 { new NameExpr( "this" ) } 230 ) 231 ) 232 ) 233 ) 234 ); 235 236 FunctionDecl * get_decl = new FunctionDecl( 237 "get_coroutine", 238 Type::Static, 239 LinkageSpec::Cforall, 240 type, 241 statement, 242 noAttributes, 243 Type::Inline 244 ); 245 246 declsToAddAfter.push_back( get_decl ); 247 248 get_decl->fixUniqueId(); 249 } 250 251 252 //============================================================================================= 126 253 // Mutex keyword implementation 127 254 //============================================================================================= … … 137 264 if( ! body ) return; 138 265 139 assert(monitor_decl); 266 if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 267 if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 268 140 269 addStatments( body, mutexArgs ); 141 270 } … … 146 275 monitor_decl = decl; 147 276 } 277 else if( decl->get_name() == "monitor_guard_t" ) { 278 assert( !guard_decl ); 279 guard_decl = decl; 280 } 148 281 } 149 282 … … 175 308 176 309 //Make sure that typed isn't mutex 177 if( !base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );310 if( base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg ); 178 311 } 179 312 180 313 void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) { 181 182 314 ObjectDecl * monitors = new ObjectDecl( 183 315 "__monitors", … … 199 331 ), 200 332 new ListInit( 201 map_range < std::list<Initializer*> > ( args, [](DeclarationWithType * var ){ 333 map_range < std::list<Initializer*> > ( args, [this](DeclarationWithType * var ){ 334 Type * type = var->get_type()->clone(); 335 type->set_mutex( false ); 202 336 return new SingleInit( new UntypedExpr( 203 337 new NameExpr( "get_monitor" ), 204 { new VariableExpr( var) }338 { new CastExpr( new VariableExpr( var ), type ) } 205 339 ) ); 206 340 }) … … 218 352 new StructInstType( 219 353 noQualifiers, 220 "monitor_guard_t"354 guard_decl 221 355 ), 222 356 new ListInit( … … 224 358 new SingleInit( new VariableExpr( monitors ) ), 225 359 new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) ) 226 } 360 }, 361 noDesignators, 362 true 227 363 ) 228 364 )) 229 365 ); 230 366 231 //monitor_desc * __monitors[] = { a, b};367 //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) }; 232 368 body->push_front( new DeclStmt( noLabels, monitors) ); 233 369 }
Note: See TracChangeset
for help on using the changeset viewer.