- Timestamp:
- Jun 3, 2019, 5:36:43 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 4ae2364
- Parents:
- 8d70648
- Location:
- src/AST
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Decl.hpp
r8d70648 rf474e91 102 102 ptr<Expr> bitfieldWidth; 103 103 104 ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type, Init * init = nullptr, 105 Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C, Expr * bitWd = nullptr, 106 std::vector< ptr<Attribute> > && attrs = {}, Function::Specs fs = {}) 104 ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type, 105 Init * init = nullptr, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C, 106 Expr * bitWd = nullptr, std::vector< ptr<Attribute> > && attrs = {}, 107 Function::Specs fs = {} ) 107 108 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ), 108 109 init( init ), bitfieldWidth( bitWd ) {} -
src/AST/TypeEnvironment.cpp
r8d70648 rf474e91 46 46 } 47 47 48 void print( std::ostream & out, const OpenVarSet & open Vars, Indenter indent ) {48 void print( std::ostream & out, const OpenVarSet & open, Indenter indent ) { 49 49 out << indent; 50 50 bool first = true; 51 for ( const auto & i : open Vars) {51 for ( const auto & i : open ) { 52 52 if ( first ) { first = false; } else { out << ' '; } 53 53 out << i.first << "(" << i.second << ")"; … … 166 166 167 167 bool TypeEnvironment::combine( 168 const TypeEnvironment & o, OpenVarSet & open Vars, const SymbolTable & symtab ) {168 const TypeEnvironment & o, OpenVarSet & open, const SymbolTable & symtab ) { 169 169 // short-circuit easy cases 170 170 if ( o.empty() ) return true; … … 189 189 EqvClass & r = *rt; 190 190 // merge bindings 191 if ( ! mergeBound( r, c, open Vars, symtab ) ) return false;191 if ( ! mergeBound( r, c, open, symtab ) ) return false; 192 192 // merge previous unbound variables into this class, checking occurs if needed 193 193 if ( r.bound ) for ( const auto & u : c.vars ) { … … 204 204 } else if ( st != rt ) { 205 205 // bound, but not to the same class 206 if ( ! mergeClasses( rt, st, open Vars, symtab ) ) return false;206 if ( ! mergeClasses( rt, st, open, symtab ) ) return false; 207 207 } // ignore bound into the same class 208 208 } … … 216 216 } 217 217 218 void TypeEnvironment::extractOpenVars( OpenVarSet & open Vars) const {218 void TypeEnvironment::extractOpenVars( OpenVarSet & open ) const { 219 219 for ( const auto & clz : env ) { 220 220 for ( const auto & var : clz.vars ) { 221 open Vars[ var ] = clz.data;222 } 223 } 224 } 225 226 void TypeEnvironment::addActual( const TypeEnvironment & actualEnv, OpenVarSet & open Vars) {221 open[ var ] = clz.data; 222 } 223 } 224 } 225 226 void TypeEnvironment::addActual( const TypeEnvironment & actualEnv, OpenVarSet & open ) { 227 227 for ( const auto & clz : actualEnv ) { 228 228 EqvClass c = clz; 229 229 c.allowWidening = false; 230 230 for ( const auto & var : c.vars ) { 231 open Vars[ var ] = c.data;231 open[ var ] = c.data; 232 232 } 233 233 env.emplace_back( std::move(c) ); … … 268 268 bool TypeEnvironment::bindVar( 269 269 const TypeInstType * typeInst, const Type * bindTo, const TypeDecl::Data & data, 270 AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 271 WidenMode widenMode, const SymbolTable & symtab ) { 270 AssertionSet & need, AssertionSet & have, const OpenVarSet & open, WidenMode widen, 271 const SymbolTable & symtab 272 ) { 272 273 // remove references from bound type, so that type variables can only bind to value types 273 bindTo= bindTo->stripReferences();274 auto tyvar = open Vars.find( typeInst->name );275 assert( tyvar != open Vars.end() );276 if ( ! tyVarCompatible( tyvar->second, bindTo) ) return false;277 if ( occurs( bindTo, typeInst->name, *this ) ) return false;274 ptr<Type> target = bindTo->stripReferences(); 275 auto tyvar = open.find( typeInst->name ); 276 assert( tyvar != open.end() ); 277 if ( ! tyVarCompatible( tyvar->second, target ) ) return false; 278 if ( occurs( target, typeInst->name, *this ) ) return false; 278 279 279 280 auto it = internal_lookup( typeInst->name ); … … 282 283 // attempt to unify equivalence class type with type to bind to. 283 284 // equivalence class type has stripped qualifiers which must be restored 284 const Type * common = nullptr;285 ptr<Type> common; 285 286 ptr<Type> newType = it->bound; 286 287 newType.get_and_mutate()->qualifiers = typeInst->qualifiers; 287 288 if ( unifyInexact( 288 newType, bindTo, *this, need, have, openVars,289 widen Mode& WidenMode{ it->allowWidening, true }, symtab, common ) ) {289 newType, target, *this, need, have, open, 290 widen & WidenMode{ it->allowWidening, true }, symtab, common ) ) { 290 291 if ( common ) { 291 it->bound = common;292 it->bound = std::move(common); 292 293 clear_qualifiers( it->bound ); 293 294 } 294 295 } else return false; 295 296 } else { 296 it->bound = bindTo;297 it->bound = std::move(target); 297 298 clear_qualifiers( it->bound ); 298 it->allowWidening = widen Mode.widenFirst && widenMode.widenSecond;299 it->allowWidening = widen.first && widen.second; 299 300 } 300 301 } else { 301 302 env.emplace_back( 302 typeInst->name, bindTo, widenMode.widenFirst && widenMode.widenSecond, data );303 typeInst->name, target, widen.first && widen.second, data ); 303 304 } 304 305 return true; … … 307 308 bool TypeEnvironment::bindVarToVar( 308 309 const TypeInstType * var1, const TypeInstType * var2, TypeDecl::Data && data, 309 AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 310 WidenMode widenMode, const SymbolTable & symtab ) { 310 AssertionSet & need, AssertionSet & have, const OpenVarSet & open, 311 WidenMode widen, const SymbolTable & symtab 312 ) { 311 313 auto c1 = internal_lookup( var1->name ); 312 314 auto c2 = internal_lookup( var2->name ); … … 314 316 // exit early if variables already bound together 315 317 if ( c1 != env.end() && c1 == c2 ) { 316 c1->allowWidening &= widen Mode;318 c1->allowWidening &= widen; 317 319 return true; 318 320 } … … 327 329 type1 = c1->bound; 328 330 } 329 widen1 = widen Mode.widenFirst && c1->allowWidening;331 widen1 = widen.first && c1->allowWidening; 330 332 } 331 333 if ( c2 != env.end() ) { … … 334 336 type2 = c2->bound; 335 337 } 336 widen2 = widen Mode.widenSecond && c2->allowWidening;338 widen2 = widen.second && c2->allowWidening; 337 339 } 338 340 … … 341 343 ptr<Type> newType1{ type1 }, newType2{ type2 }; 342 344 WidenMode newWidenMode{ widen1, widen2 }; 343 const Type * common = nullptr;345 ptr<Type> common; 344 346 345 347 if ( unifyInexact( 346 newType1, newType2, *this, need, have, open Vars, newWidenMode, symtab, common ) ) {348 newType1, newType2, *this, need, have, open, newWidenMode, symtab, common ) ) { 347 349 c1->vars.insert( c2->vars.begin(), c2->vars.end() ); 348 350 c1->allowWidening = widen1 && widen2; 349 351 if ( common ) { 350 c1->bound = common;352 c1->bound = std::move(common); 351 353 clear_qualifiers( c1->bound ); 352 354 } … … 395 397 396 398 bool TypeEnvironment::mergeBound( 397 EqvClass & to, const EqvClass & from, OpenVarSet & open Vars, const SymbolTable & symtab ) {399 EqvClass & to, const EqvClass & from, OpenVarSet & open, const SymbolTable & symtab ) { 398 400 if ( from.bound ) { 399 401 if ( to.bound ) { 400 402 // attempt to unify bound types 401 403 ptr<Type> toType{ to.bound }, fromType{ from.bound }; 402 WidenMode widen Mode{ to.allowWidening, from.allowWidening };403 const Type * common = nullptr;404 WidenMode widen{ to.allowWidening, from.allowWidening }; 405 ptr<Type> common; 404 406 AssertionSet need, have; 405 407 406 408 if ( unifyInexact( 407 toType, fromType, *this, need, have, open Vars, widenMode, symtab, common ) ) {409 toType, fromType, *this, need, have, open, widen, symtab, common ) ) { 408 410 // unifies, set common type if necessary 409 411 if ( common ) { 410 to.bound = common;412 to.bound = std::move(common); 411 413 clear_qualifiers( to.bound ); 412 414 } … … 423 425 424 426 bool TypeEnvironment::mergeClasses( 425 ClassList::iterator to, ClassList::iterator from, OpenVarSet & openVars,426 const SymbolTable & symtab) {427 ClassList::iterator to, ClassList::iterator from, OpenVarSet & open, const SymbolTable & symtab 428 ) { 427 429 EqvClass & r = *to, & s = *from; 428 430 429 431 // ensure bounds match 430 if ( ! mergeBound( r, s, open Vars, symtab ) ) return false;432 if ( ! mergeBound( r, s, open, symtab ) ) return false; 431 433 432 434 // check safely bindable -
src/AST/TypeEnvironment.hpp
r8d70648 rf474e91 178 178 const TypeInstType * typeInst, const Type * bindTo, const TypeDecl::Data & data, 179 179 AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 180 ResolvExpr::WidenMode widen Mode, const SymbolTable & symtab );180 ResolvExpr::WidenMode widen, const SymbolTable & symtab ); 181 181 182 182 /// Binds the type classes represented by `var1` and `var2` together; will add one or both … … 185 185 const TypeInstType * var1, const TypeInstType * var2, TypeDecl::Data && data, 186 186 AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 187 ResolvExpr::WidenMode widen Mode, const SymbolTable & symtab );187 ResolvExpr::WidenMode widen, const SymbolTable & symtab ); 188 188 189 189 /// Disallows widening for all bindings in the environment -
src/AST/porting.md
r8d70648 rf474e91 291 291 * moved to be helper function in `TypeEnvironment.cpp` (its only use) 292 292 293 `WidenMode` 294 * changed `widenFirst`, `widenSecond` => `first`, `second` 295 * changed `WidenMode widenMode` => `WidenMode widen` 296 293 297 [1] https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Type-Attributes.html#Type-Attributes 294 298
Note:
See TracChangeset
for help on using the changeset viewer.