Changeset b067d9b for src/GenPoly


Ignore:
Timestamp:
Oct 29, 2019, 4:01:24 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
Children:
773db65, 9421f3d8
Parents:
7951100 (diff), 8364209 (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

Location:
src/GenPoly
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r7951100 rb067d9b  
    7676
    7777                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    78                 class Pass1 final : public BoxPass, public WithTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {
     78                class Pass1 final : public BoxPass, public WithConstTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {
    7979                  public:
    8080                        Pass1();
     
    150150                /// * Calculates polymorphic offsetof expressions from offset array
    151151                /// * Inserts dynamic calculation of polymorphic type layouts where needed
    152                 class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
     152                class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithConstTypeSubstitution {
    153153                public:
    154154                        PolyGenericCalculator();
     
    657657                                paramExpr = new AddressExpr( paramExpr );
    658658                        } // if
    659                         arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call
     659                        arg = appExpr->args.insert( arg, paramExpr ); // add argument to function call
    660660                        arg++;
    661661                        // Build a comma expression to call the function and emulate a normal return.
    662662                        CommaExpr *commaExpr = new CommaExpr( appExpr, retExpr );
    663                         commaExpr->set_env( appExpr->get_env() );
    664                         appExpr->set_env( 0 );
     663                        commaExpr->env = appExpr->env;
     664                        appExpr->env = nullptr;
    665665                        return commaExpr;
    666666                }
     
    708708//                      if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {
    709709                        if ( isDynRet( function, tyVars ) ) {
    710                                 ret = addRetParam( appExpr, function->get_returnVals().front()->get_type(), arg );
     710                                ret = addRetParam( appExpr, function->returnVals.front()->get_type(), arg );
    711711                        } // if
    712712                        std::string mangleName = mangleAdapterName( function, tyVars );
     
    715715                        // cast adaptee to void (*)(), since it may have any type inside a polymorphic function
    716716                        Type * adapteeType = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
    717                         appExpr->get_args().push_front( new CastExpr( appExpr->get_function(), adapteeType ) );
     717                        appExpr->get_args().push_front( new CastExpr( appExpr->function, adapteeType ) );
    718718                        appExpr->set_function( new NameExpr( adapterName ) ); // xxx - result is never set on NameExpr
    719719
     
    725725                        if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return;
    726726
    727                         if ( arg->result->get_lvalue() ) {
     727                        if ( arg->get_lvalue() ) {
    728728                                // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations.
    729729                                // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) {
     
    798798                        for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    799799                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {
    800                                         InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() );
    801                                         assertf( inferParam != appExpr->get_inferParams().end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );
     800                                        InferredParams::const_iterator inferParam = appExpr->inferParams.find( (*assert)->get_uniqueId() );
     801                                        assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );
    802802                                        Expression *newExpr = inferParam->second.expr->clone();
    803803                                        addCast( newExpr, (*assert)->get_type(), tyVars );
     
    837837                                        deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
    838838                                        deref->result = arg->get_type()->clone();
    839                                         deref->result->set_lvalue( true );
    840839                                        return deref;
    841840                                } // if
     
    17641763
    17651764                Expression *PolyGenericCalculator::postmutate( SizeofExpr *sizeofExpr ) {
    1766                         Type *ty = sizeofExpr->get_isType() ? 
     1765                        Type *ty = sizeofExpr->get_isType() ?
    17671766                                sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result();
    1768                        
     1767
    17691768                        Expression * gen = genSizeof( ty );
    17701769                        if ( gen ) {
  • src/GenPoly/GenPoly.cc

    r7951100 rb067d9b  
    2424#include <vector>                       // for vector
    2525
     26#include "AST/Type.hpp"
    2627#include "GenPoly/ErasableScopedMap.h"  // for ErasableScopedMap<>::const_it...
    2728#include "ResolvExpr/typeops.h"         // for flatten
     
    262263                } else {
    263264                        return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
     265                }
     266        }
     267
     268        const ast::FunctionType * getFunctionType( const ast::Type * ty ) {
     269                if ( auto pty = dynamic_cast< const ast::PointerType * >( ty ) ) {
     270                        return pty->base.as< ast::FunctionType >();
     271                } else {
     272                        return dynamic_cast< const ast::FunctionType * >( ty );
    264273                }
    265274        }
     
    440449        }
    441450
    442         bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env ) {
     451        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) {
    443452                // is parameter is not polymorphic, don't need to box
    444453                if ( ! isPolyType( param, exprTyVars ) ) return false;
     
    450459        }
    451460
    452         bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env ) {
     461        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) {
    453462                FunctionType * function = getFunctionType( appExpr->function->result );
    454463                assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() );
     
    459468
    460469        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
    461                 // xxx - should this actually be insert?
    462                 tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar };
     470                tyVarMap.insert( tyVar->name, TypeDecl::Data{ tyVar } );
    463471        }
    464472
  • src/GenPoly/GenPoly.h

    r7951100 rb067d9b  
    2020
    2121#include "ErasableScopedMap.h"    // for ErasableScopedMap
     22#include "AST/Fwd.hpp"
    2223#include "SymTab/Mangler.h"       // for Mangler
    2324#include "SynTree/Declaration.h"  // for TypeDecl::Data, AggregateDecl, Type...
     
    7273        /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
    7374        FunctionType *getFunctionType( Type *ty );
     75        const ast::FunctionType * getFunctionType( const ast::Type * ty );
    7476
    7577        /// If expr (after dereferencing N >= 0 pointers) is a variable expression, returns the variable expression, NULL otherwise;
     
    8183
    8284        /// true if arg requires boxing given exprTyVars
    83         bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env );
     85        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env );
    8486
    8587        /// true if arg requires boxing in the call to appExpr
    86         bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env );
     88        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env );
    8789
    8890        /// Adds the type variable `tyVar` to `tyVarMap`
  • src/GenPoly/InstantiateGeneric.cc

    r7951100 rb067d9b  
    168168
    169169        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    170         struct GenericInstantiator final : public WithTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards {
     170        struct GenericInstantiator final : public WithConstTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards {
    171171                /// Map of (generic type, parameter list) pairs to concrete type instantiations
    172172                InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
  • src/GenPoly/Lvalue.cc

    r7951100 rb067d9b  
    2121#include "Lvalue.h"
    2222
     23#include "InitTweak/InitTweak.h"
    2324#include "Parser/LinkageSpec.h"          // for Spec, isBuiltin, Intrinsic
    2425#include "ResolvExpr/TypeEnvironment.h"  // for AssertionSet, OpenVarSet
    2526#include "ResolvExpr/Unify.h"            // for unify
    2627#include "ResolvExpr/typeops.h"
    27 #include "SymTab/Autogen.h"
    2828#include "SymTab/Indexer.h"              // for Indexer
    2929#include "SynTree/Declaration.h"         // for Declaration, FunctionDecl
     
    3333#include "SynTree/Type.h"                // for PointerType, Type, FunctionType
    3434#include "SynTree/Visitor.h"             // for Visitor, acceptAll
     35#include "Validate/FindSpecialDecls.h"   // for dereferenceOperator
    3536
    3637#if 0
     
    4445                // TODO: fold this into the general createDeref function??
    4546                Expression * mkDeref( Expression * arg ) {
    46                         if ( SymTab::dereferenceOperator ) {
     47                        if ( Validate::dereferenceOperator ) {
    4748                                // note: reference depth can be arbitrarily deep here, so peel off the outermost pointer/reference, not just pointer because they are effecitvely equivalent in this pass
    48                                 VariableExpr * deref = new VariableExpr( SymTab::dereferenceOperator );
     49                                VariableExpr * deref = new VariableExpr( Validate::dereferenceOperator );
    4950                                deref->result = new PointerType( Type::Qualifiers(), deref->result );
    5051                                Type * base = InitTweak::getPointerBase( arg->result );
     
    5354                                delete ret->result;
    5455                                ret->result = base->clone();
    55                                 ret->result->set_lvalue( true );
    5656                                return ret;
    5757                        } else {
     
    146146
    147147        namespace {
    148                 // true for intrinsic function calls that return a reference
     148                // true for intrinsic function calls that return an lvalue in C
    149149                bool isIntrinsicReference( Expression * expr ) {
     150                        // known intrinsic-reference prelude functions
     151                        static std::set<std::string> lvalueFunctions = { "*?", "?[?]" };
    150152                        if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( expr ) ) {
    151153                                std::string fname = InitTweak::getFunctionName( untyped );
    152                                 // known intrinsic-reference prelude functions
    153                                 return fname == "*?" || fname == "?[?]";
     154                                return lvalueFunctions.count(fname);
    154155                        } else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) {
    155156                                if ( DeclarationWithType * func = InitTweak::getFunction( appExpr ) ) {
    156                                         // use type of return variable rather than expr result type, since it may have been changed to a pointer type
    157                                         FunctionType * ftype = GenPoly::getFunctionType( func->get_type() );
    158                                         Type * ret = ftype->returnVals.empty() ? nullptr : ftype->returnVals.front()->get_type();
    159                                         return func->linkage == LinkageSpec::Intrinsic && dynamic_cast<ReferenceType *>( ret );
     157                                        return func->linkage == LinkageSpec::Intrinsic && lvalueFunctions.count(func->name);
    160158                                }
    161159                        }
     
    168166                                ReferenceType * result = strict_dynamic_cast< ReferenceType * >( appExpr->result );
    169167                                appExpr->result = result->base->clone();
    170                                 appExpr->result->set_lvalue( true );
    171168                                if ( ! inIntrinsic ) {
    172169                                        // when not in an intrinsic function, add a cast to
     
    197194                                unsigned int i = 0;
    198195                                const unsigned int end = ftype->parameters.size();
     196
     197                                /// The for loop may eagerly dereference the iterators and fail on empty lists
     198                                if(i == end) { return appExpr; }
    199199                                for ( auto p : unsafe_group_iterate( appExpr->args, ftype->parameters ) ) {
    200                                         if (i == end) break;
    201200                                        Expression *& arg = std::get<0>( p );
    202201                                        Type * formal = std::get<1>( p )->get_type();
     
    212211                                                // TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation.
    213212
    214                                                 if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
     213                                                if ( function->linkage != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
    215214                                                        // needed for definition of prelude functions, etc.
    216215                                                        // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address
     
    228227                                                        arg = new AddressExpr( arg );
    229228                                                // } else if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) {
    230                                                 } else if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
     229                                                } else if ( function->linkage == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
    231230                                                        // argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument
    232231                                                        PRINT(
     
    243242                                        }
    244243                                        ++i;
     244                                        if (i == end) break;
    245245                                }
    246246                        }
     
    355355                        Type * destType = castExpr->result;
    356356                        Type * srcType = castExpr->arg->result;
     357                        assertf( destType, "Cast to no type in: %s", toCString( castExpr ) );
     358                        assertf( srcType, "Cast from no type in: %s", toCString( castExpr ) );
    357359                        int depth1 = destType->referenceDepth();
    358360                        int depth2 = srcType->referenceDepth();
    359361                        int diff = depth1 - depth2;
    360362
    361                         if ( diff > 0 && ! srcType->get_lvalue() ) {
     363                        if ( diff > 0 && ! castExpr->arg->get_lvalue() ) {
    362364                                // rvalue to reference conversion -- introduce temporary
    363365                                // know that reference depth of cast argument is 0, need to introduce n temporaries for reference depth of n, e.g.
     
    403405                                        ret = new AddressExpr( ret );
    404406                                }
    405                                 if ( srcType->get_lvalue() && ! ResolvExpr::typesCompatible( srcType, strict_dynamic_cast<ReferenceType *>( destType )->base, SymTab::Indexer() ) ) {
     407                                if ( castExpr->arg->get_lvalue() && ! ResolvExpr::typesCompatible( srcType, strict_dynamic_cast<ReferenceType *>( destType )->base, SymTab::Indexer() ) ) {
    406408                                        // must keep cast if cast-to type is different from the actual type
    407409                                        castExpr->arg = ret;
     
    432434                                delete ret->result;
    433435                                ret->result = castExpr->result;
    434                                 ret->result->set_lvalue( true ); // ensure result is lvalue
     436                                assert( ret->get_lvalue() ); // ensure result is lvalue
    435437                                castExpr->env = nullptr;
    436438                                castExpr->arg = nullptr;
  • src/GenPoly/ScopedSet.h

    r7951100 rb067d9b  
    3838                typedef typename Scope::pointer pointer;
    3939                typedef typename Scope::const_pointer const_pointer;
    40                
     40
    4141                class iterator : public std::iterator< std::bidirectional_iterator_tag,
    4242                                                       value_type > {
     
    7272                                return *this;
    7373                        }
    74                        
     74
    7575                        reference operator* () { return *it; }
    7676                        pointer operator-> () { return it.operator->(); }
     
    104104                        bool operator!= (const iterator &that) { return !( *this == that ); }
    105105
     106                        size_type get_level() const { return i; }
     107
    106108                private:
    107109                        scope_list const *scopes;
     
    180182                        bool operator!= (const const_iterator &that) { return !( *this == that ); }
    181183
     184                        size_type get_level() const { return i; }
     185
    182186                private:
    183187                        scope_list const *scopes;
     
    185189                        size_type i;
    186190                };
    187                
     191
    188192                /// Starts a new scope
    189193                void beginScope() {
     
    222226                        return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) );
    223227                }
    224                
     228
    225229                /// Finds the given key in the outermost scope inside the given scope where it occurs
    226230                iterator findNext( const_iterator &it, const Value &key ) {
     
    242246                        return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second );
    243247                }
    244                
     248
    245249        };
    246250} // namespace GenPoly
  • src/GenPoly/ScrubTyVars.cc

    r7951100 rb067d9b  
    5050                                delete typeInst;
    5151                                return new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
     52                          default:
     53                                assertf(false, "Unhandled tyvar kind: %d", tyVar->second.kind);
    5254                        } // switch
    5355                } // if
  • src/GenPoly/Specialize.cc

    r7951100 rb067d9b  
    4242
    4343namespace GenPoly {
    44         struct Specialize final : public WithTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> {
     44        struct Specialize final : public WithConstTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> {
    4545                Expression * postmutate( ApplicationExpr *applicationExpr );
    4646                Expression * postmutate( CastExpr *castExpr );
     
    5454
    5555        /// Looks up open variables in actual type, returning true if any of them are bound in the environment or formal type.
    56         bool needsPolySpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
     56        bool needsPolySpecialization( Type *formalType, Type *actualType, const TypeSubstitution *env ) {
    5757                if ( env ) {
    5858                        using namespace ResolvExpr;
     
    145145        }
    146146
    147         bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
     147        bool needsSpecialization( Type *formalType, Type *actualType, const TypeSubstitution *env ) {
    148148                return needsPolySpecialization( formalType, actualType, env ) || needsTupleSpecialization( formalType, actualType );
    149149        }
     
    245245                appExpr->env = TypeSubstitution::newFromExpr( appExpr, env );
    246246                if ( inferParams ) {
    247                         appExpr->get_inferParams() = *inferParams;
     247                        appExpr->inferParams = *inferParams;
    248248                } // if
    249249
     
    284284                std::list< Expression* >::iterator actual;
    285285                for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) {
    286                         *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() );
     286                        *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->inferParams );
    287287                }
    288288        }
     
    295295                        // alternatively, if order starts to matter then copy appExpr's inferParams and pass them to handleExplicitParams.
    296296                        handleExplicitParams( appExpr );
    297                         for ( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) {
    298                                 inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, inferParam->second.inferParams.get() );
     297                        for ( InferredParams::iterator inferParam = appExpr->inferParams.begin(); inferParam != appExpr->inferParams.end(); ++inferParam ) {
     298                                inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, &inferParam->second.expr->inferParams );
    299299                        }
    300300                }
  • src/GenPoly/module.mk

    r7951100 rb067d9b  
    2222       GenPoly/FindFunction.cc \
    2323       GenPoly/InstantiateGeneric.cc
     24
     25SRCDEMANGLE += GenPoly/GenPoly.cc GenPoly/Lvalue.cc
     26
Note: See TracChangeset for help on using the changeset viewer.