Changeset bcda04c
- Timestamp:
- Mar 23, 2017, 11:37:27 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:
- bd4d011
- Parents:
- 578b637
- Location:
- src
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Keywords.cc
r578b637 rbcda04c 21 21 #include "SynTree/Expression.h" 22 22 #include "SynTree/Initializer.h" 23 #include "SynTree/Mutator.h"24 23 #include "SynTree/Statement.h" 25 24 #include "SynTree/Type.h" … … 38 37 // Visitors declaration 39 38 //============================================================================================= 39 40 //----------------------------------------------------------------------------- 41 //Handles sue type declarations : 42 // sue MyType { struct MyType { 43 // int data; int data; 44 // a_struct_t more_data; a_struct_t more_data; 45 // => NewField_t newField; 46 // }; }; 47 // static inline NewField_t * getter_name( MyType * this ) { return &this->newField; } 48 // 49 class ConcurrentSueKeyword : public Visitor { 50 protected: 51 template< typename Visitor > 52 friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor ); 53 public: 54 55 ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error ) : 56 type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ) {} 57 58 virtual ~ConcurrentSueKeyword() {} 59 60 using Visitor::visit; 61 virtual void visit( StructDecl * decl ) override final; 62 63 void handle( StructDecl * ); 64 FunctionDecl * forwardDeclare( StructDecl * ); 65 ObjectDecl * addField( StructDecl * ); 66 void addRoutines( StructDecl *, ObjectDecl *, FunctionDecl * ); 67 68 virtual bool is_target( StructDecl * decl ) = 0; 69 70 private: 71 const std::string type_name; 72 const std::string field_name; 73 const std::string getter_name; 74 const std::string context_error; 75 76 std::list< Declaration * > declsToAdd, declsToAddAfter; 77 StructDecl* type_decl = nullptr; 78 }; 79 40 80 41 81 //----------------------------------------------------------------------------- … … 47 87 // }; }; 48 88 // static inline thread_desc * get_thread( MyThread * this ) { return &this->__thrd_d; } 49 // void main( MyThread * this );50 89 // 51 class ThreadKeyword final : public Mutator{90 class ThreadKeyword final : public ConcurrentSueKeyword { 52 91 public: 53 92 54 static void implement( std::list< Declaration * > & translationUnit ) {} 93 ThreadKeyword() : ConcurrentSueKeyword( 94 "thread_desc", 95 "__thrd", 96 "get_thread", 97 "thread keyword requires threads to be in scope, add #include <thread>" 98 ) 99 {} 100 101 virtual ~ThreadKeyword() {} 102 103 virtual bool is_target( StructDecl * decl ) override final { return decl->is_thread(); } 104 105 static void implement( std::list< Declaration * > & translationUnit ) { 106 ThreadKeyword impl; 107 SymTab::acceptAndAdd( translationUnit, impl ); 108 } 55 109 }; 56 110 … … 63 117 // }; }; 64 118 // static inline coroutine_desc * get_coroutine( MyCoroutine * this ) { return &this->__cor_d; } 65 // void main( MyCoroutine * this );66 119 // 67 class CoroutineKeyword final : public Visitor { 68 template< typename Visitor > 69 friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor ); 120 class CoroutineKeyword final : public ConcurrentSueKeyword { 70 121 public: 71 122 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 * ); 123 CoroutineKeyword() : ConcurrentSueKeyword( 124 "coroutine_desc", 125 "__cor", 126 "get_coroutine", 127 "coroutine keyword requires coroutines to be in scope, add #include <coroutine>" 128 ) 129 {} 130 131 virtual ~CoroutineKeyword() {} 132 133 virtual bool is_target( StructDecl * decl ) override final { return decl->is_coroutine(); } 78 134 79 135 static void implement( std::list< Declaration * > & translationUnit ) { … … 81 137 SymTab::acceptAndAdd( translationUnit, impl ); 82 138 } 83 84 private:85 std::list< Declaration * > declsToAdd, declsToAddAfter;86 StructDecl* coroutine_decl = nullptr;87 139 }; 88 140 … … 95 147 // }; }; 96 148 // static inline monitor_desc * get_coroutine( MyMonitor * this ) { return &this->__cor_d; } 97 // void main( MyMonitor * this );98 149 // 99 class MonitorKeyword final : public Mutator{150 class MonitorKeyword final : public ConcurrentSueKeyword { 100 151 public: 101 152 102 static void implement( std::list< Declaration * > & translationUnit ) {} 153 MonitorKeyword() : ConcurrentSueKeyword( 154 "monitor_desc", 155 "__mon", 156 "get_monitor", 157 "monitor keyword requires monitors to be in scope, add #include <monitor>" 158 ) 159 {} 160 161 virtual ~MonitorKeyword() {} 162 163 virtual bool is_target( StructDecl * decl ) override final { return decl->is_monitor(); } 164 165 static void implement( std::list< Declaration * > & translationUnit ) { 166 MonitorKeyword impl; 167 SymTab::acceptAndAdd( translationUnit, impl ); 168 } 103 169 }; 104 170 … … 139 205 CoroutineKeyword ::implement( translationUnit ); 140 206 MonitorKeyword ::implement( translationUnit ); 207 } 208 209 void implementMutexFuncs( std::list< Declaration * > & translationUnit ) { 141 210 MutexKeyword ::implement( translationUnit ); 142 211 } 143 212 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() ) { 213 void implementThreadStarter( std::list< Declaration * > & translationUnit ) { 214 215 } 216 217 //============================================================================================= 218 // Generic keyword implementation 219 //============================================================================================= 220 void ConcurrentSueKeyword::visit(StructDecl * decl) { 221 if( decl->get_name() == type_name ) { 222 assert( !type_decl ); 223 type_decl = decl; 224 } 225 else if ( is_target(decl) ) { 153 226 handle( decl ); 154 227 } … … 156 229 } 157 230 158 void Co routineKeyword::handle( StructDecl * decl ) {231 void ConcurrentSueKeyword::handle( StructDecl * decl ) { 159 232 if( ! decl->has_body() ) return; 160 233 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", 234 if( !type_decl ) throw SemanticError( context_error, decl ); 235 236 FunctionDecl * func = forwardDeclare( decl ); 237 ObjectDecl * field = addField( decl ); 238 addRoutines( decl, field, func ); 239 } 240 241 FunctionDecl * ConcurrentSueKeyword::forwardDeclare( StructDecl * decl ) { 242 243 StructDecl * forward = decl->clone(); 244 forward->set_body( false ); 245 deleteAll( forward->get_members() ); 246 forward->get_members().clear(); 247 248 FunctionType * type = new FunctionType( noQualifiers, false ); 249 ObjectDecl * this_decl = new ObjectDecl( 250 "this", 170 251 noStorage, 171 252 LinkageSpec::Cforall, 172 253 nullptr, 173 new StructInstType(254 new PointerType( 174 255 noQualifiers, 175 coroutine_decl 256 new StructInstType( 257 noQualifiers, 258 decl 259 ) 176 260 ), 177 261 nullptr 178 262 ); 179 263 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 ); 264 type->get_parameters().push_back( this_decl ); 203 265 type->get_returnVals().push_back( 204 266 new ObjectDecl( … … 211 273 new StructInstType( 212 274 noQualifiers, 213 coroutine_decl275 type_decl 214 276 ) 215 277 ), … … 218 280 ); 219 281 282 FunctionDecl * get_decl = new FunctionDecl( 283 getter_name, 284 Type::Static, 285 LinkageSpec::Cforall, 286 type, 287 nullptr, 288 noAttributes, 289 Type::Inline 290 ); 291 292 declsToAdd.push_back( forward ); 293 declsToAdd.push_back( get_decl ); 294 295 return get_decl; 296 } 297 298 ObjectDecl * ConcurrentSueKeyword::addField( StructDecl * decl ) { 299 ObjectDecl * field = new ObjectDecl( 300 field_name, 301 noStorage, 302 LinkageSpec::Cforall, 303 nullptr, 304 new StructInstType( 305 noQualifiers, 306 type_decl 307 ), 308 nullptr 309 ); 310 311 decl->get_members().push_back( field ); 312 313 return field; 314 } 315 316 void ConcurrentSueKeyword::addRoutines( StructDecl * decl, ObjectDecl * field, FunctionDecl * func ) { 220 317 CompoundStmt * statement = new CompoundStmt( noLabels ); 221 318 statement->push_back( … … 223 320 noLabels, 224 321 new AddressExpr( 225 new UntypedMemberExpr( 226 new NameExpr( "__cor" ), 227 new UntypedExpr( 228 new NameExpr( "*?" ), 229 { new NameExpr( "this" ) } 230 ) 322 new MemberExpr( 323 field, 324 UntypedExpr::createDeref( new VariableExpr( func->get_functionType()->get_parameters().front() ) ) 231 325 ) 232 326 ) … … 234 328 ); 235 329 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 ); 330 FunctionDecl * get_decl = func->clone(); 331 332 get_decl->set_statements( statement ); 245 333 246 334 declsToAddAfter.push_back( get_decl ); 247 335 248 get_decl->fixUniqueId(); 249 } 250 336 // get_decl->fixUniqueId(); 337 } 251 338 252 339 //============================================================================================= -
src/Concurrency/Keywords.h
r578b637 rbcda04c 24 24 namespace Concurrency { 25 25 void applyKeywords( std::list< Declaration * > & translationUnit ); 26 void implementMutexFuncs( std::list< Declaration * > & translationUnit ); 27 void implementThreadStarter( std::list< Declaration * > & translationUnit ); 26 28 }; 27 29 -
src/Parser/lex.ll
r578b637 rbcda04c 236 236 long { KEYWORD_RETURN(LONG); } 237 237 lvalue { KEYWORD_RETURN(LVALUE); } // CFA 238 _Monitor { KEYWORD_RETURN(MONITOR); } // CFA238 monitor { KEYWORD_RETURN(MONITOR); } // CFA 239 239 mutex { KEYWORD_RETURN(MUTEX); } // CFA 240 240 _Noreturn { KEYWORD_RETURN(NORETURN); } // C11 -
src/SymTab/Autogen.cc
r578b637 rbcda04c 218 218 219 219 /// generates a function (?{}, ?=?, ^?{}) based on the data argument and members. If function is generated, inserts the type into the map. 220 void gen( const FuncData & data ) {220 void gen( const FuncData & data, bool concurrent_type ) { 221 221 if ( ! shouldGenerate( data.map, aggregateDecl ) ) return; 222 222 FunctionType * ftype = data.genType( refType ); 223 224 if(concurrent_type && InitTweak::isDestructor( data.fname )) { 225 ftype->get_parameters().front()->get_type()->set_mutex( true ); 226 } 227 223 228 cloneAll( typeParams, ftype->get_forall() ); 224 229 *out++ = genFunc( data.fname, ftype, functionNesting ); … … 403 408 auto generator = makeFuncGenerator( aggregateDecl, refType, functionNesting, typeParams, back_inserter( newFuncs ) ); 404 409 for ( const FuncData & d : data ) { 405 generator.gen( d ); 406 } 410 generator.gen( d, aggregateDecl->is_thread() || aggregateDecl->is_monitor() ); 411 } 412 407 413 // field ctors are only generated if default constructor and copy constructor are both generated 408 414 unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return InitTweak::isConstructor( dcl->get_name() ); } ); -
src/SymTab/Validate.cc
r578b637 rbcda04c 43 43 #include "Common/utility.h" 44 44 #include "Common/UniqueName.h" 45 #include "Concurrency/Keywords.h" 45 46 #include "Validate.h" 46 47 #include "SynTree/Visitor.h" … … 225 226 ReturnTypeFixer::fix( translationUnit ); // must happen before autogen 226 227 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions 228 Concurrency::applyKeywords( translationUnit ); 227 229 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecayPass 230 Concurrency::implementMutexFuncs( translationUnit ); 231 Concurrency::implementThreadStarter( translationUnit ); 228 232 acceptAll( translationUnit, epc ); 229 233 ReturnChecker::checkFunctionReturns( translationUnit ); -
src/main.cc
r578b637 rbcda04c 216 216 } // if 217 217 218 // OPTPRINT( "Concurrency" ) 219 // Concurrency::applyKeywords( translationUnit ); 220 218 221 // add the assignment statement after the initialization of a type parameter 219 222 OPTPRINT( "validate" ) … … 237 240 OPTPRINT( "mutate" ) 238 241 ControlStruct::mutate( translationUnit ); 239 OPTPRINT( "Concurrency" )240 Concurrency::applyKeywords( translationUnit );241 242 OPTPRINT( "fixNames" ) 242 243 CodeGen::fixNames( translationUnit ); -
src/tests/monitor.c
r578b637 rbcda04c 4 4 #include <thread> 5 5 6 structglobal_t {6 monitor global_t { 7 7 int value; 8 monitor_desc m;9 8 }; 10 9 11 10 void ?{}(global_t * this) { 12 11 this->value = 0; 13 }14 15 monitor_desc * get_monitor( global_t * this ) {16 return &this->m;17 12 } 18 13 … … 45 40 46 41 int main(int argc, char* argv[]) { 47 assert( global. m.entry_queue.tail != NULL );42 assert( global.__mon.entry_queue.tail != NULL ); 48 43 processor p; 49 44 { -
src/tests/multi-monitor.c
r578b637 rbcda04c 6 6 static int global12, global23, global13; 7 7 8 struct monitor_t { 9 monitor_desc m; 10 }; 11 12 monitor_desc * get_monitor( monitor_t * this ) { 13 return &this->m; 14 } 8 monitor monitor_t {}; 15 9 16 10 static monitor_t m1, m2, m3;
Note: See TracChangeset
for help on using the changeset viewer.