Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/ScrubTyVars.h

    rc6b4432 rea2ed3a  
    1919
    2020#include "AST/Fwd.hpp"        // for Node
     21#include "Common/PassVisitor.h"
    2122#include "GenPoly.h"          // for TyVarMap, isPolyType, isDynType
     23#include "SynTree/Mutator.h"  // for Mutator
     24#include "SynTree/Type.h"     // for Type (ptr only), PointerType (ptr only)
     25
     26class AlignofExpr;
     27class Expression;
     28class SizeofExpr;
    2229
    2330namespace GenPoly {
     31        struct ScrubTyVars : public WithVisitorRef<ScrubTyVars>, public WithShortCircuiting, public WithGuards {
     32                /// Whether to scrub all type variables from the provided map, dynamic type variables from the provided map, or all type variables
     33                enum ScrubMode { FromMap, DynamicFromMap, All };
     34
     35                ScrubTyVars() : tyVars(nullptr), mode( All ) {}
     36
     37                ScrubTyVars( const TyVarMap &tyVars, ScrubMode mode = FromMap ): tyVars( &tyVars ), mode( mode ) {}
     38
     39        public:
     40                /// For all polymorphic types with type variables in `tyVars`, replaces generic types, dtypes, and ftypes with the appropriate void type,
     41                /// and sizeof/alignof expressions with the proper variable
     42                template< typename SynTreeClass >
     43                static SynTreeClass *scrub( SynTreeClass *target, const TyVarMap &tyVars );
     44
     45                /// For all dynamic-layout types with type variables in `tyVars`, replaces generic types, dtypes, and ftypes with the appropriate void type,
     46                /// and sizeof/alignof expressions with the proper variable
     47                template< typename SynTreeClass >
     48                static SynTreeClass *scrubDynamic( SynTreeClass *target, const TyVarMap &tyVars );
     49
     50                /// For all polymorphic types, replaces generic types, dtypes, and ftypes with the appropriate void type,
     51                /// and sizeof/alignof expressions with the proper variable
     52                template< typename SynTreeClass >
     53                static SynTreeClass *scrubAll( SynTreeClass *target );
     54
     55                /// determine if children should be visited based on whether base type should be scrubbed.
     56                void primeBaseScrub( Type * );
     57
     58                void premutate( TypeInstType * ) { visit_children = false; }
     59                void premutate( StructInstType * ) { visit_children = false; }
     60                void premutate( UnionInstType * ) { visit_children = false; }
     61                void premutate( SizeofExpr * szeof ) { primeBaseScrub( szeof->type ); }
     62                void premutate( AlignofExpr * algnof ) { primeBaseScrub( algnof->type ); }
     63                void premutate( PointerType * pointer ) { primeBaseScrub( pointer->base ); }
     64
     65                Type * postmutate( TypeInstType * typeInst );
     66                Type * postmutate( StructInstType * structInst );
     67                Type * postmutate( UnionInstType * unionInst );
     68                Expression * postmutate( SizeofExpr * szeof );
     69                Expression * postmutate( AlignofExpr * algnof );
     70                Type * postmutate( PointerType * pointer );
     71
     72          private:
     73                /// Returns the type if it should be scrubbed, NULL otherwise.
     74                Type* shouldScrub( Type *ty ) {
     75                        switch ( mode ) {
     76                        case FromMap: return isPolyType( ty, *tyVars );
     77                        case DynamicFromMap: return isDynType( ty, *tyVars );
     78                        case All: return isPolyType( ty );
     79                        }
     80                        assert(false); return nullptr; // unreachable
     81                        // return dynamicOnly ? isDynType( ty, tyVars ) : isPolyType( ty, tyVars );
     82                }
     83
     84                /// Mutates (possibly generic) aggregate types appropriately
     85                Type* mutateAggregateType( Type *ty );
     86
     87                const TyVarMap *tyVars;  ///< Type variables to scrub
     88                ScrubMode mode;          ///< which type variables to scrub? [FromMap]
     89
     90                Type * dynType = nullptr; ///< result of shouldScrub
     91        };
     92
     93        template< typename SynTreeClass >
     94        SynTreeClass * ScrubTyVars::scrub( SynTreeClass *target, const TyVarMap &tyVars ) {
     95                PassVisitor<ScrubTyVars> scrubber( tyVars );
     96                return static_cast< SynTreeClass * >( target->acceptMutator( scrubber ) );
     97        }
     98
     99        template< typename SynTreeClass >
     100        SynTreeClass * ScrubTyVars::scrubDynamic( SynTreeClass *target, const TyVarMap &tyVars ) {
     101                PassVisitor<ScrubTyVars> scrubber( tyVars, ScrubTyVars::DynamicFromMap );
     102                return static_cast< SynTreeClass * >( target->acceptMutator( scrubber ) );
     103        }
     104
     105        template< typename SynTreeClass >
     106        SynTreeClass * ScrubTyVars::scrubAll( SynTreeClass *target ) {
     107                PassVisitor<ScrubTyVars> scrubber;
     108                return static_cast< SynTreeClass * >( target->acceptMutator( scrubber ) );
     109        }
    24110
    25111// ScrubMode and scrubTypeVarsBase are internal.
Note: See TracChangeset for help on using the changeset viewer.