Changeset 23a08aa0 for src/GenPoly/ScrubTyVars.cc
- Timestamp:
- Sep 19, 2022, 8:11:02 PM (3 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation
- Children:
- aa9f215
- Parents:
- ebf8ca5 (diff), ae1d151 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/ScrubTyVars.cc
rebf8ca5 r23a08aa0 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Mar 16 15:44:27 201713 // Update Count : 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 19 16:10:00 2022 13 // Update Count : 4 14 14 // 15 15 16 16 #include <utility> // for pair 17 17 18 #include "AST/Pass.hpp" 18 19 #include "GenPoly.h" // for mangleType, TyVarMap, alignof... 19 20 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_it... 20 21 #include "ScrubTyVars.h" 22 #include "SymTab/Mangler.h" // for mangle, typeMode 21 23 #include "SynTree/Declaration.h" // for TypeDecl, TypeDecl::Data, Typ... 22 24 #include "SynTree/Expression.h" // for Expression (ptr only), NameExpr … … 112 114 return pointer; 113 115 } 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 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 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 } // namespace 268 269 template<> 270 ast::Node const * scrubAllTypeVars<ast::Node>( const ast::Node * target ) { 271 return scrubTypeVarsBase( target, ScrubMode::All, nullptr ); 272 } 273 114 274 } // namespace GenPoly 115 275
Note:
See TracChangeset
for help on using the changeset viewer.