Changeset e50d9cb8


Ignore:
Timestamp:
Nov 1, 2022, 10:06:40 PM (2 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, ast-experimental, master
Children:
7cf8006
Parents:
0bdfcc3 (diff), 03c56f6 (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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
5 added
12 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/Makefile.am

    r0bdfcc3 re50d9cb8  
    111111        concurrency/invoke.h \
    112112        concurrency/future.hfa \
     113        concurrency/once.hfa \
    113114        concurrency/kernel/fwd.hfa \
    114115        concurrency/mutex_stmt.hfa
  • libcfa/src/bits/defs.hfa

    r0bdfcc3 re50d9cb8  
    3131#define __cfa_anonymous_object(x) inline struct x
    3232#define __cfa_dlink1(x) dlink(x)
     33#define __cfa_dlink2(x, name) inline struct name { inline dlink(x); }
    3334#else
    3435#define __cfa_anonymous_object(x) struct x __cfa_anonymous_object
    3536#define __cfa_dlink1(x) struct { struct x * next; struct x * back; }
     37#define __cfa_dlink2(x, name) struct { struct x * next; struct x * back; } __dlink ## name
    3638#endif
    3739
  • libcfa/src/concurrency/invoke.h

    r0bdfcc3 re50d9cb8  
    195195                struct __monitor_group_t monitors;
    196196
    197                 // used to put threads on dlist data structure
     197                // intrusive link fields, used for locks, monitors and any user defined data structure
     198                // default link fields for dlist
    198199                __cfa_dlink1(thread$) user_link;
    199200
    200                 struct {
    201                         struct thread$ * next;
    202                         struct thread$ * prev;
    203                 } node;
     201                // secondary intrusive link fields, used for global cluster list
     202                // default link fields for dlist
     203                __cfa_dlink2(thread$, cltr_link);
    204204
    205205                // used to store state between clh lock/unlock
     
    230230        #ifdef __cforall
    231231        extern "Cforall" {
     232                static inline thread$ * volatile & ?`next ( thread$ * this ) {
     233                        return this->user_link.next;
     234                }
    232235
    233236                static inline thread$ *& get_next( thread$ & this ) __attribute__((const)) {
    234237                        return this.user_link.next;
    235                 }
    236 
    237                 static inline [thread$ *&, thread$ *& ] __get( thread$ & this ) __attribute__((const)) {
    238                         return this.node.[next, prev];
    239238                }
    240239
     
    244243                        return result;
    245244                }
     245
     246                P9_EMBEDDED(thread$, thread$.cltr_link)
     247                P9_EMBEDDED(thread$.cltr_link, dlink(thread$))
    246248
    247249                static inline void ?{}(__monitor_group_t & this) {
  • libcfa/src/concurrency/kernel.hfa

    r0bdfcc3 re50d9cb8  
    256256        // List of threads
    257257        __spinlock_t thread_list_lock;
    258         __dllist_t(struct thread$) threads;
     258        dlist(struct thread$, thread$.cltr_link) threads;
    259259        unsigned int nthreads;
    260260
  • libcfa/src/concurrency/kernel/startup.cfa

    r0bdfcc3 re50d9cb8  
    535535        #endif
    536536
    537         node.next = 0p;
    538         node.prev = 0p;
    539537        doregister(curr_cluster, this);
    540538
     
    659657        #endif
    660658
    661         threads{ __get };
     659        threads{};
    662660
    663661        io.arbiter = create();
     
    739737        lock      (cltr->thread_list_lock __cfaabi_dbg_ctx2);
    740738        cltr->nthreads += 1;
    741         push_front(cltr->threads, thrd);
     739        insert_first(cltr->threads, thrd);
    742740        unlock    (cltr->thread_list_lock);
    743741}
     
    745743void unregister( cluster * cltr, thread$ & thrd ) {
    746744        lock  (cltr->thread_list_lock __cfaabi_dbg_ctx2);
    747         remove(cltr->threads, thrd );
    748         cltr->nthreads -= 1;
     745        {
     746                tytagref( dlink(thread$), dlink(thread$) ) ?`inner( thread$ & this ) = void;
     747                with( DLINK_VIA( thread$, thread$.cltr_link ) )
     748                        remove( thrd );
     749                cltr->nthreads -= 1;
     750        }
    749751        unlock(cltr->thread_list_lock);
    750752}
  • libcfa/src/concurrency/thread.cfa

    r0bdfcc3 re50d9cb8  
    5454        #endif
    5555
    56         node.next = 0p;
    57         node.prev = 0p;
    58 
    5956        clh_node = malloc( );
    6057        *clh_node = false;
  • libcfa/src/containers/lockfree.hfa

    r0bdfcc3 re50d9cb8  
    142142
    143143        static inline void ?{}(poison_list(T) & this) { this.head = 0p; }
     144        static inline bool is_poisoned( const poison_list(T) & this ) { return 1p == this.head; }
    144145
    145146        static inline forall(| { T * volatile & ?`next ( T * ); })
     
    147148                // Adds an element to the list
    148149                // Multi-Thread Safe, Lock-Free
    149                 T * push(poison_list(T) & this, T * elem) __attribute__((artificial));
    150                 T * push(poison_list(T) & this, T * elem) {
     150                bool push(poison_list(T) & this, T * elem) __attribute__((artificial));
     151                bool push(poison_list(T) & this, T * elem) {
    151152                        /* paranoid */ verify(0p == (elem`next));
    152153                        __atomic_store_n( &elem`next, (T*)1p, __ATOMIC_RELAXED );
     
    156157                        for() {
    157158                                // check if it's poisoned
    158                                 if(expected == 1p) return 0p;
     159                                if(expected == 1p) return false;
    159160
    160161                                // try to CAS the elem in
     
    162163                                        // We managed to exchange in, we are done
    163164
    164                                         // We should never succeed the CAS if it's poisonned.
    165                                         /* paranoid */ verify( expected != 1p );
     165                                        // We should never succeed the CAS if it's poisonned and the elem should be 1p.
     166                                        /* paranoid */ verify( expected  != 1p );
     167                                        /* paranoid */ verify( elem`next == 1p );
    166168
    167169                                        // If we aren't the first, we need to tell the person before us
    168170                                        // No need to
    169171                                        elem`next = expected;
    170                                         return expected;
     172                                        return true;
    171173                                }
    172174                        }
     
    190192                T * poison(poison_list(T) & this) {
    191193                        T * ret = __atomic_exchange_n( &this.head, (T*)1p, __ATOMIC_SEQ_CST );
    192                         /* paranoid */ verify( ret != (T*)1p );
     194                        /* paranoid */ verifyf( ret != (T*)1p, "Poison list %p poisoned more than once!", &this );
    193195                        return ret;
    194196                }
  • src/AST/Pass.impl.hpp

    r0bdfcc3 re50d9cb8  
    617617                                maybe_accept( node, &FunctionDecl::returns );
    618618                                maybe_accept( node, &FunctionDecl::type );
     619                                maybe_accept( node, &FunctionDecl::attributes );
    619620                                // First remember that we are now within a function.
    620621                                ValueGuard< bool > oldInFunction( inFunction );
     
    625626                                atFunctionTop = true;
    626627                                maybe_accept( node, &FunctionDecl::stmts );
    627                                 maybe_accept( node, &FunctionDecl::attributes );
    628628                        }
    629629                }
  • src/Common/PassVisitor.impl.h

    r0bdfcc3 re50d9cb8  
    607607                        indexerAddId( &func );
    608608                        maybeMutate_impl( node->type, *this );
     609                        maybeMutate_impl( node->attributes, *this );
    609610                        // First remember that we are now within a function.
    610611                        ValueGuard< bool > oldInFunction( inFunction );
     
    615616                        atFunctionTop = true;
    616617                        maybeMutate_impl( node->statements, *this );
    617                         maybeMutate_impl( node->attributes, *this );
    618618                }
    619619        }
  • src/GenPoly/Box.cc

    r0bdfcc3 re50d9cb8  
    6868                /// Adds layout-generation functions to polymorphic types.
    6969                class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting {
    70                         // Current level of nested functions:
    71                         unsigned int functionNesting = 0;
    7270                public:
    73                         void previsit( FunctionDecl *functionDecl );
    7471                        void previsit( StructDecl *structDecl );
    7572                        void previsit( UnionDecl *unionDecl );
     
    237234        ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
    238235
    239         void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) {
    240                 visit_children = false;
    241                 maybeAccept( functionDecl->get_functionType(), *visitor );
    242                 ++functionNesting;
    243                 maybeAccept( functionDecl->get_statements(), *visitor );
    244                 --functionNesting;
    245         }
    246 
    247236        /// Get a list of type declarations that will affect a layout function
    248237        std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
     
    271260
    272261        /// Builds a layout function declaration
    273         FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, unsigned int functionNesting, FunctionType *layoutFnType ) {
     262        FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, bool isInFunction, FunctionType *layoutFnType ) {
    274263                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    275264                // because each unit generates copies of the default routines for each aggregate.
    276265                FunctionDecl *layoutDecl = new FunctionDecl( layoutofName( typeDecl ),
    277                                                                                                          functionNesting > 0 ? Type::StorageClasses() : Type::StorageClasses( Type::Static ),
     266                                                                                                         isInFunction ? Type::StorageClasses() : Type::StorageClasses( Type::Static ),
    278267                                                                                                         LinkageSpec::AutoGen, layoutFnType, new CompoundStmt(),
    279268                                                                                                         std::list< Attribute * >(), Type::FuncSpecifiers( Type::Inline ) );
     
    347336
    348337                // build function decl
    349                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, functionNesting, layoutFnType );
     338                FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, isInFunction(), layoutFnType );
    350339
    351340                // calculate struct layout in function body
     
    354343                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 0 ) ) ) );
    355344                addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) );
    356                 unsigned long n_members = 0;
    357                 bool firstMember = true;
    358                 for ( Declaration* member : structDecl->get_members() ) {
    359                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member );
     345                for ( auto index_member : enumerate( structDecl->members ) ) {
     346                        DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( index_member.val );
    360347                        assert( dwt );
    361348                        Type *memberType = dwt->get_type();
    362349
    363                         if ( firstMember ) {
    364                                 firstMember = false;
    365                         } else {
     350                        if ( 0 < index_member.idx ) {
    366351                                // make sure all members after the first (automatically aligned at 0) are properly padded for alignment
    367352                                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );
     
    369354
    370355                        // place current size in the current offset index
    371                         addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( n_members ) ) ),
     356                        addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( index_member.idx ) ) ),
    372357                                                                              derefVar( sizeParam ) ) );
    373                         ++n_members;
    374358
    375359                        // add member size to current size
     
    406390
    407391                // build function decl
    408                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, functionNesting, layoutFnType );
     392                FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, isInFunction(), layoutFnType );
    409393
    410394                // calculate union layout in function body
     
    566550                                if ( tyParam.second.isComplete ) {
    567551                                        Type *concrete = env->lookup( tyParam.first );
    568                                         if ( concrete ) {
    569                                                 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
    570                                                 arg++;
    571                                                 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );
    572                                                 arg++;
    573                                         } else {
    574                                                 // xxx - should this be an assertion?
    575                                                 SemanticError( appExpr, toString( *env, "\nunbound type variable: ", tyParam.first, " in application " ) );
    576                                         } // if
     552                                        // If there is an unbound type variable, it should have detected already.
     553                                        assertf( concrete, "Unbound type variable: %s in: %s",
     554                                                toCString( tyParam.first ), toCString( *env ) );
     555
     556                                        arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
     557                                        arg++;
     558                                        arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );
     559                                        arg++;
    577560                                } // if
    578561                        } // for
     
    638621
    639622                void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) {
    640                         for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
    641                                 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     623                        for ( Expression * const param : params ) {
     624                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( param );
    642625                                assertf(paramType, "Aggregate parameters should be type expressions");
    643626                                paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) );
     
    692675                }
    693676
     677                // find instances of polymorphic type parameters
     678                struct PolyFinder {
     679                        const TyVarMap * tyVars = nullptr;
     680                        bool found = false;
     681
     682                        void previsit( TypeInstType * t ) {
     683                                if ( isPolyType( t, *tyVars ) ) {
     684                                        found = true;
     685                                }
     686                        }
     687                };
     688
     689                // true if there is an instance of a polymorphic type parameter in t
     690                bool hasPolymorphism( Type * t, const TyVarMap &tyVars ) {
     691                        PassVisitor<PolyFinder> finder;
     692                        finder.pass.tyVars = &tyVars;
     693                        maybeAccept( t, finder );
     694                        return finder.pass.found;
     695                }
     696
     697                /// cast parameters to polymorphic functions so that types are replaced with
     698                /// void * if they are type parameters in the formal type.
     699                /// this gets rid of warnings from gcc.
     700                void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
     701                        // type contains polymorphism, but isn't exactly a polytype, in which case it
     702                        // has some real actual type (e.g. unsigned int) and casting to void * is wrong
     703                        if ( hasPolymorphism( formal, tyVars ) && ! isPolyType( formal, tyVars ) ) {
     704                                Type * newType = formal->clone();
     705                                newType = ScrubTyVars::scrub( newType, tyVars );
     706                                actual = new CastExpr( actual, newType );
     707                        } // if
     708                }
     709
    694710                void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
    695711                        assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() );
     712                        addCast( arg, param, exprTyVars );
    696713                        if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return;
    697714
     
    724741                }
    725742
    726                 // find instances of polymorphic type parameters
    727                 struct PolyFinder {
    728                         const TyVarMap * tyVars = nullptr;
    729                         bool found = false;
    730 
    731                         void previsit( TypeInstType * t ) {
    732                                 if ( isPolyType( t, *tyVars ) ) {
    733                                         found = true;
    734                                 }
    735                         }
    736                 };
    737 
    738                 // true if there is an instance of a polymorphic type parameter in t
    739                 bool hasPolymorphism( Type * t, const TyVarMap &tyVars ) {
    740                         PassVisitor<PolyFinder> finder;
    741                         finder.pass.tyVars = &tyVars;
    742                         maybeAccept( t, finder );
    743                         return finder.pass.found;
    744                 }
    745 
    746                 /// cast parameters to polymorphic functions so that types are replaced with
    747                 /// void * if they are type parameters in the formal type.
    748                 /// this gets rid of warnings from gcc.
    749                 void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
    750                         // type contains polymorphism, but isn't exactly a polytype, in which case it
    751                         // has some real actual type (e.g. unsigned int) and casting to void * is wrong
    752                         if ( hasPolymorphism( formal, tyVars ) && ! isPolyType( formal, tyVars ) ) {
    753                                 Type * newType = formal->clone();
    754                                 newType = ScrubTyVars::scrub( newType, tyVars );
    755                                 actual = new CastExpr( actual, newType );
    756                         } // if
    757                 }
    758 
    759743                void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    760                         for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->parameters.end(); ++param, ++arg ) {
    761                                 assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( *param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() );
    762                                 addCast( *arg, (*param)->get_type(), exprTyVars );
    763                                 boxParam( (*param)->get_type(), *arg, exprTyVars );
     744                        for ( DeclarationWithType * param : function->parameters ) {
     745                                assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() );
     746                                boxParam( param->get_type(), *arg, exprTyVars );
     747                                ++arg;
    764748                        } // for
    765749                }
     
    767751                void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
    768752                        std::list< Expression *>::iterator cur = arg;
    769                         for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    770                                 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {
    771                                         InferredParams::const_iterator inferParam = appExpr->inferParams.find( (*assert)->get_uniqueId() );
    772                                         assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );
     753                        for ( TypeDecl * const tyVar : functionType->forall ) {
     754                                for ( DeclarationWithType * const assert : tyVar->assertions ) {
     755                                        InferredParams::const_iterator inferParam = appExpr->inferParams.find( assert->get_uniqueId() );
     756                                        assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( assert ).c_str(), toString( appExpr ).c_str() );
    773757                                        Expression *newExpr = inferParam->second.expr->clone();
    774                                         addCast( newExpr, (*assert)->get_type(), tyVars );
    775                                         boxParam( (*assert)->get_type(), newExpr, tyVars );
     758                                        boxParam( assert->get_type(), newExpr, tyVars );
    776759                                        appExpr->get_args().insert( cur, newExpr );
    777760                                } // for
     
    803786                        assert( param );
    804787                        assert( arg );
    805                         if ( isPolyType( realParam->get_type(), tyVars ) ) {
    806                                 if ( ! isPolyType( arg->get_type() ) ) {
    807                                         UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    808                                         deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
    809                                         deref->result = arg->get_type()->clone();
    810                                         return deref;
    811                                 } // if
     788                        if ( isPolyType( realParam->get_type(), tyVars )
     789                                        && ! isPolyType( arg->get_type() ) ) {
     790                                UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     791                                deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
     792                                deref->result = arg->get_type()->clone();
     793                                return deref;
    812794                        } // if
    813795                        return new VariableExpr( param );
     
    11451127                }
    11461128
    1147                 Expression * Pass1::postmutate( UntypedExpr *expr ) {
     1129                bool isPolyDeref( UntypedExpr * expr, TyVarMap const & scopeTyVars, TypeSubstitution const * env ) {
    11481130                        if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
    11491131                                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
    11501132                                        if ( name->name == "*?" ) {
    1151                                                 Expression *ret = expr->args.front();
    1152                                                 expr->args.clear();
    1153                                                 delete expr;
    1154                                                 return ret;
     1133                                                return true;
    11551134                                        } // if
    11561135                                } // if
    11571136                        } // if
     1137                        return false;
     1138                }
     1139
     1140                Expression * Pass1::postmutate( UntypedExpr *expr ) {
     1141                        if ( isPolyDeref( expr, scopeTyVars, env ) ) {
     1142                                Expression *ret = expr->args.front();
     1143                                expr->args.clear();
     1144                                delete expr;
     1145                                return ret;
     1146                        }
    11581147                        return expr;
    11591148                }
     
    11651154                        bool needs = false;
    11661155                        if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->arg ) ) {
    1167                                 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
    1168                                         if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
    1169                                                 if ( name->name == "*?" ) {
    1170                                                         if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) {
    1171                                                                 assert( appExpr->function->result );
    1172                                                                 FunctionType *function = getFunctionType( appExpr->function->result );
    1173                                                                 assert( function );
    1174                                                                 needs = needsAdapter( function, scopeTyVars );
    1175                                                         } // if
    1176                                                 } // if
     1156                                if ( isPolyDeref( expr, scopeTyVars, env ) ) {
     1157                                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) {
     1158                                                assert( appExpr->function->result );
     1159                                                FunctionType *function = getFunctionType( appExpr->function->result );
     1160                                                assert( function );
     1161                                                needs = needsAdapter( function, scopeTyVars );
    11771162                                        } // if
    11781163                                } // if
     
    12261211                        std::list< DeclarationWithType *> &paramList = functionType->parameters;
    12271212                        std::list< FunctionType *> functions;
    1228                         for (  DeclarationWithType * const arg : functionType->parameters ) {
     1213                        for ( DeclarationWithType * const arg : functionType->parameters ) {
    12291214                                Type *orig = arg->get_type();
    12301215                                findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter );
     
    14471432
    14481433                        if(!expect_func_type) {
    1449                                 GuardAction( [this]() {
    1450                                         knownLayouts.endScope();
    1451                                         knownOffsets.endScope();
    1452                                 });
    14531434                                // If this is the first function type we see
    14541435                                // Then it's the type of the declaration and we care about it
    1455                                 knownLayouts.beginScope();
    1456                                 knownOffsets.beginScope();
     1436                                GuardScope( *this );
    14571437                        }
    14581438
  • src/GenPoly/GenPoly.cc

    r0bdfcc3 re50d9cb8  
    120120        const ast::Type * replaceTypeInst(const ast::Type * type, const ast::TypeSubstitution * env) {
    121121                if (!env) return type;
    122                 if (auto typeInst = dynamic_cast<const ast::TypeInstType*> (type)) {
     122                if ( auto typeInst = dynamic_cast<const ast::TypeInstType*>(type) ) {
    123123                        auto newType = env->lookup(typeInst);
    124124                        if (newType) return newType;
     
    229229                auto var = typeVars.find( *inst );
    230230                if ( var != typeVars.end() && var->second.isComplete ) {
    231 
     231                        return inst;
    232232                }
    233233        } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) {
  • src/GenPoly/InstantiateGenericNew.cpp

    r0bdfcc3 re50d9cb8  
    1010// Created On       : Tue Aug 16 10:51:00 2022
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Sep 13 16:03:00 2022
    13 // Update Count     : 0
     12// Last Modified On : Mon Oct 31 16:48:00 2022
     13// Update Count     : 1
    1414//
    1515
     
    378378                //   Ptr(int) p;
    379379                //   int i;
     380                // The original expression:
    380381                //   p.x = &i;
    381                 // becomes
    382                 //   int *& _dtype_static_member_0 = (int **)&p.x;
    383                 //   _dtype_static_member_0 = &i;
     382                // Becomes the expression/declaration:
     383                //   int *& _dtype_static_member_0;
     384                //   (_dtype_static_member_0 = (int**)&p.x,
     385                //    _dtype_static_member_0) = &i;
     386
     387                // The declaration is simple:
    384388                static UniqueName tmpNamer( "_dtype_static_member_" );
    385                 ast::Expr * init = new ast::CastExpr( location,
    386                         new ast::AddressExpr( location, memberExpr ),
    387                         new ast::PointerType( ast::deepCopy( concType ) ),
    388                         ast::ExplicitCast
    389                 );
    390389                ast::ObjectDecl * tmp = new ast::ObjectDecl( location,
    391390                        tmpNamer.newName(),
    392391                        new ast::ReferenceType( concType ),
    393                         new ast::SingleInit( location, init ),
     392                        nullptr,
    394393                        ast::Storage::Classes(),
    395394                        ast::Linkage::C
    396395                );
    397396                stmtsToAddBefore.push_back( new ast::DeclStmt( location, tmp ) );
    398                 return new ast::VariableExpr( location, tmp );
     397
     398                // The expression is more complex, uses references and reference /
     399                // pointer parity. But breaking it up risks reordering.
     400                return new ast::CommaExpr( location,
     401                        ast::UntypedExpr::createAssign( location,
     402                                new ast::VariableExpr( location, tmp ),
     403                                new ast::CastExpr( location,
     404                                        new ast::AddressExpr( location, memberExpr ),
     405                                        new ast::PointerType( ast::deepCopy( concType ) ),
     406                                        ast::ExplicitCast
     407                                )
     408                        ),
     409                        new ast::VariableExpr( location, tmp )
     410                );
    399411        } else {
    400412                // Here, it can simply add a cast to actual types.
Note: See TracChangeset for help on using the changeset viewer.