source: src/GenPoly/ScrubTyVars.cc @ fa5e1aa5

Last change on this file since fa5e1aa5 was 2f61765, checked in by Andrew Beach <ajbeach@…>, 22 months ago

Fixed a clang warning and cleaned up the rest of the function.

  • Property mode set to 100644
File size: 7.9 KB
RevLine 
[51587aa]1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
[2c57025]7// ScrubTyVars.cc --
[51587aa]8//
9// Author           : Richard C. Bilson
10// Created On       : Mon May 18 07:44:20 2015
[3606fe4]11// Last Modified By : Andrew Beach
[ea2ed3a]12// Last Modified On : Wed Dec  7 17:01:00 2022
13// Update Count     : 6
[51587aa]14//
[01aeade]15
[08fc48f]16#include <utility>                      // for pair
[db0b3ce]17
[3606fe4]18#include "AST/Pass.hpp"
[08fc48f]19#include "GenPoly.h"                    // for mangleType, TyVarMap, alignof...
20#include "GenPoly/ErasableScopedMap.h"  // for ErasableScopedMap<>::const_it...
[51b7345]21#include "ScrubTyVars.h"
[0026d67]22#include "SymTab/Mangler.h"             // for mangleType
[08fc48f]23#include "SynTree/Declaration.h"        // for TypeDecl, TypeDecl::Data, Typ...
24#include "SynTree/Expression.h"         // for Expression (ptr only), NameExpr
25#include "SynTree/Mutator.h"            // for Mutator
26#include "SynTree/Type.h"               // for PointerType, TypeInstType, Type
[51b7345]27
28namespace GenPoly {
[b8a4f47]29        Type * ScrubTyVars::postmutate( TypeInstType * typeInst ) {
[5a3ac84]30                if ( ! tyVars ) {
31                        if ( typeInst->get_isFtype() ) {
32                                delete typeInst;
33                                return new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
34                        } else {
[b8a4f47]35                                PointerType * ret = new PointerType( Type::Qualifiers(), new VoidType( typeInst->get_qualifiers() ) );
[5a3ac84]36                                delete typeInst;
37                                return ret;
38                        }
39                }
40
[b8a4f47]41                TyVarMap::const_iterator tyVar = tyVars->find( typeInst->name );
[5a3ac84]42                if ( tyVar != tyVars->end() ) {
[2c57025]43                        switch ( tyVar->second.kind ) {
[01aeade]44                          case TypeDecl::Dtype:
[8f60f0b]45                          case TypeDecl::Ttype:
[01aeade]46                                {
[b8a4f47]47                                        PointerType * ret = new PointerType( Type::Qualifiers(), new VoidType( typeInst->get_qualifiers() ) );
[01aeade]48                                        delete typeInst;
49                                        return ret;
50                                }
51                          case TypeDecl::Ftype:
52                                delete typeInst;
53                                return new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
[d978ada]54                          default:
55                                assertf(false, "Unhandled tyvar kind: %d", tyVar->second.kind);
[01aeade]56                        } // switch
57                } // if
58                return typeInst;
[a08ba92]59        }
[51b7345]60
[b8a4f47]61        Type * ScrubTyVars::mutateAggregateType( Type * ty ) {
[3bb195cb]62                if ( shouldScrub( ty ) ) {
[b8a4f47]63                        PointerType * ret = new PointerType( Type::Qualifiers(), new VoidType( ty->get_qualifiers() ) );
[b18b0b5]64                        delete ty;
65                        return ret;
66                }
67                return ty;
68        }
[2c57025]69
[b8a4f47]70        Type * ScrubTyVars::postmutate( StructInstType * structInst ) {
[b18b0b5]71                return mutateAggregateType( structInst );
72        }
73
[b8a4f47]74        Type * ScrubTyVars::postmutate( UnionInstType * unionInst ) {
[b18b0b5]75                return mutateAggregateType( unionInst );
76        }
77
[b8a4f47]78        void ScrubTyVars::primeBaseScrub( Type * type ) {
79                // need to determine whether type needs to be scrubbed to determine whether
80                // automatic recursion is necessary
81                if ( Type * t = shouldScrub( type ) ) {
82                        visit_children = false;
83                        GuardValue( dynType );
84                        dynType = t;
85                }
86        }
87
88        Expression * ScrubTyVars::postmutate( SizeofExpr * szeof ) {
[db0b3ce]89                // sizeof( T ) => _sizeof_T parameter, which is the size of T
[b8a4f47]90                if ( dynType ) {
[3bb195cb]91                        Expression *expr = new NameExpr( sizeofName( mangleType( dynType ) ) );
[01aeade]92                        return expr;
93                } // if
[b8a4f47]94                return szeof;
[a08ba92]95        }
[51b7345]96
[b8a4f47]97        Expression * ScrubTyVars::postmutate( AlignofExpr * algnof ) {
[db0b3ce]98                // alignof( T ) => _alignof_T parameter, which is the alignment of T
[b8a4f47]99                if ( dynType ) {
[3bb195cb]100                        Expression *expr = new NameExpr( alignofName( mangleType( dynType ) ) );
[db0b3ce]101                        return expr;
102                } // if
[b8a4f47]103                return algnof;
[db0b3ce]104        }
105
[b8a4f47]106        Type * ScrubTyVars::postmutate( PointerType * pointer ) {
107                if ( dynType ) {
108                        Type * ret = dynType->acceptMutator( *visitor );
[6f95000]109                        ret->get_qualifiers() |= pointer->get_qualifiers();
[b8a4f47]110                        pointer->base = nullptr;
[6d160d7]111                        delete pointer;
112                        return ret;
113                }
[b8a4f47]114                return pointer;
[a08ba92]115        }
[3606fe4]116
117namespace {
118
119struct ScrubTypeVars :
120        public ast::WithGuards,
121        public ast::WithShortCircuiting,
122        public ast::WithVisitorRef<ScrubTypeVars> {
123
[c8837e5]124        ScrubTypeVars( ScrubMode m, TypeVarMap const * tv ) :
[3606fe4]125                        mode ( m ), typeVars( tv ) {}
126
127        void previsit( ast::TypeInstType const * ) { visit_children = false; }
128        void previsit( ast::StructInstType const * ) { visit_children = false; }
129        void previsit( ast::UnionInstType const * ) { visit_children = false; }
130        void previsit( ast::SizeofExpr const * expr ) { primeBaseScrub( expr->type ); }
131        void previsit( ast::AlignofExpr const * expr ) { primeBaseScrub( expr->type ); }
132        void previsit( ast::PointerType const * type ) { primeBaseScrub( type->base ); }
133
134        ast::Type const * postvisit( ast::TypeInstType const * type );
135        ast::Type const * postvisit( ast::StructInstType const * type );
136        ast::Type const * postvisit( ast::UnionInstType const * type );
137        ast::Expr const * postvisit( ast::SizeofExpr const * expr );
138        ast::Expr const * postvisit( ast::AlignofExpr const * expr );
139        ast::Type const * postvisit( ast::PointerType const * type );
140
141private:
142        ScrubMode const mode;
143        /// Type varriables to scrub.
[c8837e5]144        TypeVarMap const * const typeVars;
[3606fe4]145        /// Value cached by primeBaseScrub.
146        ast::Type const * dynType = nullptr;
147
148        /// Returns the type if it should be scrubbed, nullptr otherwise.
149        ast::Type const * shouldScrub( ast::Type const * type ) {
150                switch ( mode ) {
151                case ScrubMode::FromMap:
152                        return isPolyType( type, *typeVars );
153                case ScrubMode::DynamicFromMap:
154                        return isDynType( type, *typeVars );
155                case ScrubMode::All:
156                        return isPolyType( type );
157                default:
158                        assertf( false, "Invalid ScrubMode in shouldScrub." );
159                        throw;
160                }
161        }
162
163        void primeBaseScrub( ast::Type const * type ) {
164                // Need to determine whether type needs to be scrubbed to
165                // determine whether automatic recursion is necessary.
166                if ( ast::Type const * t = shouldScrub( type ) ) {
167                        visit_children = false;
168                        GuardValue( dynType ) = t;
169                }
170        }
171
172        ast::Type const * postvisitAggregateType(
173                        ast::BaseInstType const * type ) {
174                if ( !shouldScrub( type ) ) return type;
175                return new ast::PointerType( new ast::VoidType( type->qualifiers ) );
176        }
177};
178
179ast::Type const * ScrubTypeVars::postvisit( ast::TypeInstType const * type ) {
[2f61765]180        ast::TypeDecl::Kind kind;
[3606fe4]181        // This implies that mode == ScrubMode::All.
182        if ( !typeVars ) {
[2f61765]183                kind = type->kind;
184        } else {
185                // Otherwise, only scrub the type var if it is in map.
186                auto typeVar = typeVars->find( *type );
187                if ( typeVar == typeVars->end() ) {
188                        return type;
[3606fe4]189                }
[2f61765]190                kind = typeVar->second.kind;
[3606fe4]191        }
192
[2f61765]193        switch ( kind ) {
194        case ast::TypeDecl::Dtype:
195        case ast::TypeDecl::Ttype:
[3606fe4]196                return new ast::PointerType(
197                        new ast::VoidType( type->qualifiers ) );
[2f61765]198        case ast::TypeDecl::Ftype:
[3606fe4]199                return new ast::PointerType(
200                        new ast::FunctionType( ast::VariableArgs ) );
201        default:
[2f61765]202                assertf( false, "Unhandled type variable kind: %d", kind );
[3606fe4]203                throw; // Just in case the assert is removed, stop here.
204        }
205}
206
207ast::Type const * ScrubTypeVars::postvisit( ast::StructInstType const * type ) {
208        return postvisitAggregateType( type );
209}
210
211ast::Type const * ScrubTypeVars::postvisit( ast::UnionInstType const * type ) {
212        return postvisitAggregateType( type );
213}
214
215ast::Expr const * ScrubTypeVars::postvisit( ast::SizeofExpr const * expr ) {
216        // sizeof( T ) becomes the _sizeof_T parameter.
217        if ( dynType ) {
218                return new ast::NameExpr( expr->location,
[0026d67]219                        sizeofName( Mangle::mangleType( dynType ) ) );
[3606fe4]220        } else {
221                return expr;
222        }
223}
224
225ast::Expr const * ScrubTypeVars::postvisit( ast::AlignofExpr const * expr ) {
226        // alignof( T ) becomes the _alignof_T parameter.
227        if ( dynType ) {
228                return new ast::NameExpr( expr->location,
[0026d67]229                        alignofName( Mangle::mangleType( dynType ) ) );
[3606fe4]230        } else {
231                return expr;
232        }
233}
234
235ast::Type const * ScrubTypeVars::postvisit( ast::PointerType const * type ) {
236        if ( dynType ) {
237                ast::Type * ret = ast::mutate( dynType->accept( *visitor ) );
238                ret->qualifiers |= type->qualifiers;
239                return ret;
240        } else {
241                return type;
242        }
243}
244
[ea2ed3a]245} // namespace
246
[3606fe4]247const ast::Node * scrubTypeVarsBase(
[ea2ed3a]248                const ast::Node * node, const TypeVarMap * typeVars, ScrubMode mode ) {
[3606fe4]249        if ( ScrubMode::All == mode ) {
250                assert( nullptr == typeVars );
251        } else {
252                assert( nullptr != typeVars );
253        }
254        ast::Pass<ScrubTypeVars> visitor( mode, typeVars );
[ea2ed3a]255        return node->accept( visitor );
[3606fe4]256}
257
[51b7345]258} // namespace GenPoly
[01aeade]259
[51587aa]260// Local Variables: //
261// tab-width: 4 //
262// mode: c++ //
263// compile-command: "make install" //
264// End: //
Note: See TracBrowser for help on using the repository browser.