source: src/GenPoly/ScrubTyVars.cc@ 994028dc

ADT ast-experimental
Last change on this file since 994028dc was 0026d67, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Replaced Mangle::typeMode() with Mangle::mangleType(...), as it is how typeMode() was always used and it is shorter. Various other clean-up in the Mangler files.

  • Property mode set to 100644
File size: 8.6 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
[c8837e5]12// Last Modified On : Fri Oct 7 15:42:00 2022
13// Update Count : 5
[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...
[51b73452]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
[51b73452]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 }
[51b73452]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 }
[51b73452]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
119enum class ScrubMode {
120 FromMap,
121 DynamicFromMap,
122 All,
123};
124
125struct ScrubTypeVars :
126 public ast::WithGuards,
127 public ast::WithShortCircuiting,
128 public ast::WithVisitorRef<ScrubTypeVars> {
129
[c8837e5]130 ScrubTypeVars( ScrubMode m, TypeVarMap const * tv ) :
[3606fe4]131 mode ( m ), typeVars( tv ) {}
132
133 void previsit( ast::TypeInstType const * ) { visit_children = false; }
134 void previsit( ast::StructInstType const * ) { visit_children = false; }
135 void previsit( ast::UnionInstType const * ) { visit_children = false; }
136 void previsit( ast::SizeofExpr const * expr ) { primeBaseScrub( expr->type ); }
137 void previsit( ast::AlignofExpr const * expr ) { primeBaseScrub( expr->type ); }
138 void previsit( ast::PointerType const * type ) { primeBaseScrub( type->base ); }
139
140 ast::Type const * postvisit( ast::TypeInstType const * type );
141 ast::Type const * postvisit( ast::StructInstType const * type );
142 ast::Type const * postvisit( ast::UnionInstType const * type );
143 ast::Expr const * postvisit( ast::SizeofExpr const * expr );
144 ast::Expr const * postvisit( ast::AlignofExpr const * expr );
145 ast::Type const * postvisit( ast::PointerType const * type );
146
147private:
148 ScrubMode const mode;
149 /// Type varriables to scrub.
[c8837e5]150 TypeVarMap const * const typeVars;
[3606fe4]151 /// Value cached by primeBaseScrub.
152 ast::Type const * dynType = nullptr;
153
154 /// Returns the type if it should be scrubbed, nullptr otherwise.
155 ast::Type const * shouldScrub( ast::Type const * type ) {
156 switch ( mode ) {
157 case ScrubMode::FromMap:
158 return isPolyType( type, *typeVars );
159 case ScrubMode::DynamicFromMap:
160 return isDynType( type, *typeVars );
161 case ScrubMode::All:
162 return isPolyType( type );
163 default:
164 assertf( false, "Invalid ScrubMode in shouldScrub." );
165 throw;
166 }
167 }
168
169 void primeBaseScrub( ast::Type const * type ) {
170 // Need to determine whether type needs to be scrubbed to
171 // determine whether automatic recursion is necessary.
172 if ( ast::Type const * t = shouldScrub( type ) ) {
173 visit_children = false;
174 GuardValue( dynType ) = t;
175 }
176 }
177
178 ast::Type const * postvisitAggregateType(
179 ast::BaseInstType const * type ) {
180 if ( !shouldScrub( type ) ) return type;
181 return new ast::PointerType( new ast::VoidType( type->qualifiers ) );
182 }
183};
184
185ast::Type const * ScrubTypeVars::postvisit( ast::TypeInstType const * type ) {
186 // This implies that mode == ScrubMode::All.
187 if ( !typeVars ) {
188 if ( ast::TypeDecl::Ftype == type->kind ) {
189 return new ast::PointerType(
190 new ast::FunctionType( ast::FixedArgs ) );
191 } else {
192 return new ast::PointerType(
193 new ast::VoidType( type->qualifiers ) );
194 }
195 }
196
[63d1ebe]197 auto typeVar = typeVars->find( *type );
[3606fe4]198 if ( typeVar == typeVars->end() ) {
199 return type;
200 }
201
202 switch ( typeVar->second.kind ) {
[0bd46fd]203 case ::TypeDecl::Dtype:
204 case ::TypeDecl::Ttype:
[3606fe4]205 return new ast::PointerType(
206 new ast::VoidType( type->qualifiers ) );
[0bd46fd]207 case ::TypeDecl::Ftype:
[3606fe4]208 return new ast::PointerType(
209 new ast::FunctionType( ast::VariableArgs ) );
210 default:
211 assertf( false,
212 "Unhandled type variable kind: %d", typeVar->second.kind );
213 throw; // Just in case the assert is removed, stop here.
214 }
215}
216
217ast::Type const * ScrubTypeVars::postvisit( ast::StructInstType const * type ) {
218 return postvisitAggregateType( type );
219}
220
221ast::Type const * ScrubTypeVars::postvisit( ast::UnionInstType const * type ) {
222 return postvisitAggregateType( type );
223}
224
225ast::Expr const * ScrubTypeVars::postvisit( ast::SizeofExpr const * expr ) {
226 // sizeof( T ) becomes the _sizeof_T parameter.
227 if ( dynType ) {
228 return new ast::NameExpr( expr->location,
[0026d67]229 sizeofName( Mangle::mangleType( dynType ) ) );
[3606fe4]230 } else {
231 return expr;
232 }
233}
234
235ast::Expr const * ScrubTypeVars::postvisit( ast::AlignofExpr const * expr ) {
236 // alignof( T ) becomes the _alignof_T parameter.
237 if ( dynType ) {
238 return new ast::NameExpr( expr->location,
[0026d67]239 alignofName( Mangle::mangleType( dynType ) ) );
[3606fe4]240 } else {
241 return expr;
242 }
243}
244
245ast::Type const * ScrubTypeVars::postvisit( ast::PointerType const * type ) {
246 if ( dynType ) {
247 ast::Type * ret = ast::mutate( dynType->accept( *visitor ) );
248 ret->qualifiers |= type->qualifiers;
249 return ret;
250 } else {
251 return type;
252 }
253}
254
255const ast::Node * scrubTypeVarsBase(
256 const ast::Node * target,
[c8837e5]257 ScrubMode mode, const TypeVarMap * typeVars ) {
[3606fe4]258 if ( ScrubMode::All == mode ) {
259 assert( nullptr == typeVars );
260 } else {
261 assert( nullptr != typeVars );
262 }
263 ast::Pass<ScrubTypeVars> visitor( mode, typeVars );
264 return target->accept( visitor );
265}
266
267} // namespace
268
[c8837e5]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}
280
[3606fe4]281template<>
282ast::Node const * scrubAllTypeVars<ast::Node>( const ast::Node * target ) {
283 return scrubTypeVarsBase( target, ScrubMode::All, nullptr );
284}
285
[51b73452]286} // namespace GenPoly
[01aeade]287
[51587aa]288// Local Variables: //
289// tab-width: 4 //
290// mode: c++ //
291// compile-command: "make install" //
292// End: //
Note: See TracBrowser for help on using the repository browser.