Changeset 4f6dda0


Ignore:
Timestamp:
Mar 11, 2022, 11:08:19 AM (19 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum
Children:
630c4bb
Parents:
b053083
Message:

Converted Implement Concurrent Keywords to the new AST. Includes updates to various helpers, including the virtual table and a lot of examine helpers.

Files:
2 added
9 edited
2 moved

Legend:

Unmodified
Added
Removed
  • src/AST/GenericSubstitution.cpp

    rb053083 r4f6dda0  
    4545                        visit_children = false;
    4646                        const AggregateDecl * aggr = ty->aggr();
    47                         sub = TypeSubstitution{ aggr->params.begin(), aggr->params.end(), ty->params.begin() };
     47                        sub = TypeSubstitution( aggr->params, ty->params );
    4848                }
    4949
  • src/AST/TypeSubstitution.hpp

    rb053083 r4f6dda0  
    3737  public:
    3838        TypeSubstitution();
     39        template< typename FormalContainer, typename ActualContainer >
     40        TypeSubstitution( FormalContainer formals, ActualContainer actuals );
    3941        template< typename FormalIterator, typename ActualIterator >
    4042        TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
     
    7678        bool empty() const;
    7779
     80        template< typename FormalContainer, typename ActualContainer >
     81        void addAll( FormalContainer formals, ActualContainer actuals );
    7882        template< typename FormalIterator, typename ActualIterator >
    79         void add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
     83        void addAll( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
    8084
    8185        /// create a new TypeSubstitution using bindings from env containing all of the type variables in expr
     
    112116};
    113117
     118template< typename FormalContainer, typename ActualContainer >
     119TypeSubstitution::TypeSubstitution( FormalContainer formals, ActualContainer actuals ) {
     120        assert( formals.size() == actuals.size() );
     121        addAll( formals.begin(), formals.end(), actuals.begin() );
     122}
     123
     124template< typename FormalIterator, typename ActualIterator >
     125TypeSubstitution::TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) {
     126        addAll( formalBegin, formalEnd, actualBegin );
     127}
     128
     129template< typename FormalContainer, typename ActualContainer >
     130void TypeSubstitution::addAll( FormalContainer formals, ActualContainer actuals ) {
     131        assert( formals.size() == actuals.size() );
     132        addAll( formals.begin(), formals.end(), actuals.begin() );
     133}
     134
    114135// this is the only place where type parameters outside a function formal may be substituted.
    115136template< typename FormalIterator, typename ActualIterator >
    116 void TypeSubstitution::add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) {
     137void TypeSubstitution::addAll( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) {
    117138        // FormalIterator points to a TypeDecl
    118139        // ActualIterator points to a Type
     
    129150                        } // if
    130151                } else {
    131                        
     152                        // Is this an error?
    132153                } // if
    133154        } // for
    134155}
    135 
    136 
    137 
    138 template< typename FormalIterator, typename ActualIterator >
    139 TypeSubstitution::TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) {
    140         add( formalBegin, formalEnd, actualBegin );
    141 }
    142 
    143156
    144157} // namespace ast
  • src/Common/Examine.cc

    rb053083 r4f6dda0  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Examine.h --
     7// Examine.cc -- Helpers for examining AST code.
    88//
    99// Author           : Andrew Beach
    1010// Created On       : Wed Sept 2 14:02 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Sep  8 12:15 2020
    13 // Update Count     : 0
     12// Last Modified On : Fri Dec 10 10:27 2021
     13// Update Count     : 1
    1414//
    1515
    1616#include "Common/Examine.h"
    1717
     18#include "AST/Type.hpp"
    1819#include "CodeGen/OperatorTable.h"
     20#include "InitTweak/InitTweak.h"
    1921
    2022DeclarationWithType * isMainFor( FunctionDecl * func, AggregateDecl::Aggregate kind ) {
     
    3638
    3739namespace {
     40
     41// getTypeofThis but does some extra checks used in this module.
     42const ast::Type * getTypeofThisSolo( const ast::FunctionDecl * func ) {
     43        if ( 1 != func->params.size() ) {
     44                return nullptr;
     45        }
     46        auto ref = func->type->params.front().as<ast::ReferenceType>();
     47        return (ref) ? ref->base : nullptr;
     48}
     49
     50}
     51
     52const ast::DeclWithType * isMainFor(
     53                const ast::FunctionDecl * func, ast::AggregateDecl::Aggregate kind ) {
     54        if ( "main" != func->name ) return nullptr;
     55        if ( 1 != func->params.size() ) return nullptr;
     56
     57        auto param = func->params.front();
     58
     59        auto type = dynamic_cast<const ast::ReferenceType *>( param->get_type() );
     60        if ( !type ) return nullptr;
     61
     62        auto obj = type->base.as<ast::StructInstType>();
     63        if ( !obj ) return nullptr;
     64
     65        if ( kind != obj->base->kind ) return nullptr;
     66
     67        return param;
     68}
     69
     70namespace {
    3871        Type * getDestructorParam( FunctionDecl * func ) {
    3972                if ( !CodeGen::isDestructor( func->name ) ) return nullptr;
     
    4881                return nullptr;
    4982        }
     83
     84const ast::Type * getDestructorParam( const ast::FunctionDecl * func ) {
     85        if ( !CodeGen::isDestructor( func->name ) ) return nullptr;
     86        //return InitTweak::getParamThis( func )->type;
     87        return getTypeofThisSolo( func );
     88}
     89
    5090}
    5191
     
    5797        return false;
    5898}
     99
     100bool isDestructorFor(
     101                const ast::FunctionDecl * func, const ast::StructDecl * type_decl ) {
     102        if ( const ast::Type * type = getDestructorParam( func ) ) {
     103                auto stype = dynamic_cast<const ast::StructInstType *>( type );
     104                return stype && stype->base.get() == type_decl;
     105        }
     106        return false;
     107}
  • src/Common/Examine.h

    rb053083 r4f6dda0  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Examine.h --
     7// Examine.h -- Helpers for examining AST code.
    88//
    99// Author           : Andrew Beach
    1010// Created On       : Wed Sept 2 13:57 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Sep  8 12:08 2020
    13 // Update Count     : 0
     12// Last Modified On : Fri Dec 10 10:28 2021
     13// Update Count     : 1
    1414//
    1515
     16#include "AST/Decl.hpp"
    1617#include "SynTree/Declaration.h"
    1718
    1819/// Check if this is a main function for a type of an aggregate kind.
    1920DeclarationWithType * isMainFor( FunctionDecl * func, AggregateDecl::Aggregate kind );
     21const ast::DeclWithType * isMainFor(
     22        const ast::FunctionDecl * func, ast::AggregateDecl::Aggregate kind );
    2023// Returns a pointer to the parameter if true, nullptr otherwise.
    2124
    2225/// Check if this function is a destructor for the given structure.
    2326bool isDestructorFor( FunctionDecl * func, StructDecl * type_decl );
     27bool isDestructorFor(
     28        const ast::FunctionDecl * func, const ast::StructDecl * type );
  • src/Concurrency/KeywordsNew.cpp

    rb053083 r4f6dda0  
    1010// Created On       : Tue Nov 16  9:53:00 2021
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Dec  1 11:24:00 2021
    13 // Update Count     : 1
     12// Last Modified On : Fri Mar 11 10:40:00 2022
     13// Update Count     : 2
    1414//
    1515
     
    1818#include "AST/Copy.hpp"
    1919#include "AST/Decl.hpp"
     20#include "AST/Expr.hpp"
    2021#include "AST/Pass.hpp"
    2122#include "AST/Stmt.hpp"
     23#include "AST/DeclReplacer.hpp"
    2224#include "AST/TranslationUnit.hpp"
    2325#include "CodeGen/OperatorTable.h"
     26#include "Common/Examine.h"
    2427#include "Common/utility.h"
     28#include "ControlStruct/LabelGeneratorNew.hpp"
    2529#include "InitTweak/InitTweak.h"
     30#include "Virtual/Tables.h"
    2631
    2732namespace Concurrency {
     
    2934namespace {
    3035
    31 inline static bool isThread( const ast::DeclWithType * decl ) {
     36// --------------------------------------------------------------------------
     37// Loose Helper Functions:
     38
     39/// Detect threads constructed with the keyword thread.
     40bool isThread( const ast::DeclWithType * decl ) {
    3241        auto baseType = decl->get_type()->stripDeclarator();
    3342        auto instType = dynamic_cast<const ast::StructInstType *>( baseType );
    3443        if ( nullptr == instType ) { return false; }
    3544        return instType->base->is_thread();
     45}
     46
     47/// Get the virtual type id if given a type name.
     48std::string typeIdType( std::string const & exception_name ) {
     49        return exception_name.empty() ? std::string()
     50                : Virtual::typeIdType( exception_name );
     51}
     52
     53/// Get the vtable type name if given a type name.
     54std::string vtableTypeName( std::string const & exception_name ) {
     55        return exception_name.empty() ? std::string()
     56                : Virtual::vtableTypeName( exception_name );
     57}
     58
     59static ast::Type * mutate_under_references( ast::ptr<ast::Type>& type ) {
     60        ast::Type * mutType = type.get_and_mutate();
     61        for ( ast::ReferenceType * mutRef
     62                ; (mutRef = dynamic_cast<ast::ReferenceType *>( mutType ))
     63                ; mutType = mutRef->base.get_and_mutate() );
     64        return mutType;
     65}
     66
     67// Describe that it adds the generic parameters and the uses of the generic
     68// parameters on the function and first "this" argument.
     69ast::FunctionDecl * fixupGenerics(
     70                const ast::FunctionDecl * func, const ast::StructDecl * decl ) {
     71        const CodeLocation & location = decl->location;
     72        // We have to update both the declaration
     73        auto mutFunc = ast::mutate( func );
     74        auto mutType = mutFunc->type.get_and_mutate();
     75
     76        if ( decl->params.empty() ) {
     77                return mutFunc;
     78        }
     79
     80        assert( 0 != mutFunc->params.size() );
     81        assert( 0 != mutType->params.size() );
     82
     83        // Add the "forall" clause information.
     84        for ( const ast::ptr<ast::TypeDecl> & typeParam : decl->params ) {
     85                auto typeDecl = ast::deepCopy( typeParam );
     86                mutFunc->type_params.push_back( typeDecl );
     87                mutType->forall.push_back(
     88                        new ast::TypeInstType( typeDecl->name, typeDecl ) );
     89                for ( auto & assertion : typeDecl->assertions ) {
     90                        mutFunc->assertions.push_back( assertion );
     91                        mutType->assertions.emplace_back(
     92                                new ast::VariableExpr( location, assertion ) );
     93                }
     94                typeDecl->assertions.clear();
     95        }
     96
     97        // Even chain_mutate is not powerful enough for this:
     98        ast::ptr<ast::Type>& paramType = strict_dynamic_cast<ast::ObjectDecl *>(
     99                mutFunc->params[0].get_and_mutate() )->type;
     100        auto paramTypeInst = strict_dynamic_cast<ast::StructInstType *>(
     101                mutate_under_references( paramType ) );
     102        auto typeParamInst = strict_dynamic_cast<ast::StructInstType *>(
     103                mutate_under_references( mutType->params[0] ) );
     104
     105        for ( const ast::ptr<ast::TypeDecl> & typeDecl : mutFunc->type_params ) {
     106                paramTypeInst->params.push_back(
     107                        new ast::TypeExpr( location,
     108                                new ast::TypeInstType( typeDecl->name, typeDecl ) ) );
     109                typeParamInst->params.push_back(
     110                        new ast::TypeExpr( location,
     111                                new ast::TypeInstType( typeDecl->name, typeDecl ) ) );
     112        }
     113
     114        return mutFunc;
     115}
     116
     117// --------------------------------------------------------------------------
     118struct ConcurrentSueKeyword : public ast::WithDeclsToAdd<> {
     119        ConcurrentSueKeyword(
     120                std::string&& type_name, std::string&& field_name,
     121                std::string&& getter_name, std::string&& context_error,
     122                std::string&& exception_name,
     123                bool needs_main, ast::AggregateDecl::Aggregate cast_target
     124        ) :
     125                type_name( type_name ), field_name( field_name ),
     126                getter_name( getter_name ), context_error( context_error ),
     127                exception_name( exception_name ),
     128                typeid_name( typeIdType( exception_name ) ),
     129                vtable_name( vtableTypeName( exception_name ) ),
     130                needs_main( needs_main ), cast_target( cast_target )
     131        {}
     132
     133        virtual ~ConcurrentSueKeyword() {}
     134
     135        const ast::Decl * postvisit( const ast::StructDecl * decl );
     136        const ast::DeclWithType * postvisit( const ast::FunctionDecl * decl );
     137        const ast::Expr * postvisit( const ast::KeywordCastExpr * expr );
     138
     139        struct StructAndField {
     140                const ast::StructDecl * decl;
     141                const ast::ObjectDecl * field;
     142        };
     143
     144        const ast::StructDecl * handleStruct( const ast::StructDecl * );
     145        void handleMain( const ast::FunctionDecl *, const ast::StructInstType * );
     146        void addTypeId( const ast::StructDecl * );
     147        void addVtableForward( const ast::StructDecl * );
     148        const ast::FunctionDecl * forwardDeclare( const ast::StructDecl * );
     149        StructAndField addField( const ast::StructDecl * );
     150        void addGetRoutines( const ast::ObjectDecl *, const ast::FunctionDecl * );
     151        void addLockUnlockRoutines( const ast::StructDecl * );
     152
     153private:
     154        const std::string type_name;
     155        const std::string field_name;
     156        const std::string getter_name;
     157        const std::string context_error;
     158        const std::string exception_name;
     159        const std::string typeid_name;
     160        const std::string vtable_name;
     161        const bool needs_main;
     162        const ast::AggregateDecl::Aggregate cast_target;
     163
     164        const ast::StructDecl   * type_decl = nullptr;
     165        const ast::FunctionDecl * dtor_decl = nullptr;
     166        const ast::StructDecl * except_decl = nullptr;
     167        const ast::StructDecl * typeid_decl = nullptr;
     168        const ast::StructDecl * vtable_decl = nullptr;
     169};
     170
     171// Handles thread type declarations:
     172//
     173// thread Mythread {                         struct MyThread {
     174//  int data;                                  int data;
     175//  a_struct_t more_data;                      a_struct_t more_data;
     176//                                =>             thread$ __thrd_d;
     177// };                                        };
     178//                                           static inline thread$ * get_thread( MyThread * this ) { return &this->__thrd_d; }
     179//
     180struct ThreadKeyword final : public ConcurrentSueKeyword {
     181        ThreadKeyword() : ConcurrentSueKeyword(
     182                "thread$",
     183                "__thrd",
     184                "get_thread",
     185                "thread keyword requires threads to be in scope, add #include <thread.hfa>\n",
     186                "ThreadCancelled",
     187                true,
     188                ast::AggregateDecl::Thread )
     189        {}
     190
     191        virtual ~ThreadKeyword() {}
     192};
     193
     194// Handles coroutine type declarations:
     195//
     196// coroutine MyCoroutine {                   struct MyCoroutine {
     197//  int data;                                  int data;
     198//  a_struct_t more_data;                      a_struct_t more_data;
     199//                                =>             coroutine$ __cor_d;
     200// };                                        };
     201//                                           static inline coroutine$ * get_coroutine( MyCoroutine * this ) { return &this->__cor_d; }
     202//
     203struct CoroutineKeyword final : public ConcurrentSueKeyword {
     204        CoroutineKeyword() : ConcurrentSueKeyword(
     205                "coroutine$",
     206                "__cor",
     207                "get_coroutine",
     208                "coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>\n",
     209                "CoroutineCancelled",
     210                true,
     211                ast::AggregateDecl::Coroutine )
     212        {}
     213
     214        virtual ~CoroutineKeyword() {}
     215};
     216
     217// Handles monitor type declarations:
     218//
     219// monitor MyMonitor {                       struct MyMonitor {
     220//  int data;                                  int data;
     221//  a_struct_t more_data;                      a_struct_t more_data;
     222//                                =>             monitor$ __mon_d;
     223// };                                        };
     224//                                           static inline monitor$ * get_coroutine( MyMonitor * this ) {
     225//                                               return &this->__cor_d;
     226//                                           }
     227//                                           void lock(MyMonitor & this) {
     228//                                               lock(get_monitor(this));
     229//                                           }
     230//                                           void unlock(MyMonitor & this) {
     231//                                               unlock(get_monitor(this));
     232//                                           }
     233//
     234struct MonitorKeyword final : public ConcurrentSueKeyword {
     235        MonitorKeyword() : ConcurrentSueKeyword(
     236                "monitor$",
     237                "__mon",
     238                "get_monitor",
     239                "monitor keyword requires monitors to be in scope, add #include <monitor.hfa>\n",
     240                "",
     241                false,
     242                ast::AggregateDecl::Monitor )
     243        {}
     244
     245        virtual ~MonitorKeyword() {}
     246};
     247
     248// Handles generator type declarations:
     249//
     250// generator MyGenerator {                   struct MyGenerator {
     251//  int data;                                  int data;
     252//  a_struct_t more_data;                      a_struct_t more_data;
     253//                                =>             int __generator_state;
     254// };                                        };
     255//
     256struct GeneratorKeyword final : public ConcurrentSueKeyword {
     257        GeneratorKeyword() : ConcurrentSueKeyword(
     258                "generator$",
     259                "__generator_state",
     260                "get_generator",
     261                "Unable to find builtin type generator$\n",
     262                "",
     263                true,
     264                ast::AggregateDecl::Generator )
     265        {}
     266
     267        virtual ~GeneratorKeyword() {}
     268};
     269
     270const ast::Decl * ConcurrentSueKeyword::postvisit(
     271                const ast::StructDecl * decl ) {
     272        if ( !decl->body ) {
     273                return decl;
     274        } else if ( cast_target == decl->kind ) {
     275                return handleStruct( decl );
     276        } else if ( type_name == decl->name ) {
     277                assert( !type_decl );
     278                type_decl = decl;
     279        } else if ( exception_name == decl->name ) {
     280                assert( !except_decl );
     281                except_decl = decl;
     282        } else if ( typeid_name == decl->name ) {
     283                assert( !typeid_decl );
     284                typeid_decl = decl;
     285        } else if ( vtable_name == decl->name ) {
     286                assert( !vtable_decl );
     287                vtable_decl = decl;
     288        }
     289        return decl;
     290}
     291
     292// Try to get the full definition, but raise an error on conflicts.
     293const ast::FunctionDecl * getDefinition(
     294                const ast::FunctionDecl * old_decl,
     295                const ast::FunctionDecl * new_decl ) {
     296        if ( !new_decl->stmts ) {
     297                return old_decl;
     298        } else if ( !old_decl->stmts ) {
     299                return new_decl;
     300        } else {
     301                assert( !old_decl->stmts || !new_decl->stmts );
     302                return nullptr;
     303        }
     304}
     305
     306const ast::DeclWithType * ConcurrentSueKeyword::postvisit(
     307                const ast::FunctionDecl * decl ) {
     308        if ( type_decl && isDestructorFor( decl, type_decl ) ) {
     309                // Check for forward declarations, try to get the full definition.
     310                dtor_decl = (dtor_decl) ? getDefinition( dtor_decl, decl ) : decl;
     311        } else if ( !vtable_name.empty() && decl->has_body() ) {
     312                if (const ast::DeclWithType * param = isMainFor( decl, cast_target )) {
     313                        if ( !vtable_decl ) {
     314                                SemanticError( decl, context_error );
     315                        }
     316                        // Should be safe because of isMainFor.
     317                        const ast::StructInstType * struct_type =
     318                                static_cast<const ast::StructInstType *>(
     319                                        static_cast<const ast::ReferenceType *>(
     320                                                param->get_type() )->base.get() );
     321
     322                        handleMain( decl, struct_type );
     323                }
     324        }
     325        return decl;
     326}
     327
     328const ast::Expr * ConcurrentSueKeyword::postvisit(
     329                const ast::KeywordCastExpr * expr ) {
     330        if ( cast_target == expr->target ) {
     331                // Convert `(thread &)ex` to `(thread$ &)*get_thread(ex)`, etc.
     332                if ( !type_decl || !dtor_decl ) {
     333                        SemanticError( expr, context_error );
     334                }
     335                assert( nullptr == expr->result );
     336                auto cast = ast::mutate( expr );
     337                cast->result = new ast::ReferenceType( new ast::StructInstType( type_decl ) );
     338                cast->concrete_target.field  = field_name;
     339                cast->concrete_target.getter = getter_name;
     340                return cast;
     341        }
     342        return expr;
     343}
     344
     345const ast::StructDecl * ConcurrentSueKeyword::handleStruct(
     346                const ast::StructDecl * decl ) {
     347        assert( decl->body );
     348
     349        if ( !type_decl || !dtor_decl ) {
     350                SemanticError( decl, context_error );
     351        }
     352
     353        if ( !exception_name.empty() ) {
     354                if( !typeid_decl || !vtable_decl ) {
     355                        SemanticError( decl, context_error );
     356                }
     357                addTypeId( decl );
     358                addVtableForward( decl );
     359        }
     360
     361        const ast::FunctionDecl * func = forwardDeclare( decl );
     362        StructAndField addFieldRet = addField( decl );
     363        decl = addFieldRet.decl;
     364        const ast::ObjectDecl * field = addFieldRet.field;
     365
     366        addGetRoutines( field, func );
     367        // Add routines to monitors for use by mutex stmt.
     368        if ( ast::AggregateDecl::Monitor == cast_target ) {
     369                addLockUnlockRoutines( decl );
     370        }
     371
     372        return decl;
     373}
     374
     375void ConcurrentSueKeyword::handleMain(
     376                const ast::FunctionDecl * decl, const ast::StructInstType * type ) {
     377        assert( vtable_decl );
     378        assert( except_decl );
     379
     380        const CodeLocation & location = decl->location;
     381
     382        std::vector<ast::ptr<ast::Expr>> poly_args = {
     383                new ast::TypeExpr( location, type ),
     384        };
     385        ast::ObjectDecl * vtable_object = Virtual::makeVtableInstance(
     386                location,
     387                "_default_vtable_object_declaration",
     388                new ast::StructInstType( vtable_decl, copy( poly_args ) ),
     389                type,
     390                nullptr
     391        );
     392        declsToAddAfter.push_back( vtable_object );
     393        declsToAddAfter.push_back(
     394                new ast::ObjectDecl(
     395                        location,
     396                        Virtual::concurrentDefaultVTableName(),
     397                        new ast::ReferenceType( vtable_object->type, ast::CV::Const ),
     398                        new ast::SingleInit( location,
     399                                new ast::VariableExpr( location, vtable_object ) ),
     400                        ast::Storage::Classes(),
     401                        ast::Linkage::Cforall
     402                )
     403        );
     404        declsToAddAfter.push_back( Virtual::makeGetExceptionFunction(
     405                location,
     406                vtable_object,
     407                new ast::StructInstType( except_decl, copy( poly_args ) )
     408        ) );
     409}
     410
     411void ConcurrentSueKeyword::addTypeId( const ast::StructDecl * decl ) {
     412        assert( typeid_decl );
     413        const CodeLocation & location = decl->location;
     414
     415        ast::StructInstType * typeid_type =
     416                new ast::StructInstType( typeid_decl, ast::CV::Const );
     417        typeid_type->params.push_back(
     418                new ast::TypeExpr( location, new ast::StructInstType( decl ) ) );
     419        declsToAddBefore.push_back(
     420                Virtual::makeTypeIdInstance( location, typeid_type ) );
     421        // If the typeid_type is going to be kept, the other reference will have
     422        // been made by now, but we also get to avoid extra mutates.
     423        ast::ptr<ast::StructInstType> typeid_cleanup = typeid_type;
     424}
     425
     426void ConcurrentSueKeyword::addVtableForward( const ast::StructDecl * decl ) {
     427        assert( vtable_decl );
     428        const CodeLocation& location = decl->location;
     429
     430        std::vector<ast::ptr<ast::Expr>> poly_args = {
     431                new ast::TypeExpr( location, new ast::StructInstType( decl ) ),
     432        };
     433        declsToAddBefore.push_back( Virtual::makeGetExceptionForward(
     434                location,
     435                new ast::StructInstType( vtable_decl, copy( poly_args ) ),
     436                new ast::StructInstType( except_decl, copy( poly_args ) )
     437        ) );
     438        ast::ObjectDecl * vtable_object = Virtual::makeVtableForward(
     439                location,
     440                "_default_vtable_object_declaration",
     441                new ast::StructInstType( vtable_decl, std::move( poly_args ) )
     442        );
     443        declsToAddBefore.push_back( vtable_object );
     444        declsToAddBefore.push_back(
     445                new ast::ObjectDecl(
     446                        location,
     447                        Virtual::concurrentDefaultVTableName(),
     448                        new ast::ReferenceType( vtable_object->type, ast::CV::Const ),
     449                        nullptr,
     450                        ast::Storage::Extern,
     451                        ast::Linkage::Cforall
     452                )
     453        );
     454}
     455
     456const ast::FunctionDecl * ConcurrentSueKeyword::forwardDeclare(
     457                const ast::StructDecl * decl ) {
     458        const CodeLocation & location = decl->location;
     459
     460        ast::StructDecl * forward = ast::deepCopy( decl );
     461        {
     462                // If removing members makes ref-count go to zero, do not free.
     463                ast::ptr<ast::StructDecl> forward_ptr = forward;
     464                forward->body = false;
     465                forward->members.clear();
     466                forward_ptr.release();
     467        }
     468
     469        ast::ObjectDecl * this_decl = new ast::ObjectDecl(
     470                location,
     471                "this",
     472                new ast::ReferenceType( new ast::StructInstType( decl ) ),
     473                nullptr,
     474                ast::Storage::Classes(),
     475                ast::Linkage::Cforall
     476        );
     477
     478        ast::ObjectDecl * ret_decl = new ast::ObjectDecl(
     479                location,
     480                "ret",
     481                new ast::PointerType( new ast::StructInstType( type_decl ) ),
     482                nullptr,
     483                ast::Storage::Classes(),
     484                ast::Linkage::Cforall
     485        );
     486
     487        ast::FunctionDecl * get_decl = new ast::FunctionDecl(
     488                location,
     489                getter_name,
     490                {}, // forall
     491                { this_decl }, // params
     492                { ret_decl }, // returns
     493                nullptr, // stmts
     494                ast::Storage::Static,
     495                ast::Linkage::Cforall,
     496                { new ast::Attribute( "const" ) },
     497                ast::Function::Inline
     498        );
     499        get_decl = fixupGenerics( get_decl, decl );
     500
     501        ast::FunctionDecl * main_decl = nullptr;
     502        if ( needs_main ) {
     503                // `this_decl` is copied here because the original was used above.
     504                main_decl = new ast::FunctionDecl(
     505                        location,
     506                        "main",
     507                        {},
     508                        { ast::deepCopy( this_decl ) },
     509                        {},
     510                        nullptr,
     511                        ast::Storage::Classes(),
     512                        ast::Linkage::Cforall
     513                );
     514                main_decl = fixupGenerics( main_decl, decl );
     515        }
     516
     517        declsToAddBefore.push_back( forward );
     518        if ( needs_main ) declsToAddBefore.push_back( main_decl );
     519        declsToAddBefore.push_back( get_decl );
     520
     521        return get_decl;
     522}
     523
     524ConcurrentSueKeyword::StructAndField ConcurrentSueKeyword::addField(
     525                const ast::StructDecl * decl ) {
     526        const CodeLocation & location = decl->location;
     527
     528        ast::ObjectDecl * field = new ast::ObjectDecl(
     529                location,
     530                field_name,
     531                new ast::StructInstType( type_decl ),
     532                nullptr,
     533                ast::Storage::Classes(),
     534                ast::Linkage::Cforall
     535        );
     536
     537        auto mutDecl = ast::mutate( decl );
     538        mutDecl->members.push_back( field );
     539
     540        return {mutDecl, field};
     541}
     542
     543void ConcurrentSueKeyword::addGetRoutines(
     544                const ast::ObjectDecl * field, const ast::FunctionDecl * forward ) {
     545        // Say it is generated at the "same" places as the forward declaration.
     546        const CodeLocation & location = forward->location;
     547
     548        const ast::DeclWithType * param = forward->params.front();
     549        ast::Stmt * stmt = new ast::ReturnStmt( location,
     550                new ast::AddressExpr( location,
     551                        new ast::MemberExpr( location,
     552                                field,
     553                                new ast::CastExpr( location,
     554                                        new ast::VariableExpr( location, param ),
     555                                        ast::deepCopy( param->get_type()->stripReferences() ),
     556                                        ast::ExplicitCast
     557                                )
     558                        )
     559                )
     560        );
     561
     562        ast::FunctionDecl * decl = ast::deepCopy( forward );
     563        decl->stmts = new ast::CompoundStmt( location, { stmt } );
     564        declsToAddAfter.push_back( decl );
     565}
     566
     567void ConcurrentSueKeyword::addLockUnlockRoutines(
     568                const ast::StructDecl * decl ) {
     569        // This should only be used on monitors.
     570        assert( ast::AggregateDecl::Monitor == cast_target );
     571
     572        const CodeLocation & location = decl->location;
     573
     574        // The parameter for both routines.
     575        ast::ObjectDecl * this_decl = new ast::ObjectDecl(
     576                location,
     577                "this",
     578                new ast::ReferenceType( new ast::StructInstType( decl ) ),
     579                nullptr,
     580                ast::Storage::Classes(),
     581                ast::Linkage::Cforall
     582        );
     583
     584        ast::FunctionDecl * lock_decl = new ast::FunctionDecl(
     585                location,
     586                "lock",
     587                { /* forall */ },
     588                {
     589                        // Copy the declaration of this.
     590                        ast::deepCopy( this_decl ),
     591                },
     592                { /* returns */ },
     593                nullptr,
     594                ast::Storage::Static,
     595                ast::Linkage::Cforall,
     596                { /* attributes */ },
     597                ast::Function::Inline
     598        );
     599        lock_decl = fixupGenerics( lock_decl, decl );
     600
     601        lock_decl->stmts = new ast::CompoundStmt( location, {
     602                new ast::ExprStmt( location,
     603                        new ast::UntypedExpr( location,
     604                                new ast::NameExpr( location, "lock" ),
     605                                {
     606                                        new ast::UntypedExpr( location,
     607                                                new ast::NameExpr( location, "get_monitor" ),
     608                                                { new ast::VariableExpr( location,
     609                                                        InitTweak::getParamThis( lock_decl ) ) }
     610                                        )
     611                                }
     612                        )
     613                )
     614        } );
     615
     616        ast::FunctionDecl * unlock_decl = new ast::FunctionDecl(
     617                location,
     618                "unlock",
     619                { /* forall */ },
     620                {
     621                        // Last use, consume the declaration of this.
     622                        this_decl,
     623                },
     624                { /* returns */ },
     625                nullptr,
     626                ast::Storage::Static,
     627                ast::Linkage::Cforall,
     628                { /* attributes */ },
     629                ast::Function::Inline
     630        );
     631        unlock_decl = fixupGenerics( unlock_decl, decl );
     632
     633        unlock_decl->stmts = new ast::CompoundStmt( location, {
     634                new ast::ExprStmt( location,
     635                        new ast::UntypedExpr( location,
     636                                new ast::NameExpr( location, "unlock" ),
     637                                {
     638                                        new ast::UntypedExpr( location,
     639                                                new ast::NameExpr( location, "get_monitor" ),
     640                                                { new ast::VariableExpr( location,
     641                                                        InitTweak::getParamThis( unlock_decl ) ) }
     642                                        )
     643                                }
     644                        )
     645                )
     646        } );
     647
     648        declsToAddAfter.push_back( lock_decl );
     649        declsToAddAfter.push_back( unlock_decl );
     650}
     651
     652
     653// --------------------------------------------------------------------------
     654struct SuspendKeyword final :
     655                public ast::WithStmtsToAdd<>, public ast::WithGuards {
     656        SuspendKeyword() = default;
     657        virtual ~SuspendKeyword() = default;
     658
     659        void previsit( const ast::FunctionDecl * );
     660        const ast::DeclWithType * postvisit( const ast::FunctionDecl * );
     661        const ast::Stmt * postvisit( const ast::SuspendStmt * );
     662
     663private:
     664        bool is_real_suspend( const ast::FunctionDecl * );
     665
     666        const ast::Stmt * make_generator_suspend( const ast::SuspendStmt * );
     667        const ast::Stmt * make_coroutine_suspend( const ast::SuspendStmt * );
     668
     669        struct LabelPair {
     670                ast::Label obj;
     671                int idx;
     672        };
     673
     674        LabelPair make_label(const ast::Stmt * stmt ) {
     675                labels.push_back( ControlStruct::newLabel( "generator", stmt ) );
     676                return { labels.back(), int(labels.size()) };
     677        }
     678
     679        const ast::DeclWithType * in_generator = nullptr;
     680        const ast::FunctionDecl * decl_suspend = nullptr;
     681        std::vector<ast::Label> labels;
     682};
     683
     684void SuspendKeyword::previsit( const ast::FunctionDecl * decl ) {
     685        GuardValue( in_generator ); in_generator = nullptr;
     686
     687        // If it is the real suspend, grab it if we don't have one already.
     688        if ( is_real_suspend( decl ) ) {
     689                decl_suspend = decl_suspend ? decl_suspend : decl;
     690                return;
     691        }
     692
     693        // Otherwise check if this is a generator main and, if so, handle it.
     694        auto param = isMainFor( decl, ast::AggregateDecl::Generator );
     695        if ( !param ) return;
     696
     697        if ( 0 != decl->returns.size() ) {
     698                SemanticError( decl->location, "Generator main must return void" );
     699        }
     700
     701        in_generator = param;
     702        GuardValue( labels ); labels.clear();
     703}
     704
     705const ast::DeclWithType * SuspendKeyword::postvisit(
     706                const ast::FunctionDecl * decl ) {
     707        // Only modify a full definition of a generator with states.
     708        if ( !decl->stmts || !in_generator || labels.empty() ) return decl;
     709
     710        const CodeLocation & location = decl->location;
     711
     712        // Create a new function body:
     713        // static void * __generator_labels[] = {&&s0, &&s1, ...};
     714        // void * __generator_label = __generator_labels[GEN.__generator_state];
     715        // goto * __generator_label;
     716        // s0: ;
     717        // OLD_BODY
     718
     719        // This is the null statement inserted right before the body.
     720        ast::NullStmt * noop = new ast::NullStmt( location );
     721        noop->labels.push_back( ControlStruct::newLabel( "generator", noop ) );
     722        const ast::Label & first_label = noop->labels.back();
     723
     724        // Add each label to the init, starting with the first label.
     725        std::vector<ast::ptr<ast::Init>> inits = {
     726                new ast::SingleInit( location,
     727                        new ast::LabelAddressExpr( location, copy( first_label ) ) ) };
     728        // Then go through all the stored labels, and clear the store.
     729        for ( auto && label : labels ) {
     730                inits.push_back( new ast::SingleInit( label.location,
     731                        new ast::LabelAddressExpr( label.location, std::move( label )
     732                        ) ) );
     733        }
     734        labels.clear();
     735        // Then construct the initializer itself.
     736        auto init = new ast::ListInit( location, std::move( inits ) );
     737
     738        ast::ObjectDecl * generatorLabels = new ast::ObjectDecl(
     739                location,
     740                "__generator_labels",
     741                new ast::ArrayType(
     742                        new ast::PointerType( new ast::VoidType() ),
     743                        nullptr,
     744                        ast::FixedLen,
     745                        ast::DynamicDim
     746                ),
     747                init,
     748                ast::Storage::Classes(),
     749                ast::Linkage::AutoGen
     750        );
     751
     752        ast::ObjectDecl * generatorLabel = new ast::ObjectDecl(
     753                location,
     754                "__generator_label",
     755                new ast::PointerType( new ast::VoidType() ),
     756                new ast::SingleInit( location,
     757                        new ast::UntypedExpr( location,
     758                                new ast::NameExpr( location, "?[?]" ),
     759                                {
     760                                        // TODO: Could be a variable expr.
     761                                        new ast::NameExpr( location, "__generator_labels" ),
     762                                        new ast::UntypedMemberExpr( location,
     763                                                new ast::NameExpr( location, "__generator_state" ),
     764                                                new ast::VariableExpr( location, in_generator )
     765                                        )
     766                                }
     767                        )
     768                ),
     769                ast::Storage::Classes(),
     770                ast::Linkage::AutoGen
     771        );
     772
     773        ast::BranchStmt * theGoTo = new ast::BranchStmt(
     774                location, new ast::VariableExpr( location, generatorLabel )
     775        );
     776
     777        // The noop goes here in order.
     778
     779        ast::CompoundStmt * body = new ast::CompoundStmt( location, {
     780                { new ast::DeclStmt( location, generatorLabels ) },
     781                { new ast::DeclStmt( location, generatorLabel ) },
     782                { theGoTo },
     783                { noop },
     784                { decl->stmts },
     785        } );
     786
     787        auto mutDecl = ast::mutate( decl );
     788        mutDecl->stmts = body;
     789        return mutDecl;
     790}
     791
     792const ast::Stmt * SuspendKeyword::postvisit( const ast::SuspendStmt * stmt ) {
     793        switch ( stmt->type ) {
     794        case ast::SuspendStmt::None:
     795                // Use the context to determain the implicit target.
     796                if ( in_generator ) {
     797                        return make_generator_suspend( stmt );
     798                } else {
     799                        return make_coroutine_suspend( stmt );
     800                }
     801        case ast::SuspendStmt::Coroutine:
     802                return make_coroutine_suspend( stmt );
     803        case ast::SuspendStmt::Generator:
     804                // Generator suspends must be directly in a generator.
     805                if ( !in_generator ) SemanticError( stmt->location, "'suspend generator' must be used inside main of generator type." );
     806                return make_generator_suspend( stmt );
     807        }
     808        assert( false );
     809        return stmt;
     810}
     811
     812/// Find the real/official suspend declaration.
     813bool SuspendKeyword::is_real_suspend( const ast::FunctionDecl * decl ) {
     814        return ( !decl->linkage.is_mangled
     815                && 0 == decl->params.size()
     816                && 0 == decl->returns.size()
     817                && "__cfactx_suspend" == decl->name );
     818}
     819
     820const ast::Stmt * SuspendKeyword::make_generator_suspend(
     821                const ast::SuspendStmt * stmt ) {
     822        assert( in_generator );
     823        // Target code is:
     824        //   GEN.__generator_state = X;
     825        //   THEN
     826        //   return;
     827        //   __gen_X:;
     828
     829        const CodeLocation & location = stmt->location;
     830
     831        LabelPair label = make_label( stmt );
     832
     833        // This is the context saving statement.
     834        stmtsToAddBefore.push_back( new ast::ExprStmt( location,
     835                new ast::UntypedExpr( location,
     836                        new ast::NameExpr( location, "?=?" ),
     837                        {
     838                                new ast::UntypedMemberExpr( location,
     839                                        new ast::NameExpr( location, "__generator_state" ),
     840                                        new ast::VariableExpr( location, in_generator )
     841                                ),
     842                                ast::ConstantExpr::from_int( location, label.idx ),
     843                        }
     844                )
     845        ) );
     846
     847        // The THEN component is conditional (return is not).
     848        if ( stmt->then ) {
     849                stmtsToAddBefore.push_back( stmt->then.get() );
     850        }
     851        stmtsToAddBefore.push_back( new ast::ReturnStmt( location, nullptr ) );
     852
     853        // The null statement replaces the old suspend statement.
     854        return new ast::NullStmt( location, { label.obj } );
     855}
     856
     857const ast::Stmt * SuspendKeyword::make_coroutine_suspend(
     858                const ast::SuspendStmt * stmt ) {
     859        // The only thing we need from the old statement is the location.
     860        const CodeLocation & location = stmt->location;
     861
     862        if ( !decl_suspend ) {
     863                SemanticError( location, "suspend keyword applied to coroutines requires coroutines to be in scope, add #include <coroutine.hfa>\n" );
     864        }
     865        if ( stmt->then ) {
     866                SemanticError( location, "Compound statement following coroutines is not implemented." );
     867        }
     868
     869        return new ast::ExprStmt( location,
     870                new ast::UntypedExpr( location,
     871                        ast::VariableExpr::functionPointer( location, decl_suspend ) )
     872        );
    36873}
    37874
     
    2511088                                {
    2521089                                        new ast::SingleInit( location,
    253                                                 new ast::AddressExpr(
     1090                                                new ast::AddressExpr( location,
    2541091                                                        new ast::VariableExpr( location, monitor ) ) ),
    2551092                                        new ast::SingleInit( location,
     
    5641401
    5651402// --------------------------------------------------------------------------
     1403// Interface Functions:
    5661404
    5671405void implementKeywords( ast::TranslationUnit & translationUnit ) {
    568         (void)translationUnit;
    569         assertf(false, "Apply Keywords not implemented." );
     1406        ast::Pass<ThreadKeyword>::run( translationUnit );
     1407        ast::Pass<CoroutineKeyword>::run( translationUnit );
     1408        ast::Pass<MonitorKeyword>::run( translationUnit );
     1409        ast::Pass<GeneratorKeyword>::run( translationUnit );
     1410        ast::Pass<SuspendKeyword>::run( translationUnit );
    5701411}
    5711412
  • src/Validate/ForallPointerDecay.cpp

    rb053083 r4f6dda0  
    7070                AssertionList assertions;
    7171                // Substitute trait decl parameters for instance parameters.
    72                 ast::TypeSubstitution sub(
    73                         inst->base->params.begin(),
    74                         inst->base->params.end(),
    75                         inst->params.begin()
    76                 );
     72                ast::TypeSubstitution sub( inst->base->params, inst->params );
    7773                for ( const ast::ptr<ast::Decl> & decl : inst->base->members ) {
    7874                        ast::ptr<ast::DeclWithType> copy =
  • src/Virtual/Tables.cc

    rb053083 r4f6dda0  
    1010// Created On       : Mon Aug 31 11:11:00 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Apr 21 15:36:00 2021
    13 // Update Count     : 2
    14 //
    15 
     12// Last Modified On : Fri Mar 11 10:40:00 2022
     13// Update Count     : 3
     14//
     15
     16#include "AST/Attribute.hpp"
     17#include "AST/Copy.hpp"
     18#include "AST/Decl.hpp"
     19#include "AST/Expr.hpp"
     20#include "AST/Init.hpp"
     21#include "AST/Stmt.hpp"
     22#include "AST/Type.hpp"
    1623#include <SynTree/Attribute.h>
    1724#include <SynTree/Declaration.h>
     
    7784}
    7885
     86static ast::ObjectDecl * makeVtableDeclaration(
     87                CodeLocation const & location, std::string const & name,
     88                ast::StructInstType const * type, ast::Init const * init ) {
     89        ast::Storage::Classes storage;
     90        if ( nullptr == init ) {
     91                storage.is_extern = true;
     92        }
     93        return new ast::ObjectDecl(
     94                location,
     95                name,
     96                type,
     97                init,
     98                storage,
     99                ast::Linkage::Cforall
     100        );
     101}
     102
    79103ObjectDecl * makeVtableForward( std::string const & name, StructInstType * type ) {
    80104        assert( type );
    81105        return makeVtableDeclaration( name, type, nullptr );
     106}
     107
     108ast::ObjectDecl * makeVtableForward(
     109                CodeLocation const & location, std::string const & name,
     110                ast::StructInstType const * vtableType ) {
     111        assert( vtableType );
     112        return makeVtableDeclaration( location, name, vtableType, nullptr );
    82113}
    83114
     
    123154}
    124155
     156static std::vector<ast::ptr<ast::Init>> buildInits(
     157                CodeLocation const & location,
     158                //std::string const & name,
     159                ast::StructInstType const * vtableType,
     160                ast::Type const * objectType ) {
     161        ast::StructDecl const * vtableStruct = vtableType->base;
     162
     163        std::vector<ast::ptr<ast::Init>> inits;
     164        inits.reserve( vtableStruct->members.size() );
     165
     166        // This is designed to run before the resolver.
     167        for ( auto field : vtableStruct->members ) {
     168                if ( std::string( "parent" ) == field->name ) {
     169                        // This will not work with polymorphic state.
     170                        auto oField = field.strict_as<ast::ObjectDecl>();
     171                        auto fieldType = oField->type.strict_as<ast::PointerType>();
     172                        auto parentType = fieldType->base.strict_as<ast::StructInstType>();
     173                        std::string const & parentInstance = instanceName( parentType->name );
     174                        inits.push_back(
     175                                        new ast::SingleInit( location, new ast::AddressExpr( new ast::NameExpr( location, parentInstance ) ) ) );
     176                } else if ( std::string( "__cfavir_typeid" ) == field->name ) {
     177                        std::string const & baseType = baseTypeName( vtableType->name );
     178                        std::string const & typeId = typeIdName( baseType );
     179                        inits.push_back( new ast::SingleInit( location, new ast::AddressExpr( new ast::NameExpr( location, typeId ) ) ) );
     180                } else if ( std::string( "size" ) == field->name ) {
     181                        inits.push_back( new ast::SingleInit( location, new ast::SizeofExpr( location, objectType )
     182                        ) );
     183                } else if ( std::string( "align" ) == field->name ) {
     184                        inits.push_back( new ast::SingleInit( location,
     185                                new ast::AlignofExpr( location, objectType )
     186                        ) );
     187                } else {
     188                        inits.push_back( new ast::SingleInit( location,
     189                                new ast::NameExpr( location, field->name )
     190                        ) );
     191                }
     192                //ast::Expr * expr = buildInitExpr(...);
     193                //inits.push_back( new ast::SingleInit( location, expr ) )
     194        }
     195
     196        return inits;
     197}
     198
     199ast::ObjectDecl * makeVtableInstance(
     200                CodeLocation const & location,
     201                std::string const & name,
     202                ast::StructInstType const * vtableType,
     203                ast::Type const * objectType,
     204                ast::Init const * init ) {
     205        assert( vtableType );
     206        assert( objectType );
     207
     208        // Build the initialization.
     209        if ( nullptr == init ) {
     210                init = new ast::ListInit( location,
     211                        buildInits( location, vtableType, objectType ) );
     212
     213        // The provided init should initialize everything except the parent
     214        // pointer, the size-of and align-of fields. These should be inserted.
     215        } else {
     216                // Except this is not yet supported.
     217                assert(false);
     218        }
     219        return makeVtableDeclaration( location, name, vtableType, init );
     220}
     221
    125222namespace {
    126223        std::string const functionName = "get_exception_vtable";
     
    140237                new ReferenceType( noQualifiers, vtableType ),
    141238                nullptr,
    142         { new Attribute("unused") }
     239                { new Attribute("unused") }
    143240        ) );
    144241        type->parameters.push_back( new ObjectDecl(
     
    157254                type,
    158255                nullptr
     256        );
     257}
     258
     259ast::FunctionDecl * makeGetExceptionForward(
     260                CodeLocation const & location,
     261                ast::Type const * vtableType,
     262                ast::Type const * exceptType ) {
     263        assert( vtableType );
     264        assert( exceptType );
     265        return new ast::FunctionDecl(
     266                location,
     267                functionName,
     268                { /* forall */ },
     269                { new ast::ObjectDecl(
     270                        location,
     271                        "__unused",
     272                        new ast::PointerType( exceptType )
     273                ) },
     274                { new ast::ObjectDecl(
     275                        location,
     276                        "_retvalue",
     277                        new ast::ReferenceType( vtableType )
     278                ) },
     279                nullptr,
     280                ast::Storage::Classes(),
     281                ast::Linkage::Cforall,
     282                { new ast::Attribute( "unused" ) }
    159283        );
    160284}
     
    172296}
    173297
     298ast::FunctionDecl * makeGetExceptionFunction(
     299                CodeLocation const & location,
     300                ast::ObjectDecl const * vtableInstance, ast::Type const * exceptType ) {
     301        assert( vtableInstance );
     302        assert( exceptType );
     303        ast::FunctionDecl * func = makeGetExceptionForward(
     304                        location, ast::deepCopy( vtableInstance->type ), exceptType );
     305        func->stmts = new ast::CompoundStmt( location, {
     306                new ast::ReturnStmt( location, new ast::VariableExpr( location, vtableInstance ) )
     307        } );
     308        return func;
     309}
     310
    174311ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType ) {
    175312        assert( typeIdType );
     
    191328}
    192329
    193 }
     330ast::ObjectDecl * makeTypeIdInstance(
     331                CodeLocation const & location,
     332                ast::StructInstType const * typeIdType ) {
     333        assert( typeIdType );
     334        ast::StructInstType * type = ast::mutate( typeIdType );
     335        type->set_const( true );
     336        std::string const & typeid_name = typeIdTypeToInstance( typeIdType->name );
     337        return new ast::ObjectDecl(
     338                location,
     339                typeid_name,
     340                type,
     341                new ast::ListInit( location, {
     342                        new ast::SingleInit( location,
     343                                new ast::AddressExpr( location,
     344                                        new ast::NameExpr( location, "__cfatid_exception_t" ) ) )
     345                } ),
     346                ast::Storage::Classes(),
     347                ast::Linkage::Cforall,
     348                nullptr,
     349                { new ast::Attribute( "cfa_linkonce" ) }
     350        );
     351}
     352
     353}
  • src/Virtual/Tables.h

    rb053083 r4f6dda0  
    1010// Created On       : Mon Aug 31 11:07:00 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Apr 21 10:30:00 2021
    13 // Update Count     : 2
     12// Last Modified On : Wec Dec  8 16:58:00 2021
     13// Update Count     : 3
    1414//
    1515
    1616#include <list>  // for list
    1717
     18#include <string>
     19#include "AST/Fwd.hpp"
    1820class Declaration;
    1921class StructDecl;
     
    3537 * vtableType node is consumed.
    3638 */
     39ast::ObjectDecl * makeVtableForward(
     40        CodeLocation const & location, std::string const & name,
     41        ast::StructInstType const * vtableType );
    3742
    3843ObjectDecl * makeVtableInstance(
     
    4348 * vtableType and init (if provided) nodes are consumed.
    4449 */
     50ast::ObjectDecl * makeVtableInstance(
     51        CodeLocation const & location,
     52        std::string const & name,
     53        ast::StructInstType const * vtableType,
     54        ast::Type const * objectType,
     55        ast::Init const * init = nullptr );
    4556
    4657// Some special code for how exceptions interact with virtual tables.
     
    4960 * linking the vtableType to the exceptType. Both nodes are consumed.
    5061 */
     62ast::FunctionDecl * makeGetExceptionForward(
     63        CodeLocation const & location,
     64        ast::Type const * vtableType,
     65        ast::Type const * exceptType );
    5166
    5267FunctionDecl * makeGetExceptionFunction(
     
    5570 * exceptType node is consumed.
    5671 */
     72ast::FunctionDecl * makeGetExceptionFunction(
     73        CodeLocation const & location,
     74        ast::ObjectDecl const * vtableInstance, ast::Type const * exceptType );
    5775
    5876ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType );
     
    6078 * TODO: Should take the parent type. Currently locked to the exception_t.
    6179 */
     80ast::ObjectDecl * makeTypeIdInstance(
     81        const CodeLocation & location, ast::StructInstType const * typeIdType );
    6282
    6383}
  • src/main.cc

    rb053083 r4f6dda0  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jan 26 14:09:00 2022
    13 // Update Count     : 670
     12// Last Modified On : Fri Mar 11 10:39:00 2022
     13// Update Count     : 671
    1414//
    1515
     
    333333
    334334                if( useNewAST ) {
    335                         PASS( "Implement Concurrent Keywords", Concurrency::applyKeywords( translationUnit ) );
    336                         //PASS( "Forall Pointer Decay - A", SymTab::decayForallPointersA( translationUnit ) );
    337                         //PASS( "Forall Pointer Decay - B", SymTab::decayForallPointersB( translationUnit ) );
    338                         //PASS( "Forall Pointer Decay - C", SymTab::decayForallPointersC( translationUnit ) );
    339                         //PASS( "Forall Pointer Decay - D", SymTab::decayForallPointersD( translationUnit ) );
    340335                        CodeTools::fillLocations( translationUnit );
    341336
     
    347342
    348343                        forceFillCodeLocations( transUnit );
     344
     345                        PASS( "Implement Concurrent Keywords", Concurrency::implementKeywords( transUnit ) );
    349346
    350347                        // Must be after implement concurrent keywords; because uniqueIds
     
    497494                        PASS( "Translate Tries" , ControlStruct::translateTries( translationUnit ) );
    498495                }
    499 
    500                
    501496
    502497                PASS( "Gen Waitfor" , Concurrency::generateWaitFor( translationUnit ) );
Note: See TracChangeset for help on using the changeset viewer.