Changes in src/GenPoly/ScrubTyVars.cc [3606fe4:d978ada]
- File:
-
- 1 edited
-
src/GenPoly/ScrubTyVars.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/ScrubTyVars.cc
r3606fe4 rd978ada 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Aug 19 16:10:00 202213 // Update Count : 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 16 15:44:27 2017 13 // Update Count : 3 14 14 // 15 15 16 16 #include <utility> // for pair 17 17 18 #include "AST/Pass.hpp"19 18 #include "GenPoly.h" // for mangleType, TyVarMap, alignof... 20 19 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_it... 21 20 #include "ScrubTyVars.h" 22 #include "SymTab/Mangler.h" // for mangle, typeMode23 21 #include "SynTree/Declaration.h" // for TypeDecl, TypeDecl::Data, Typ... 24 22 #include "SynTree/Expression.h" // for Expression (ptr only), NameExpr … … 114 112 return pointer; 115 113 } 116 117 namespace {118 119 enum class ScrubMode {120 FromMap,121 DynamicFromMap,122 All,123 };124 125 struct ScrubTypeVars :126 public ast::WithGuards,127 public ast::WithShortCircuiting,128 public ast::WithVisitorRef<ScrubTypeVars> {129 130 ScrubTypeVars( ScrubMode m, TyVarMap const * tv ) :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 147 private:148 ScrubMode const mode;149 /// Type varriables to scrub.150 TyVarMap const * const typeVars;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 to171 // 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 185 ast::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 197 auto typeVar = typeVars->find( type->name );198 if ( typeVar == typeVars->end() ) {199 return type;200 }201 202 switch ( typeVar->second.kind ) {203 case ast::TypeDecl::Dtype:204 case ast::TypeDecl::Ttype:205 return new ast::PointerType(206 new ast::VoidType( type->qualifiers ) );207 case ast::TypeDecl::Ftype: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 217 ast::Type const * ScrubTypeVars::postvisit( ast::StructInstType const * type ) {218 return postvisitAggregateType( type );219 }220 221 ast::Type const * ScrubTypeVars::postvisit( ast::UnionInstType const * type ) {222 return postvisitAggregateType( type );223 }224 225 ast::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,229 sizeofName( Mangle::mangle( dynType, Mangle::typeMode() ) ) );230 } else {231 return expr;232 }233 }234 235 ast::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,239 alignofName( Mangle::mangle( dynType, Mangle::typeMode() ) ) );240 } else {241 return expr;242 }243 }244 245 ast::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 255 const ast::Node * scrubTypeVarsBase(256 const ast::Node * target,257 ScrubMode mode, const TyVarMap * typeVars ) {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 } // namespace268 269 template<>270 ast::Node const * scrubAllTypeVars<ast::Node>( const ast::Node * target ) {271 return scrubTypeVarsBase( target, ScrubMode::All, nullptr );272 }273 274 114 } // namespace GenPoly 275 115
Note:
See TracChangeset
for help on using the changeset viewer.