// // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // Keywords.cc -- // // Author : Thierry Delisle // Created On : Mon Mar 13 12:41:22 2017 // Last Modified By : // Last Modified On : // Update Count : 10 // #include "Concurrency/Keywords.h" #include // for assert #include // for string, operator== #include #include "Common/Examine.h" // for isMainFor #include "Common/PassVisitor.h" // for PassVisitor #include "Common/SemanticError.h" // for SemanticError #include "Common/utility.h" // for deleteAll, map_range #include "CodeGen/OperatorTable.h" // for isConstructor #include "ControlStruct/LabelGenerator.h" // for LebelGenerator #include "InitTweak/InitTweak.h" // for getPointerBase #include "SynTree/LinkageSpec.h" // for Cforall #include "SynTree/Constant.h" // for Constant #include "SynTree/Declaration.h" // for StructDecl, FunctionDecl, ObjectDecl #include "SynTree/Expression.h" // for VariableExpr, ConstantExpr, Untype... #include "SynTree/Initializer.h" // for SingleInit, ListInit, Initializer ... #include "SynTree/Label.h" // for Label #include "SynTree/Statement.h" // for CompoundStmt, DeclStmt, ExprStmt #include "SynTree/Type.h" // for StructInstType, Type, PointerType #include "SynTree/Visitor.h" // for Visitor, acceptAll #include "Virtual/Tables.h" class Attribute; namespace Concurrency { inline static std::string getTypeIdName( std::string const & exception_name ) { return exception_name.empty() ? std::string() : Virtual::typeIdType( exception_name ); } inline static std::string getVTableName( std::string const & exception_name ) { return exception_name.empty() ? std::string() : Virtual::vtableTypeName( exception_name ); } // Only detects threads constructed with the keyword thread. inline static bool isThread( DeclarationWithType * decl ) { Type * baseType = decl->get_type()->stripDeclarator(); StructInstType * instType = dynamic_cast( baseType ); if ( nullptr == instType ) { return false; } return instType->baseStruct->is_thread(); } //============================================================================================= // Pass declarations //============================================================================================= //----------------------------------------------------------------------------- //Handles sue type declarations : // sue MyType { struct MyType { // int data; int data; // a_struct_t more_data; a_struct_t more_data; // => NewField_t newField; // }; }; // static inline NewField_t * getter_name( MyType * this ) { return &this->newField; } // class ConcurrentSueKeyword : public WithDeclsToAdd { public: ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, std::string&& exception_name, bool needs_main, AggregateDecl::Aggregate cast_target ) : type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ), exception_name( exception_name ), typeid_name( getTypeIdName( exception_name ) ), vtable_name( getVTableName( exception_name ) ), needs_main( needs_main ), cast_target( cast_target ) {} virtual ~ConcurrentSueKeyword() {} Declaration * postmutate( StructDecl * decl ); DeclarationWithType * postmutate( FunctionDecl * decl ); void handle( StructDecl * ); void addTypeId( StructDecl * ); void addVtableForward( StructDecl * ); FunctionDecl * forwardDeclare( StructDecl * ); ObjectDecl * addField( StructDecl * ); void addRoutines( ObjectDecl *, FunctionDecl * ); virtual bool is_target( StructDecl * decl ) = 0; Expression * postmutate( KeywordCastExpr * cast ); private: const std::string type_name; const std::string field_name; const std::string getter_name; const std::string context_error; const std::string exception_name; const std::string typeid_name; const std::string vtable_name; bool needs_main; AggregateDecl::Aggregate cast_target; StructDecl * type_decl = nullptr; FunctionDecl * dtor_decl = nullptr; StructDecl * except_decl = nullptr; StructDecl * typeid_decl = nullptr; StructDecl * vtable_decl = nullptr; }; //----------------------------------------------------------------------------- //Handles thread type declarations : // thread Mythread { struct MyThread { // int data; int data; // a_struct_t more_data; a_struct_t more_data; // => $thread __thrd_d; // }; }; // static inline $thread * get_thread( MyThread * this ) { return &this->__thrd_d; } // class ThreadKeyword final : public ConcurrentSueKeyword { public: ThreadKeyword() : ConcurrentSueKeyword( "$thread", "__thrd", "get_thread", "thread keyword requires threads to be in scope, add #include \n", "ThreadCancelled", true, AggregateDecl::Thread ) {} virtual ~ThreadKeyword() {} virtual bool is_target( StructDecl * decl ) override final { return decl->is_thread(); } static void implement( std::list< Declaration * > & translationUnit ) { PassVisitor< ThreadKeyword > impl; mutateAll( translationUnit, impl ); } }; //----------------------------------------------------------------------------- //Handles coroutine type declarations : // coroutine MyCoroutine { struct MyCoroutine { // int data; int data; // a_struct_t more_data; a_struct_t more_data; // => $coroutine __cor_d; // }; }; // static inline $coroutine * get_coroutine( MyCoroutine * this ) { return &this->__cor_d; } // class CoroutineKeyword final : public ConcurrentSueKeyword { public: CoroutineKeyword() : ConcurrentSueKeyword( "$coroutine", "__cor", "get_coroutine", "coroutine keyword requires coroutines to be in scope, add #include \n", "CoroutineCancelled", true, AggregateDecl::Coroutine ) {} virtual ~CoroutineKeyword() {} virtual bool is_target( StructDecl * decl ) override final { return decl->is_coroutine(); } static void implement( std::list< Declaration * > & translationUnit ) { PassVisitor< CoroutineKeyword > impl; mutateAll( translationUnit, impl ); } }; //----------------------------------------------------------------------------- //Handles monitor type declarations : // monitor MyMonitor { struct MyMonitor { // int data; int data; // a_struct_t more_data; a_struct_t more_data; // => $monitor __mon_d; // }; }; // static inline $monitor * get_coroutine( MyMonitor * this ) { return &this->__cor_d; } // class MonitorKeyword final : public ConcurrentSueKeyword { public: MonitorKeyword() : ConcurrentSueKeyword( "$monitor", "__mon", "get_monitor", "monitor keyword requires monitors to be in scope, add #include \n", "", false, AggregateDecl::Monitor ) {} virtual ~MonitorKeyword() {} virtual bool is_target( StructDecl * decl ) override final { return decl->is_monitor(); } static void implement( std::list< Declaration * > & translationUnit ) { PassVisitor< MonitorKeyword > impl; mutateAll( translationUnit, impl ); } }; //----------------------------------------------------------------------------- //Handles generator type declarations : // generator MyGenerator { struct MyGenerator { // int data; int data; // a_struct_t more_data; a_struct_t more_data; // => int __gen_next; // }; }; // class GeneratorKeyword final : public ConcurrentSueKeyword { public: GeneratorKeyword() : ConcurrentSueKeyword( "$generator", "__generator_state", "get_generator", "Unable to find builtin type $generator\n", "", true, AggregateDecl::Generator ) {} virtual ~GeneratorKeyword() {} virtual bool is_target( StructDecl * decl ) override final { return decl->is_generator(); } static void implement( std::list< Declaration * > & translationUnit ) { PassVisitor< GeneratorKeyword > impl; mutateAll( translationUnit, impl ); } }; //----------------------------------------------------------------------------- class SuspendKeyword final : public WithStmtsToAdd, public WithGuards { public: SuspendKeyword() = default; virtual ~SuspendKeyword() = default; void premutate( FunctionDecl * ); DeclarationWithType * postmutate( FunctionDecl * ); Statement * postmutate( SuspendStmt * ); static void implement( std::list< Declaration * > & translationUnit ) { PassVisitor< SuspendKeyword > impl; mutateAll( translationUnit, impl ); } private: bool is_real_suspend( FunctionDecl * ); Statement * make_generator_suspend( SuspendStmt * ); Statement * make_coroutine_suspend( SuspendStmt * ); struct LabelPair { Label obj; int idx; }; LabelPair make_label() { labels.push_back( gen.newLabel("generator") ); return { labels.back(), int(labels.size()) }; } DeclarationWithType * in_generator = nullptr; FunctionDecl * decl_suspend = nullptr; std::vector