Changeset 265e460 for src/GenPoly


Ignore:
Timestamp:
Oct 8, 2022, 9:43:21 AM (3 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, ast-experimental, master
Children:
b2ddaf3
Parents:
815943f (diff), d8c96a9 (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:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r815943f r265e460  
    6666                };
    6767
    68                 /// Adds layout-generation functions to polymorphic types
     68                /// Adds layout-generation functions to polymorphic types.
    6969                class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting {
    70                         unsigned int functionNesting = 0;  // current level of nested functions
     70                        // Current level of nested functions:
     71                        unsigned int functionNesting = 0;
    7172                public:
    7273                        void previsit( FunctionDecl *functionDecl );
     
    7576                };
    7677
    77                 /// 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                /// Replaces polymorphic return types with out-parameters,
     79                /// replaces calls to polymorphic functions with adapter calls,
     80                /// and adds appropriate type variables to the function call.
    7881                class Pass1 final : public BoxPass, public WithConstTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {
    7982                  public:
     
    146149                };
    147150
    148                 /// Replaces member and size/align/offsetof expressions on polymorphic generic types with calculated expressions.
     151                /// * Replaces member and size/align/offsetof expressions on polymorphic generic types with calculated expressions.
    149152                /// * Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference
    150153                /// * Calculates polymorphic offsetof expressions from offset array
     
    199202                };
    200203
    201                 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, sizeof expressions of polymorphic types with the proper variable, and strips fields from generic struct declarations.
     204                /// Replaces initialization of polymorphic values with alloca,
     205                /// declaration of dtype/ftype with appropriate void expression,
     206                /// sizeof expressions of polymorphic types with the proper variable,
     207                /// and strips fields from generic struct declarations.
    202208                struct Pass3 final : public BoxPass, public WithGuards {
    203209                        template< typename DeclClass >
  • src/GenPoly/GenPoly.cc

    r815943f r265e460  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Sep 14  9:24:00 2022
    13 // Update Count     : 15
     12// Last Modified On : Fri Oct  7 15:25:00 2022
     13// Update Count     : 16
    1414//
    1515
     
    6464                }
    6565
    66                 __attribute__((unused))
    67                 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {
    68                         for (auto &param : params) {
    69                                 auto paramType = param.strict_as<ast::TypeExpr>();
    70                                 if (isPolyType(paramType->type, tyVars, env)) return true;
    71                         }
    72                         return false;
    73                 }
    74 
    7566                /// Checks a parameter list for dynamic-layout parameters from tyVars; will substitute according to env if present
    7667                bool hasDynParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     
    8374                }
    8475
    85                 bool hasDynParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) {
    86                         for ( ast::ptr<ast::Expr> const & param : params ) {
    87                                 auto paramType = param.as<ast::TypeExpr>();
    88                                 assertf( paramType, "Aggregate parameters should be type expressions." );
    89                                 if ( isDynType( paramType->type, tyVars, typeSubs ) ) {
     76                bool hasDynParams(
     77                                const std::vector<ast::ptr<ast::Expr>> & params,
     78                                const TypeVarMap & typeVars,
     79                                const ast::TypeSubstitution * subst ) {
     80                        for ( ast::ptr<ast::Expr> const & paramExpr : params ) {
     81                                auto param = paramExpr.as<ast::TypeExpr>();
     82                                assertf( param, "Aggregate parameters should be type expressions." );
     83                                if ( isDynType( param->type.get(), typeVars, subst ) ) {
    9084                                        return true;
    9185                                }
     
    195189        }
    196190
     191const ast::Type * isPolyType( const ast::Type * type,
     192                const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ) {
     193        type = replaceTypeInst( type, subst );
     194
     195        if ( auto inst = dynamic_cast< const ast::TypeInstType * >( type ) ) {
     196                if ( typeVars.find( inst->typeString() ) != typeVars.end() ) return type;
     197        } else if ( auto array = dynamic_cast< const ast::ArrayType * >( type ) ) {
     198                return isPolyType( array->base, subst );
     199        } else if ( auto sue = dynamic_cast< const ast::StructInstType * >( type ) ) {
     200                if ( hasPolyParams( sue->params, subst ) ) return type;
     201        } else if ( auto sue = dynamic_cast< const ast::UnionInstType * >( type ) ) {
     202                if ( hasPolyParams( sue->params, subst ) ) return type;
     203        }
     204        return nullptr;
     205}
     206
    197207        ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
    198208                type = replaceTypeInst( type, env );
     
    211221        }
    212222
    213         const ast::BaseInstType *isDynType( const ast::Type *type, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) {
    214                 type = replaceTypeInst( type, typeSubs );
    215 
    216                 if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) {
    217                         auto var = tyVars.find( inst->name );
    218                         if ( var != tyVars.end() && var->second.isComplete ) {
    219                                 return inst;
    220                         }
    221                 } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) {
    222                         if ( hasDynParams( inst->params, tyVars, typeSubs ) ) {
    223                                 return inst;
    224                         }
    225                 } else if ( auto inst = dynamic_cast<ast::UnionInstType const *>( type ) ) {
    226                         if ( hasDynParams( inst->params, tyVars, typeSubs ) ) {
    227                                 return inst;
    228                         }
    229                 }
    230                 return nullptr;
    231         }
     223const ast::BaseInstType * isDynType(
     224                const ast::Type * type, const TypeVarMap & typeVars,
     225                const ast::TypeSubstitution * subst ) {
     226        type = replaceTypeInst( type, subst );
     227
     228        if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) {
     229                auto var = typeVars.find( inst->name );
     230                if ( var != typeVars.end() && var->second.isComplete ) {
     231
     232                }
     233        } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) {
     234                if ( hasDynParams( inst->params, typeVars, subst ) ) {
     235                        return inst;
     236                }
     237        } else if ( auto inst = dynamic_cast<ast::UnionInstType const *>( type ) ) {
     238                if ( hasDynParams( inst->params, typeVars, subst ) ) {
     239                        return inst;
     240                }
     241        }
     242        return nullptr;
     243}
    232244
    233245        ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &forallTypes ) {
     
    236248                return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes );
    237249        }
     250
     251const ast::BaseInstType *isDynRet(
     252                const ast::FunctionType * type, const TypeVarMap & typeVars ) {
     253        if ( type->returns.empty() ) return nullptr;
     254
     255        return isDynType( type->returns.front(), typeVars );
     256}
    238257
    239258        ReferenceToType *isDynRet( FunctionType *function ) {
     
    260279        }
    261280
     281bool needsAdapter(
     282                ast::FunctionType const * adaptee, const TypeVarMap & typeVars ) {
     283        if ( isDynRet( adaptee, typeVars ) ) return true;
     284
     285        for ( auto param : adaptee->params ) {
     286                if ( isDynType( param, typeVars ) ) {
     287                        return true;
     288                }
     289        }
     290        return false;
     291}
     292
    262293        Type *isPolyPtr( Type *type, const TypeSubstitution *env ) {
    263294                type = replaceTypeInst( type, env );
     
    311342                return isPolyType( type, tyVars, env );
    312343        }
     344
     345ast::Type const * hasPolyBase(
     346                ast::Type const * type, const TypeVarMap & typeVars,
     347                int * levels, const ast::TypeSubstitution * subst ) {
     348        int level_count = 0;
     349
     350        while ( true ) {
     351                type = replaceTypeInst( type, subst );
     352
     353                if ( auto ptr = dynamic_cast<ast::PointerType const *>( type ) ) {
     354                        type = ptr->base;
     355                        ++level_count;
     356                } else {
     357                        break;
     358                }
     359        }
     360
     361        if ( nullptr != levels ) { *levels = level_count; }
     362        return isPolyType( type, typeVars, subst );
     363}
    313364
    314365        bool includesPolyType( Type *type, const TypeSubstitution *env ) {
     
    685736}
    686737
    687         namespace {
    688                 // temporary hack to avoid re-implementing anything related to TyVarMap
    689                 // does this work? these two structs have identical definitions.
    690                 inline TypeDecl::Data convData(const ast::TypeDecl::Data & data) {
    691                         return *reinterpret_cast<const TypeDecl::Data *>(&data);
    692                 }
    693         }
    694 
    695738        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) {
    696739                // is parameter is not polymorphic, don't need to box
     
    703746        }
    704747
    705         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TyVarMap &exprTyVars, const ast::TypeSubstitution * env) {
    706                 // is parameter is not polymorphic, don't need to box
    707                 if ( ! isPolyType( param, exprTyVars ) ) return false;
    708                 ast::ptr<ast::Type> newType = arg;
    709                 if ( env ) env->apply( newType );
    710                 // if the argument's type is polymorphic, we don't need to box again!
    711                 return ! isPolyType( newType );
    712         }
     748bool needsBoxing( const ast::Type * param, const ast::Type * arg,
     749                const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ) {
     750        // Don't need to box if the parameter is not polymorphic.
     751        if ( !isPolyType( param, typeVars ) ) return false;
     752
     753        ast::ptr<ast::Type> newType = arg;
     754        if ( subst ) {
     755                int count = subst->apply( newType );
     756                (void)count;
     757        }
     758        // Only need to box if the argument is not also polymorphic.
     759        return !isPolyType( newType );
     760}
    713761
    714762        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) {
     
    720768        }
    721769
    722         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * appExpr, const ast::TypeSubstitution * env) {
    723                 const ast::FunctionType * function = getFunctionType(appExpr->func->result);
    724                 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->func->result ).c_str() );
    725                 TyVarMap exprTyVars(TypeDecl::Data{});
    726                 makeTyVarMap(function, exprTyVars);
    727                 return needsBoxing(param, arg, exprTyVars, env);
    728 
    729         }
     770bool needsBoxing(
     771                const ast::Type * param, const ast::Type * arg,
     772                const ast::ApplicationExpr * expr,
     773                const ast::TypeSubstitution * subst ) {
     774        const ast::FunctionType * function = getFunctionType( expr->func->result );
     775        assertf( function, "ApplicationExpr has non-function type: %s", toString( expr->func->result ).c_str() );
     776        TypeVarMap exprTyVars = { ast::TypeDecl::Data() };
     777        makeTypeVarMap( function, exprTyVars );
     778        return needsBoxing( param, arg, exprTyVars, subst );
     779}
    730780
    731781        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
     
    733783        }
    734784
    735         void addToTyVarMap( const ast::TypeInstType * tyVar, TyVarMap & tyVarMap) {
    736                 tyVarMap.insert(tyVar->typeString(), convData(ast::TypeDecl::Data{tyVar->base}));
    737         }
     785void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ) {
     786        typeVars.insert( type->typeString(), ast::TypeDecl::Data( type->base ) );
     787}
    738788
    739789        void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {
     
    747797        }
    748798
    749         void makeTyVarMap(const ast::Type * type, TyVarMap & tyVarMap) {
    750                 if (auto ptype = dynamic_cast<const ast::FunctionType *>(type)) {
    751                         for (auto & tyVar : ptype->forall) {
    752                                 assert (tyVar);
    753                                 addToTyVarMap(tyVar, tyVarMap);
    754                         }
    755                 }
    756                 if (auto pointer = dynamic_cast<const ast::PointerType *>(type)) {
    757                         makeTyVarMap(pointer->base, tyVarMap);
    758                 }
    759         }
     799void makeTypeVarMap( const ast::Type * type, TypeVarMap & typeVars ) {
     800        if ( auto func = dynamic_cast<ast::FunctionType const *>( type ) ) {
     801                for ( auto & typeVar : func->forall ) {
     802                        assert( typeVar );
     803                        addToTypeVarMap( typeVar, typeVars );
     804                }
     805        }
     806        if ( auto pointer = dynamic_cast<ast::PointerType const *>( type ) ) {
     807                makeTypeVarMap( pointer->base, typeVars );
     808        }
     809}
    760810
    761811        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) {
     
    766816        }
    767817
     818void printTypeVarMap( std::ostream &os, const TypeVarMap & typeVars ) {
     819        for ( auto const & pair : typeVars ) {
     820                os << pair.first << " (" << pair.second << ") ";
     821        } // for
     822        os << std::endl;
     823}
     824
    768825} // namespace GenPoly
    769826
  • src/GenPoly/GenPoly.h

    r815943f r265e460  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 19 16:03:00 2022
    13 // Update Count     : 8
     12// Last Modified On : Fri Oct  7 15:06:00 2022
     13// Update Count     : 9
    1414//
    1515
     
    2020
    2121#include "ErasableScopedMap.h"    // for ErasableScopedMap
    22 #include "AST/Fwd.hpp"
     22#include "AST/Decl.hpp"           // for TypeDecl::Data
     23#include "AST/Fwd.hpp"            // for ApplicationExpr, BaseInstType, Func...
    2324#include "SymTab/Mangler.h"       // for Mangler
    2425#include "SynTree/Declaration.h"  // for TypeDecl::Data, AggregateDecl, Type...
     
    2930        // TODO Via some tricks this works for ast::TypeDecl::Data as well.
    3031        typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap;
     32        using TypeVarMap = ErasableScopedMap< std::string, ast::TypeDecl::Data >;
    3133
    3234        /// Replaces a TypeInstType by its referrent in the environment, if applicable
     
    3941        /// returns polymorphic type if is polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
    4042        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
    41         const ast::Type * isPolyType(const ast::Type * type, const TyVarMap & tyVars, const ast::TypeSubstitution * env = nullptr);
     43        const ast::Type * isPolyType( const ast::Type * type, const TypeVarMap & typeVars, const ast::TypeSubstitution * subst = nullptr );
    4244
    4345        /// returns dynamic-layout type if is dynamic-layout type in tyVars, NULL otherwise; will look up substitution in env if provided
    4446        ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
    45         const ast::BaseInstType *isDynType( const ast::Type *type, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs = 0 );
     47        const ast::BaseInstType *isDynType( const ast::Type * type, const TypeVarMap & typeVars, const ast::TypeSubstitution * subst = 0 );
    4648
    4749        /// true iff function has dynamic-layout return type under the given type variable map
    4850        ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &tyVars );
     51        const ast::BaseInstType *isDynRet( const ast::FunctionType * type, const TypeVarMap & typeVars );
    4952
    5053        /// true iff function has dynamic-layout return type under the type variable map generated from its forall-parameters
     
    5356        /// A function needs an adapter if it returns a dynamic-layout value or if any of its parameters have dynamic-layout type
    5457        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr );
     58        bool needsAdapter( ast::FunctionType const * adaptee, const TypeVarMap & typeVars );
    5559
    5660        /// returns polymorphic type if is pointer to polymorphic type, NULL otherwise; will look up substitution in env if provided
     
    5963        /// returns polymorphic type if is pointer to polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
    6064        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
     65        const ast::Type * isPolyPtr( const ast::Type * type, const TypeVarMap & typeVars, const ast::TypeSubstitution * env = 0 );
    6166
    6267        /// if the base type (after dereferencing N >= 0 pointers) is a polymorphic type, returns the base type, NULL otherwise;
     
    6772        /// N will be stored in levels, if provided, will look up substitution in env if provided
    6873        Type *hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels = 0, const TypeSubstitution *env = 0 );
     74        const ast::Type * hasPolyBase( const ast::Type * type, const TypeVarMap & typeVars, int * levels = 0, const ast::TypeSubstitution * env = 0 );
    6975
    7076        /// true iff this type or some base of this type after dereferencing pointers is either polymorphic or a generic type with at least one
     
    9096        /// true if arg requires boxing given exprTyVars
    9197        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env );
    92         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TyVarMap &exprTyVars, const ast::TypeSubstitution * env);
     98        bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TypeVarMap & typeVars, const ast::TypeSubstitution * subst );
    9399
    94100        /// true if arg requires boxing in the call to appExpr
    95101        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env );
    96         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * appExpr, const ast::TypeSubstitution * env);
     102        bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * expr, const ast::TypeSubstitution * subst );
    97103
    98104        /// Adds the type variable `tyVar` to `tyVarMap`
    99105        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap );
     106        void addToTypeVarMap( const ast::TypeDecl * type, TypeVarMap & typeVars );
    100107
    101108        /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap`
    102109        void makeTyVarMap( Type *type, TyVarMap &tyVarMap );
    103         void makeTyVarMap(const ast::Type * type, TyVarMap & tyVarMap);
     110        void makeTypeVarMap( const ast::Type * type, TypeVarMap & typeVars );
    104111
    105112        /// Prints type variable map
    106113        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap );
     114        void printTypeVarMap( std::ostream &os, const TypeVarMap & typeVars );
    107115
    108116        /// Gets the mangled name of this type; alias for SymTab::Mangler::mangleType().
  • src/GenPoly/Lvalue.h

    r815943f r265e460  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:21:59 2017
    13 // Update Count     : 2
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Sep 15 14:13:00 2022
     13// Update Count     : 3
    1414//
    1515
     
    2020class Declaration;
    2121class Expression;
     22namespace ast {
     23        class Expr;
     24        class TranslationUnit;
     25}
    2226
    2327namespace GenPoly {
    2428        /// replaces return type of `lvalue T` with `T*`, along with appropriate address-of and dereference operators
    2529        void convertLvalue( std::list< Declaration* >& translationUnit );
     30        void convertLvalue( ast::TranslationUnit & translationUnit );
    2631
    2732        /// true after reference types have been eliminated from the source code. After this point, reference types should not be added to the AST.
     
    3035        /// applies transformations that allow GCC to accept more complicated lvalue expressions, e.g. &(a, b)
    3136        Expression * generalizedLvalue( Expression * expr );
     37        ast::Expr const * generalizedLvalue( ast::Expr const * expr );
    3238} // namespace GenPoly
    3339
  • src/GenPoly/ScrubTyVars.cc

    r815943f r265e460  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 19 16:10:00 2022
    13 // Update Count     : 4
     12// Last Modified On : Fri Oct  7 15:42:00 2022
     13// Update Count     : 5
    1414//
    1515
     
    128128        public ast::WithVisitorRef<ScrubTypeVars> {
    129129
    130         ScrubTypeVars( ScrubMode m, TyVarMap const * tv ) :
     130        ScrubTypeVars( ScrubMode m, TypeVarMap const * tv ) :
    131131                        mode ( m ), typeVars( tv ) {}
    132132
     
    148148        ScrubMode const mode;
    149149        /// Type varriables to scrub.
    150         TyVarMap const * const typeVars;
     150        TypeVarMap const * const typeVars;
    151151        /// Value cached by primeBaseScrub.
    152152        ast::Type const * dynType = nullptr;
     
    255255const ast::Node * scrubTypeVarsBase(
    256256                const ast::Node * target,
    257                 ScrubMode mode, const TyVarMap * typeVars ) {
     257                ScrubMode mode, const TypeVarMap * typeVars ) {
    258258        if ( ScrubMode::All == mode ) {
    259259                assert( nullptr == typeVars );
     
    266266
    267267} // namespace
     268
     269template<>
     270ast::Node const * scrubTypeVars<ast::Node>(
     271        const ast::Node * target, const TypeVarMap & typeVars ) {
     272        return scrubTypeVarsBase( target, ScrubMode::FromMap, &typeVars );
     273}
     274
     275template<>
     276ast::Node const * scrubTypeVarsDynamic<ast::Node>(
     277        ast::Node const * target, const TypeVarMap & typeVars ) {
     278        return scrubTypeVarsBase( target, ScrubMode::DynamicFromMap, &typeVars );
     279}
    268280
    269281template<>
  • src/GenPoly/ScrubTyVars.h

    r815943f r265e460  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 19 14:14:00 2022
    13 // Update Count     : 3
     12// Last Modified On : Fri Oct  7 15:51:00 2022
     13// Update Count     : 4
    1414//
    1515
     
    109109        }
    110110
     111/// For all polymorphic types with type variables in `typeVars`,
     112/// replaces generic types, dtypes, and ftypes with the appropriate void type,
     113/// and sizeof/alignof expressions with the proper variable.
     114template<typename node_t>
     115node_t const * scrubTypeVars(
     116                node_t const * target, const TypeVarMap & typeVars ) {
     117        return strict_dynamic_cast<node_t const *>(
     118                        scrubTypeVars<ast::Node>( target ) );
     119}
     120
     121/// For all dynamic-layout types with type variables in `typeVars`,
     122/// replaces generic types, dtypes, and ftypes with the appropriate void type,
     123/// and sizeof/alignof expressions with the proper variable.
     124template<typename node_t>
     125ast::Node const * scrubTypeVarsDynamic(
     126                node_t const * target, const TypeVarMap & typeVars ) {
     127        return strict_dynamic_cast<node_t const *>(
     128                        scrubTypeVarsDynamic<ast::Node>( target, typeVars ) );
     129}
     130
    111131/// For all polymorphic types, replaces generic types, with the appropriate
    112132/// void type, and sizeof/alignof expressions with the proper variable.
    113133template<typename node_t>
    114134node_t const * scrubAllTypeVars( node_t const * target ) {
    115         return strict_dynamic_cast<node_t const *>( scrubAllTypeVars<ast::Node>( target ) );
     135        return strict_dynamic_cast<node_t const *>(
     136                        scrubAllTypeVars<ast::Node>( target ) );
    116137}
     138
     139// We specialize for Node as a base case.
     140template<>
     141ast::Node const * scrubTypeVars<ast::Node>(
     142                const ast::Node * target, const TypeVarMap & typeVars );
     143
     144template<>
     145ast::Node const * scrubTypeVarsDynamic<ast::Node>(
     146                ast::Node const * target, const TypeVarMap & typeVars );
    117147
    118148template<>
  • src/GenPoly/module.mk

    r815943f r265e460  
    3030        GenPoly/InstantiateGeneric.cc \
    3131        GenPoly/InstantiateGeneric.h \
     32        GenPoly/LvalueNew.cpp \
    3233        GenPoly/Lvalue.cc \
    3334        GenPoly/ScopedSet.h \
Note: See TracChangeset for help on using the changeset viewer.