- Timestamp:
- Dec 14, 2022, 12:23:42 PM (3 years ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 441a6a7
- Parents:
- 7d9598d8 (diff), d8bdf13 (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. - Location:
- src
- Files:
-
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r7d9598d8 r2dcd80a 1764 1764 { old->linkage.val }, 1765 1765 GET_ACCEPT_1(base, Type), 1766 old->hide == EnumDecl::EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible, 1766 1767 old->enumValues 1767 1768 ); -
src/AST/Decl.cpp
r7d9598d8 r2dcd80a 125 125 } 126 126 127 std::ostream & operator<< ( std::ostream & out, const TypeD ecl::Data & data ) {127 std::ostream & operator<< ( std::ostream & out, const TypeData & data ) { 128 128 return out << data.kind << ", " << data.isComplete; 129 129 } -
src/AST/Decl.hpp
r7d9598d8 r2dcd80a 10 10 // Created On : Thu May 9 10:00:00 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu May 5 12:09:00 202213 // Update Count : 3 312 // Last Modified On : Thu Nov 24 9:44:00 2022 13 // Update Count : 34 14 14 // 15 15 … … 191 191 ptr<Type> init; 192 192 193 /// Data extracted from a type decl194 struct Data {195 Kind kind;196 bool isComplete;197 198 Data() : kind( NUMBER_OF_KINDS ), isComplete( false ) {}199 Data( const TypeDecl * d ) : kind( d->kind ), isComplete( d->sized ) {}200 Data( Kind k, bool c ) : kind( k ), isComplete( c ) {}201 Data( const Data & d1, const Data & d2 )202 : kind( d1.kind ), isComplete( d1.isComplete || d2.isComplete ) {}203 204 bool operator==( const Data & o ) const { return kind == o.kind && isComplete == o.isComplete; }205 bool operator!=( const Data & o ) const { return !(*this == o); }206 };207 208 193 TypeDecl( 209 194 const CodeLocation & loc, const std::string & name, Storage::Classes storage, … … 225 210 }; 226 211 227 std::ostream & operator<< ( std::ostream &, const TypeDecl::Data & ); 212 /// Data extracted from a TypeDecl. 213 struct TypeData { 214 TypeDecl::Kind kind; 215 bool isComplete; 216 217 TypeData() : kind( TypeDecl::NUMBER_OF_KINDS ), isComplete( false ) {} 218 TypeData( const TypeDecl * d ) : kind( d->kind ), isComplete( d->sized ) {} 219 TypeData( TypeDecl::Kind k, bool c ) : kind( k ), isComplete( c ) {} 220 TypeData( const TypeData & d1, const TypeData & d2 ) 221 : kind( d1.kind ), isComplete( d1.isComplete || d2.isComplete ) {} 222 223 bool operator==( const TypeData & o ) const { return kind == o.kind && isComplete == o.isComplete; } 224 bool operator!=( const TypeData & o ) const { return !(*this == o); } 225 }; 226 227 std::ostream & operator<< ( std::ostream &, const TypeData & ); 228 228 229 229 /// C-style typedef `typedef Foo Bar` … … 315 315 // enum (type_optional) Name {...} 316 316 ptr<Type> base; // if isTyped == true && base.get() == nullptr, it is a "void" type enum 317 318 EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false, 317 enum class EnumHiding { Visible, Hide } hide; 318 319 EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false, 319 320 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall, 320 Type const * base = nullptr, 321 Type const * base = nullptr, EnumHiding hide = EnumHiding::Hide, 321 322 std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() ) 322 : AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), base(base), enumValues(enumValues) {}323 : AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), base(base), hide(hide), enumValues(enumValues) {} 323 324 324 325 /// gets the integer value for this enumerator, returning true iff value found -
src/AST/Pass.impl.hpp
r7d9598d8 r2dcd80a 686 686 687 687 if ( __visit_children() ) { 688 // unlike structs, traits, and unions, enums inject their members into the global scope 689 maybe_accept( node, &EnumDecl::base ); 690 maybe_accept( node, &EnumDecl::params ); 691 maybe_accept( node, &EnumDecl::members ); 692 maybe_accept( node, &EnumDecl::attributes ); 688 if ( node->hide == ast::EnumDecl::EnumHiding::Hide ) { 689 guard_symtab guard { *this }; 690 maybe_accept( node, &EnumDecl::base ); 691 maybe_accept( node, &EnumDecl::params ); 692 maybe_accept( node, &EnumDecl::members ); 693 maybe_accept( node, &EnumDecl::attributes ); 694 } else { 695 maybe_accept( node, &EnumDecl::base ); 696 maybe_accept( node, &EnumDecl::params ); 697 maybe_accept( node, &EnumDecl::members ); 698 maybe_accept( node, &EnumDecl::attributes ); 699 } 693 700 } 694 701 -
src/AST/Type.cpp
r7d9598d8 r2dcd80a 10 10 // Created On : Mon May 13 15:00:00 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Jul 23 14:16:00 202013 // Update Count : 512 // Last Modified On : Thu Nov 24 9:49:00 2022 13 // Update Count : 6 14 14 // 15 15 … … 147 147 // --- TypeInstType 148 148 149 TypeInstType::TypeInstType( const TypeEnvKey & key ) 150 : BaseInstType(key.base->name), base(key.base), kind(key.base->kind), formal_usage(key.formal_usage), expr_id(key.expr_id) {} 151 149 152 bool TypeInstType::operator==( const TypeInstType & other ) const { 150 153 return base == other.base … … 164 167 bool TypeInstType::isComplete() const { return base->sized; } 165 168 166 std::string Type InstType::TypeEnvKey::typeString() const {169 std::string TypeEnvKey::typeString() const { 167 170 return std::string("_") + std::to_string(formal_usage) 168 171 + "_" + std::to_string(expr_id) + "_" + base->name; 169 172 } 170 173 171 bool Type InstType::TypeEnvKey::operator==(172 const Type InstType::TypeEnvKey & other ) const {174 bool TypeEnvKey::operator==( 175 const TypeEnvKey & other ) const { 173 176 return base == other.base 174 177 && formal_usage == other.formal_usage … … 176 179 } 177 180 178 bool Type InstType::TypeEnvKey::operator<(179 const Type InstType::TypeEnvKey & other ) const {181 bool TypeEnvKey::operator<( 182 const TypeEnvKey & other ) const { 180 183 // TypeEnvKey ordering is an arbitrary total ordering. 181 184 // It doesn't mean anything but allows for a sorting. -
src/AST/Type.hpp
r7d9598d8 r2dcd80a 10 10 // Created On : Thu May 9 10:00:00 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jul 14 15:54:00 202113 // Update Count : 712 // Last Modified On : Thu Nov 24 9:47:00 2022 13 // Update Count : 8 14 14 // 15 15 … … 390 390 }; 391 391 392 struct TypeEnvKey; 393 392 394 /// instance of named type alias (typedef or variable) 393 395 class TypeInstType final : public BaseInstType { … … 401 403 int expr_id = 0; 402 404 403 // compact representation used for map lookups.404 struct TypeEnvKey {405 const TypeDecl * base = nullptr;406 int formal_usage = 0;407 int expr_id = 0;408 409 TypeEnvKey() = default;410 TypeEnvKey(const TypeDecl * base, int formal_usage = 0, int expr_id = 0)411 : base(base), formal_usage(formal_usage), expr_id(expr_id) {}412 TypeEnvKey(const TypeInstType & inst)413 : base(inst.base), formal_usage(inst.formal_usage), expr_id(inst.expr_id) {}414 std::string typeString() const;415 bool operator==(const TypeEnvKey & other) const;416 bool operator<(const TypeEnvKey & other) const;417 };418 419 405 bool operator==(const TypeInstType & other) const; 420 406 … … 433 419 TypeInstType( const TypeInstType & o ) = default; 434 420 435 TypeInstType( const TypeEnvKey & key ) 436 : BaseInstType(key.base->name), base(key.base), kind(key.base->kind), formal_usage(key.formal_usage), expr_id(key.expr_id) {} 421 TypeInstType( const TypeEnvKey & key ); 437 422 438 423 /// sets `base`, updating `kind` correctly … … 453 438 TypeInstType * clone() const override { return new TypeInstType{ *this }; } 454 439 MUTATE_FRIEND 440 }; 441 442 /// Compact representation of TypeInstType used for map lookups. 443 struct TypeEnvKey { 444 const TypeDecl * base = nullptr; 445 int formal_usage = 0; 446 int expr_id = 0; 447 448 TypeEnvKey() = default; 449 TypeEnvKey(const TypeDecl * base, int formal_usage = 0, int expr_id = 0) 450 : base(base), formal_usage(formal_usage), expr_id(expr_id) {} 451 TypeEnvKey(const TypeInstType & inst) 452 : base(inst.base), formal_usage(inst.formal_usage), expr_id(inst.expr_id) {} 453 std::string typeString() const; 454 bool operator==(const TypeEnvKey & other) const; 455 bool operator<(const TypeEnvKey & other) const; 455 456 }; 456 457 … … 560 561 namespace std { 561 562 template<> 562 struct hash<typename ast::Type InstType::TypeEnvKey> {563 size_t operator() (const ast::Type InstType::TypeEnvKey & x) const {563 struct hash<typename ast::TypeEnvKey> { 564 size_t operator() (const ast::TypeEnvKey & x) const { 564 565 const size_t p = 1000007; 565 566 size_t res = reinterpret_cast<size_t>(x.base); -
src/AST/TypeEnvironment.cpp
r7d9598d8 r2dcd80a 82 82 } 83 83 84 const EqvClass * TypeEnvironment::lookup( const Type InstType::TypeEnvKey & var ) const {84 const EqvClass * TypeEnvironment::lookup( const TypeEnvKey & var ) const { 85 85 for ( ClassList::const_iterator i = env.begin(); i != env.end(); ++i ) { 86 86 if ( i->vars.find( var ) != i->vars.end() ) return &*i; … … 122 122 void TypeEnvironment::writeToSubstitution( TypeSubstitution & sub ) const { 123 123 for ( const auto & clz : env ) { 124 Type InstType::TypeEnvKey clzRep;124 TypeEnvKey clzRep; 125 125 bool first = true; 126 126 for ( const auto & var : clz.vars ) { … … 146 146 struct Occurs : public ast::WithVisitorRef<Occurs> { 147 147 bool result; 148 std::unordered_set< Type InstType::TypeEnvKey > vars;148 std::unordered_set< TypeEnvKey > vars; 149 149 const TypeEnvironment & tenv; 150 150 151 Occurs( const Type InstType::TypeEnvKey & var, const TypeEnvironment & env )151 Occurs( const TypeEnvKey & var, const TypeEnvironment & env ) 152 152 : result( false ), vars(), tenv( env ) { 153 153 if ( const EqvClass * clz = tenv.lookup( var ) ) { … … 170 170 171 171 /// true if `var` occurs in `ty` under `env` 172 bool occurs( const Type * ty, const Type InstType::TypeEnvKey & var, const TypeEnvironment & env ) {172 bool occurs( const Type * ty, const TypeEnvKey & var, const TypeEnvironment & env ) { 173 173 Pass<Occurs> occur{ var, env }; 174 174 maybe_accept( ty, occur ); … … 258 258 namespace { 259 259 /// true if the given type can be bound to the given type variable 260 bool tyVarCompatible( const TypeD ecl::Data & data, const Type * type ) {260 bool tyVarCompatible( const TypeData & data, const Type * type ) { 261 261 switch ( data.kind ) { 262 262 case TypeDecl::Dtype: … … 279 279 280 280 bool TypeEnvironment::bindVar( 281 const TypeInstType * typeInst, const Type * bindTo, const TypeD ecl::Data & data,281 const TypeInstType * typeInst, const Type * bindTo, const TypeData & data, 282 282 AssertionSet & need, AssertionSet & have, const OpenVarSet & open, WidenMode widen, 283 283 const SymbolTable & symtab … … 319 319 320 320 bool TypeEnvironment::bindVarToVar( 321 const TypeInstType * var1, const TypeInstType * var2, TypeD ecl::Data && data,321 const TypeInstType * var1, const TypeInstType * var2, TypeData && data, 322 322 AssertionSet & need, AssertionSet & have, const OpenVarSet & open, 323 323 WidenMode widen, const SymbolTable & symtab … … 457 457 } 458 458 459 TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const Type InstType::TypeEnvKey & var ) {459 TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const TypeEnvKey & var ) { 460 460 for ( ClassList::iterator i = env.begin(); i != env.end(); ++i ) { 461 461 if ( i->vars.count( var ) ) return i; -
src/AST/TypeEnvironment.hpp
r7d9598d8 r2dcd80a 79 79 80 80 /// Set of open variables 81 using OpenVarSet = std::unordered_map< Type InstType::TypeEnvKey, TypeDecl::Data >;81 using OpenVarSet = std::unordered_map< TypeEnvKey, TypeData >; 82 82 83 83 /// Merges one set of open vars into another … … 95 95 /// they bind to. 96 96 struct EqvClass { 97 std::unordered_set< Type InstType::TypeEnvKey > vars;97 std::unordered_set< TypeEnvKey > vars; 98 98 ptr<Type> bound; 99 99 bool allowWidening; 100 TypeD ecl::Data data;100 TypeData data; 101 101 102 102 EqvClass() : vars(), bound(), allowWidening( true ), data() {} … … 111 111 112 112 /// Singleton class constructor from substitution 113 EqvClass( const Type InstType::TypeEnvKey & v, const Type * b )113 EqvClass( const TypeEnvKey & v, const Type * b ) 114 114 : vars{ v }, bound( b ), allowWidening( false ), data( TypeDecl::Dtype, false ) {} 115 115 116 116 /// Single-var constructor (strips qualifiers from bound type) 117 EqvClass( const Type InstType::TypeEnvKey & v, const Type * b, bool w, const TypeDecl::Data & d )117 EqvClass( const TypeEnvKey & v, const Type * b, bool w, const TypeData & d ) 118 118 : vars{ v }, bound( b ), allowWidening( w ), data( d ) { 119 119 reset_qualifiers( bound ); … … 121 121 122 122 /// Double-var constructor 123 EqvClass( const Type InstType::TypeEnvKey & v, const TypeInstType::TypeEnvKey & u, bool w, const TypeDecl::Data & d )123 EqvClass( const TypeEnvKey & v, const TypeEnvKey & u, bool w, const TypeData & d ) 124 124 : vars{ v, u }, bound(), allowWidening( w ), data( d ) {} 125 125 … … 137 137 public: 138 138 /// Finds the equivalence class containing a variable; nullptr for none such 139 const EqvClass * lookup( const Type InstType::TypeEnvKey & var ) const;139 const EqvClass * lookup( const TypeEnvKey & var ) const; 140 140 141 141 /// Add a new equivalence class for each type variable … … 181 181 /// needed. Returns false on failure. 182 182 bool bindVar( 183 const TypeInstType * typeInst, const Type * bindTo, const TypeD ecl::Data & data,183 const TypeInstType * typeInst, const Type * bindTo, const TypeData & data, 184 184 AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 185 185 ResolvExpr::WidenMode widen, const SymbolTable & symtab ); … … 188 188 /// classes if needed. Returns false on failure. 189 189 bool bindVarToVar( 190 const TypeInstType * var1, const TypeInstType * var2, TypeD ecl::Data && data,190 const TypeInstType * var1, const TypeInstType * var2, TypeData && data, 191 191 AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 192 192 ResolvExpr::WidenMode widen, const SymbolTable & symtab ); … … 213 213 214 214 /// Private lookup API; returns array index of string, or env.size() for not found 215 ClassList::iterator internal_lookup( const Type InstType::TypeEnvKey & );215 ClassList::iterator internal_lookup( const TypeEnvKey & ); 216 216 }; 217 217 -
src/AST/TypeSubstitution.cpp
r7d9598d8 r2dcd80a 52 52 } 53 53 54 void TypeSubstitution::add( const Type InstType::TypeEnvKey & key, const Type * actualType) {54 void TypeSubstitution::add( const TypeEnvKey & key, const Type * actualType) { 55 55 typeMap[ key ] = actualType; 56 56 } … … 64 64 65 65 const Type *TypeSubstitution::lookup( 66 const Type InstType::TypeEnvKey & formalType ) const {66 const TypeEnvKey & formalType ) const { 67 67 TypeMap::const_iterator i = typeMap.find( formalType ); 68 68 … … 85 85 86 86 const Type *TypeSubstitution::lookup( const TypeInstType * formalType ) const { 87 return lookup( ast::Type InstType::TypeEnvKey( *formalType ) );87 return lookup( ast::TypeEnvKey( *formalType ) ); 88 88 } 89 89 -
src/AST/TypeSubstitution.hpp
r7d9598d8 r2dcd80a 72 72 73 73 void add( const TypeInstType * formalType, const Type *actualType ); 74 void add( const Type InstType::TypeEnvKey & key, const Type *actualType );74 void add( const TypeEnvKey & key, const Type *actualType ); 75 75 void add( const TypeSubstitution &other ); 76 76 void remove( const TypeInstType * formalType ); 77 const Type *lookup( const Type InstType::TypeEnvKey & formalType ) const;77 const Type *lookup( const TypeEnvKey & formalType ) const; 78 78 const Type *lookup( const TypeInstType * formalType ) const; 79 79 bool empty() const; … … 105 105 friend class Pass; 106 106 107 typedef std::unordered_map< Type InstType::TypeEnvKey, ptr<Type> > TypeMap;107 typedef std::unordered_map< TypeEnvKey, ptr<Type> > TypeMap; 108 108 TypeMap typeMap; 109 109 … … 184 184 int subCount = 0; 185 185 bool freeOnly; 186 typedef std::unordered_set< Type InstType::TypeEnvKey > BoundVarsType;186 typedef std::unordered_set< TypeEnvKey > BoundVarsType; 187 187 BoundVarsType boundVars; 188 188 -
src/CodeGen/CodeGenerator.cc
r7d9598d8 r2dcd80a 290 290 if ( obj->get_init() ) { 291 291 obj->get_init()->accept( *visitor ); 292 last_val = ((ConstantExpr *)(((SingleInit *)(obj->init))->value))->constant.get_ival(); 292 Expression* expr = ((SingleInit *)(obj->init))->value; 293 while ( auto temp = dynamic_cast<CastExpr *>(expr) ) { 294 expr = temp->arg; 295 } 296 last_val = ((ConstantExpr *)expr)->constant.get_ival(); 293 297 } else { 294 298 output << ++last_val; -
src/GenPoly/Box.cc
r7d9598d8 r2dcd80a 37 37 #include "InitTweak/InitTweak.h" // for getFunctionName, isAssignment 38 38 #include "Lvalue.h" // for generalizedLvalue 39 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass40 39 #include "ResolvExpr/typeops.h" // for typesCompatible 41 40 #include "ScopedSet.h" // for ScopedSet, ScopedSet<>::iter... … … 95 94 private: 96 95 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application 97 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); 96 /// Will insert 0, 2 or 3 more arguments. 97 std::list< Expression *>::iterator passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); 98 98 /// passes extra type parameters into a polymorphic function application 99 99 /// Returns an iterator to the first argument after the added … … 488 488 makeTyVarMap( functionType, scopeTyVars ); 489 489 490 std::list< DeclarationWithType *> ¶mList = functionType->parameters;491 490 std::list< FunctionType const *> functions; 492 491 for ( TypeDecl * const tyVar : functionType->forall ) { … … 495 494 } // for 496 495 } // for 497 for ( DeclarationWithType * const arg : paramList) {496 for ( DeclarationWithType * const arg : functionType->parameters ) { 498 497 findFunction( arg->get_type(), functions, scopeTyVars, needsAdapter ); 499 498 } // for … … 532 531 } 533 532 534 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {533 std::list< Expression *>::iterator Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 535 534 Type *polyType = isPolyType( parmType, exprTyVars ); 536 535 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { 537 536 std::string typeName = mangleType( polyType ); 538 if ( seenTypes.count( typeName ) ) return ;537 if ( seenTypes.count( typeName ) ) return arg; 539 538 540 539 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); … … 556 555 seenTypes.insert( typeName ); 557 556 } 557 return arg; 558 558 } 559 559 … … 562 562 std::list< Expression *>::iterator arg = appExpr->args.begin(); 563 563 // pass size/align for type variables 564 // NOTE: This is iterating over a map. This means the sorting 565 // order of the keys changes behaviour, as the iteration order 566 // is visible outside the loop. - The order matches the orignal 567 // order because the vars have been renamed with numbers that, 568 // even when converted to strings, sort in the original order. 569 // (At least, that is the best explination I have.) 564 570 for ( std::pair<std::string, TypeDecl::Data> const & tyParam : exprTyVars ) { 565 ResolvExpr::EqvClass eqvClass; 566 if ( tyParam.second.isComplete ) { 567 Type *concrete = env->lookup( tyParam.first ); 568 // If there is an unbound type variable, it should have detected already. 569 assertf( concrete, "Unbound type variable: %s in: %s", 570 toCString( tyParam.first ), toCString( *env ) ); 571 572 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 573 arg++; 574 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 575 arg++; 576 } // if 571 if ( !tyParam.second.isComplete ) continue; 572 Type *concrete = env->lookup( tyParam.first ); 573 // If there is an unbound type variable, it should have detected already. 574 assertf( concrete, "Unbound type variable: %s in: %s", 575 toCString( tyParam.first ), toCString( *env ) ); 576 577 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 578 arg++; 579 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 580 arg++; 577 581 } // for 578 582 … … 582 586 assert( funcType ); 583 587 584 // These iterators don't advance in unison.585 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();586 std::list< Expression* >::const_iterator fnArg = arg;587 std::set< std::string > seenTypes; ///< names for generic types we've seen588 // Iterator over the original function arguments. 589 std::list< Expression* >::const_iterator fnArg; 590 // Names for generic types we've seen. 591 std::set< std::string > seenTypes; 588 592 589 593 // a polymorphic return type may need to be added to the argument list 590 594 if ( polyRetType ) { 591 595 Type *concRetType = replaceWithConcrete( polyRetType, env ); 592 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 593 ++fnArg; // skip the return parameter in the argument list 596 arg = passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 597 // Skip the return parameter in the argument list. 598 fnArg = arg + 1; 599 } else { 600 fnArg = arg; 594 601 } 595 602 596 603 // add type information args for presently unseen types in parameter list 604 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); 597 605 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 598 if ( ! (*fnArg)->get_result() ) continue;599 606 Type * argType = (*fnArg)->get_result(); 600 passArgTypeVars( appExpr, (*fnParm)->get_type(), argType, arg, exprTyVars, seenTypes ); 607 if ( ! argType ) continue; 608 arg = passArgTypeVars( appExpr, (*fnParm)->get_type(), argType, arg, exprTyVars, seenTypes ); 601 609 } 602 610 return arg; … … 680 688 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function ) { 681 689 Expression *ret = appExpr; 682 // if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {683 690 if ( isDynRet( function, scopeTyVars ) ) { 684 691 ret = addRetParam( appExpr, function->returnVals.front()->get_type() ); … … 772 779 773 780 void Pass1::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) { 774 std::list< Expression *>::iterator cur = arg;775 781 for ( TypeDecl * const tyVar : functionType->forall ) { 776 782 for ( DeclarationWithType * const assert : tyVar->assertions ) { … … 779 785 Expression *newExpr = inferParam->second.expr->clone(); 780 786 boxParam( newExpr, assert->get_type(), tyVars ); 781 appExpr->get_args().insert( cur, newExpr ); 787 arg = appExpr->get_args().insert( arg, newExpr ); 788 ++arg; 782 789 } // for 783 790 } // for … … 922 929 // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this 923 930 // pre-substitution parameter function type. 924 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {925 adaptersDone.insert( adaptersDone.begin(), mangleName );931 // The second part of the insert result is "is the value new". 932 if ( adaptersDone.insert( mangleName ).second ) { 926 933 927 934 // apply substitution to type variables to figure out what the adapter's type should look like … … 1106 1113 1107 1114 Expression *ret = appExpr; 1115 // Save iterator to the first original parameter (works with lists). 1108 1116 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 1109 1117 … … 1172 1180 1173 1181 void Pass1::premutate( AddressExpr * ) { visit_children = false; } 1182 1174 1183 Expression * Pass1::postmutate( AddressExpr * addrExpr ) { 1175 1184 assert( addrExpr->arg->result && ! addrExpr->arg->result->isVoid() ); … … 1232 1241 1233 1242 void Pass2::addAdapters( FunctionType *functionType ) { 1234 std::list< DeclarationWithType *> ¶mList = functionType->parameters;1235 1243 std::list< FunctionType const *> functions; 1236 1244 for ( DeclarationWithType * const arg : functionType->parameters ) { … … 1245 1253 std::string adapterName = makeAdapterName( mangleName ); 1246 1254 // adapter may not be used in body, pass along with unused attribute. 1247 paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) ); 1255 functionType->parameters.push_front( 1256 new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) ); 1248 1257 adaptersDone.insert( adaptersDone.begin(), mangleName ); 1249 1258 } 1250 1259 } 1251 // deleteAll( functions );1252 1260 } 1253 1261 -
src/GenPoly/ErasableScopedMap.h
r7d9598d8 r2dcd80a 23 23 24 24 namespace GenPoly { 25 /// A map where the items are placed into nested scopes; 26 /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward; 27 /// erasing a key means that find() will no longer report any instance of the key in a scope further 28 /// out, but the erasure itself is scoped. Key erasure works by inserting a sentinal value into the 29 /// value field, and thus only works for Value types where a meaningful sentinal can be chosen. 30 template<typename Key, typename Value> 31 class ErasableScopedMap { 32 typedef std::map< Key, Value > Scope; 33 typedef std::vector< Scope > ScopeList; 34 35 ScopeList scopes; ///< scoped list of maps 36 Value erased; ///< sentinal value for erased keys 37 public: 38 typedef typename Scope::key_type key_type; 39 typedef typename Scope::mapped_type mapped_type; 40 typedef typename Scope::value_type value_type; 41 typedef typename ScopeList::size_type size_type; 42 typedef typename ScopeList::difference_type difference_type; 43 typedef typename Scope::reference reference; 44 typedef typename Scope::const_reference const_reference; 45 typedef typename Scope::pointer pointer; 46 typedef typename Scope::const_pointer const_pointer; 47 48 class iterator : public std::iterator< std::bidirectional_iterator_tag, 49 value_type > { 50 friend class ErasableScopedMap; 51 friend class const_iterator; 52 typedef typename std::map< Key, Value >::iterator wrapped_iterator; 53 typedef typename std::vector< std::map< Key, Value > > scope_list; 54 typedef typename scope_list::size_type size_type; 55 56 /// Checks if this iterator points to a valid item 57 bool is_valid() const { 58 return it != map->scopes[i].end() && it->second != map->erased; 25 26 /// A map where the items are placed into nested scopes. 27 /// Inserted items are placed into the innermost scope, lookup looks from the 28 /// innermost scope outward. Erasing a key means that find() will no longer 29 /// report any instance of the key in a scope further out, but the erasure 30 /// itself is scoped. Key erasure works by inserting a sentinal value into 31 /// the value field, and thus only works for Value types where a meaningful 32 /// sentinal can be chosen. 33 template<typename Key, typename Value> 34 class ErasableScopedMap { 35 typedef std::map< Key, Value > Scope; 36 typedef std::vector< Scope > ScopeList; 37 38 /// Scoped list of maps. 39 ScopeList scopes; 40 /// Sentinal value for erased keys. 41 Value erased; 42 public: 43 typedef typename Scope::key_type key_type; 44 typedef typename Scope::mapped_type mapped_type; 45 typedef typename Scope::value_type value_type; 46 typedef typename ScopeList::size_type size_type; 47 typedef typename ScopeList::difference_type difference_type; 48 typedef typename Scope::reference reference; 49 typedef typename Scope::const_reference const_reference; 50 typedef typename Scope::pointer pointer; 51 typedef typename Scope::const_pointer const_pointer; 52 53 // Both iterator types are complete bidirection iterators, defined below. 54 class iterator; 55 class const_iterator; 56 57 /// Starts a new scope 58 void beginScope() { 59 Scope scope; 60 scopes.push_back(scope); 61 } 62 63 /// Ends a scope; invalidates any iterators pointing to elements of that scope 64 void endScope() { 65 scopes.pop_back(); 66 assert( ! scopes.empty() ); 67 } 68 69 /// Default constructor initializes with one scope 70 ErasableScopedMap( const Value &erased_ ) : erased( erased_ ) { beginScope(); } 71 72 iterator begin() { return iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); } 73 const_iterator begin() const { return const_iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); } 74 const_iterator cbegin() const { return const_iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); } 75 iterator end() { return iterator(*this, scopes[0].end(), 0); } 76 const_iterator end() const { return const_iterator(*this, scopes[0].end(), 0); } 77 const_iterator cend() const { return const_iterator(*this, scopes[0].end(), 0); } 78 79 /// Gets the index of the current scope (counted from 1) 80 size_type currentScope() const { return scopes.size(); } 81 82 /// Finds the given key in the outermost scope it occurs; returns end() for none such 83 iterator find( const Key &key ) { 84 for ( size_type i = scopes.size() - 1; ; --i ) { 85 typename Scope::iterator val = scopes[i].find( key ); 86 if ( val != scopes[i].end() ) { 87 return val->second == erased ? end() : iterator( *this, val, i ); 59 88 } 60 61 /// Increments on invalid 62 iterator& next_valid() { 63 if ( ! is_valid() ) { ++(*this); } 64 return *this; 89 if ( i == 0 ) break; 90 } 91 return end(); 92 } 93 const_iterator find( const Key &key ) const { 94 return const_iterator( const_cast< ErasableScopedMap< Key, Value >* >(this)->find( key ) ); 95 } 96 97 /// Finds the given key in the outermost scope inside the given scope where it occurs 98 iterator findNext( const_iterator &it, const Key &key ) { 99 if ( it.i == 0 ) return end(); 100 for ( size_type i = it.i - 1; ; --i ) { 101 typename Scope::iterator val = scopes[i].find( key ); 102 if ( val != scopes[i].end() ) { 103 return val->second == erased ? end() : iterator( *this, val, i ); 65 104 } 66 67 /// Decrements on invalid 68 iterator& prev_valid() { 69 if ( ! is_valid() ) { --(*this); } 70 return *this; 71 } 72 73 iterator(ErasableScopedMap< Key, Value > const &_map, const wrapped_iterator &_it, size_type _i) 74 : map(&_map), it(_it), i(_i) {} 75 76 public: 77 iterator(const iterator &that) : map(that.map), it(that.it), i(that.i) {} 78 iterator& operator= (const iterator &that) { 79 map = that.map; i = that.i; it = that.it; 80 return *this; 81 } 82 83 reference operator* () { return *it; } 84 pointer operator-> () { return it.operator->(); } 85 86 iterator& operator++ () { 87 if ( it == map->scopes[i].end() ) { 88 if ( i == 0 ) return *this; 89 --i; 90 it = map->scopes[i].begin(); 91 } else { 92 ++it; 93 } 94 return next_valid(); 95 } 96 iterator& operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 97 98 iterator& operator-- () { 99 // may fail if this is the begin iterator; allowed by STL spec 100 if ( it == map->scopes[i].begin() ) { 101 ++i; 102 it = map->scopes[i].end(); 103 } 104 --it; 105 return prev_valid(); 106 } 107 iterator& operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 108 109 bool operator== (const iterator &that) { 110 return map == that.map && i == that.i && it == that.it; 111 } 112 bool operator!= (const iterator &that) { return !( *this == that ); } 113 114 private: 115 ErasableScopedMap< Key, Value > const *map; 116 wrapped_iterator it; 117 size_type i; 118 }; 119 120 class const_iterator : public std::iterator< std::bidirectional_iterator_tag, 121 value_type > { 122 friend class ErasableScopedMap; 123 typedef typename std::map< Key, Value >::iterator wrapped_iterator; 124 typedef typename std::map< Key, Value >::const_iterator wrapped_const_iterator; 125 typedef typename std::vector< std::map< Key, Value > > scope_list; 126 typedef typename scope_list::size_type size_type; 127 128 /// Checks if this iterator points to a valid item 129 bool is_valid() const { 130 return it != map->scopes[i].end() && it->second != map->erased; 131 } 132 133 /// Increments on invalid 134 const_iterator& next_valid() { 135 if ( ! is_valid() ) { ++(*this); } 136 return *this; 137 } 138 139 /// Decrements on invalid 140 const_iterator& prev_valid() { 141 if ( ! is_valid() ) { --(*this); } 142 return *this; 143 } 144 145 const_iterator(ErasableScopedMap< Key, Value > const &_map, const wrapped_const_iterator &_it, size_type _i) 146 : map(&_map), it(_it), i(_i) {} 147 public: 148 const_iterator(const iterator &that) : map(that.map), it(that.it), i(that.i) {} 149 const_iterator(const const_iterator &that) : map(that.map), it(that.it), i(that.i) {} 150 const_iterator& operator= (const iterator &that) { 151 map = that.map; i = that.i; it = that.it; 152 return *this; 153 } 154 const_iterator& operator= (const const_iterator &that) { 155 map = that.map; i = that.i; it = that.it; 156 return *this; 157 } 158 159 const_reference operator* () { return *it; } 160 const_pointer operator-> () { return it.operator->(); } 161 162 const_iterator& operator++ () { 163 if ( it == map->scopes[i].end() ) { 164 if ( i == 0 ) return *this; 165 --i; 166 it = map->scopes[i].begin(); 167 } else { 168 ++it; 169 } 170 return next_valid(); 171 } 172 const_iterator& operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 173 174 const_iterator& operator-- () { 175 // may fail if this is the begin iterator; allowed by STL spec 176 if ( it == map->scopes[i].begin() ) { 177 ++i; 178 it = map->scopes[i].end(); 179 } 180 --it; 181 return prev_valid(); 182 } 183 const_iterator& operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 184 185 bool operator== (const const_iterator &that) { 186 return map == that.map && i == that.i && it == that.it; 187 } 188 bool operator!= (const const_iterator &that) { return !( *this == that ); } 189 190 private: 191 ErasableScopedMap< Key, Value > const *map; 192 wrapped_const_iterator it; 193 size_type i; 194 }; 195 196 /// Starts a new scope 197 void beginScope() { 198 Scope scope; 199 scopes.push_back(scope); 200 } 201 202 /// Ends a scope; invalidates any iterators pointing to elements of that scope 203 void endScope() { 204 scopes.pop_back(); 205 assert( ! scopes.empty() ); 206 } 207 208 /// Default constructor initializes with one scope 209 ErasableScopedMap( const Value &erased_ ) : erased( erased_ ) { beginScope(); } 210 211 iterator begin() { return iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); } 212 const_iterator begin() const { return const_iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); } 213 const_iterator cbegin() const { return const_iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); } 214 iterator end() { return iterator(*this, scopes[0].end(), 0); } 215 const_iterator end() const { return const_iterator(*this, scopes[0].end(), 0); } 216 const_iterator cend() const { return const_iterator(*this, scopes[0].end(), 0); } 217 218 /// Gets the index of the current scope (counted from 1) 219 size_type currentScope() const { return scopes.size(); } 220 221 /// Finds the given key in the outermost scope it occurs; returns end() for none such 222 iterator find( const Key &key ) { 223 for ( size_type i = scopes.size() - 1; ; --i ) { 224 typename Scope::iterator val = scopes[i].find( key ); 225 if ( val != scopes[i].end() ) { 226 return val->second == erased ? end() : iterator( *this, val, i ); 227 } 228 if ( i == 0 ) break; 229 } 230 return end(); 231 } 232 const_iterator find( const Key &key ) const { 233 return const_iterator( const_cast< ErasableScopedMap< Key, Value >* >(this)->find( key ) ); 234 } 235 236 /// Finds the given key in the outermost scope inside the given scope where it occurs 237 iterator findNext( const_iterator &it, const Key &key ) { 238 if ( it.i == 0 ) return end(); 239 for ( size_type i = it.i - 1; ; --i ) { 240 typename Scope::iterator val = scopes[i].find( key ); 241 if ( val != scopes[i].end() ) { 242 return val->second == erased ? end() : iterator( *this, val, i ); 243 } 244 if ( i == 0 ) break; 245 } 246 return end(); 247 } 248 const_iterator findNext( const_iterator &it, const Key &key ) const { 249 return const_iterator( const_cast< ErasableScopedMap< Key, Value >* >(this)->findNext( it, key ) ); 250 } 251 252 /// Inserts the given key-value pair into the outermost scope 253 std::pair< iterator, bool > insert( const value_type &value ) { 254 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value ); 255 return std::make_pair( iterator(*this, res.first, scopes.size()-1), res.second ); 256 } 257 std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); } 258 259 /// Marks the given element as erased from this scope inward; returns 1 for erased an element, 0 otherwise 260 size_type erase( const Key &key ) { 261 typename Scope::iterator val = scopes.back().find( key ); 262 if ( val != scopes.back().end() ) { 263 val->second = erased; 264 return 1; 265 } else { 266 scopes.back().insert( val, std::make_pair( key, erased ) ); 267 return 0; 268 } 269 } 270 271 Value& operator[] ( const Key &key ) { 272 iterator slot = find( key ); 273 if ( slot != end() ) return slot->second; 274 return insert( key, Value() ).first->second; 275 } 276 }; 105 if ( i == 0 ) break; 106 } 107 return end(); 108 } 109 const_iterator findNext( const_iterator &it, const Key &key ) const { 110 return const_iterator( const_cast< ErasableScopedMap< Key, Value >* >(this)->findNext( it, key ) ); 111 } 112 113 /// Inserts the given key-value pair into the outermost scope 114 std::pair< iterator, bool > insert( const value_type &value ) { 115 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value ); 116 return std::make_pair( iterator(*this, res.first, scopes.size()-1), res.second ); 117 } 118 std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); } 119 120 /// Marks the given element as erased from this scope inward; returns 1 for erased an element, 0 otherwise 121 size_type erase( const Key &key ) { 122 typename Scope::iterator val = scopes.back().find( key ); 123 if ( val != scopes.back().end() ) { 124 val->second = erased; 125 return 1; 126 } else { 127 scopes.back().insert( val, std::make_pair( key, erased ) ); 128 return 0; 129 } 130 } 131 132 Value& operator[] ( const Key &key ) { 133 iterator slot = find( key ); 134 if ( slot != end() ) return slot->second; 135 return insert( key, Value() ).first->second; 136 } 137 }; 138 139 template<typename Key, typename Value> 140 class ErasableScopedMap<Key, Value>::iterator : 141 public std::iterator< std::bidirectional_iterator_tag, value_type > { 142 friend class ErasableScopedMap; 143 typedef typename std::map< Key, Value >::iterator wrapped_iterator; 144 typedef typename std::vector< std::map< Key, Value > > scope_list; 145 typedef typename scope_list::size_type size_type; 146 147 /// Checks if this iterator points to a valid item 148 bool is_valid() const { 149 return it != map->scopes[i].end() && it->second != map->erased; 150 } 151 152 /// Increments on invalid 153 iterator& next_valid() { 154 if ( ! is_valid() ) { ++(*this); } 155 return *this; 156 } 157 158 /// Decrements on invalid 159 iterator& prev_valid() { 160 if ( ! is_valid() ) { --(*this); } 161 return *this; 162 } 163 164 iterator(ErasableScopedMap< Key, Value > const &_map, const wrapped_iterator &_it, size_type _i) 165 : map(&_map), it(_it), i(_i) {} 166 167 public: 168 iterator(const iterator &that) : map(that.map), it(that.it), i(that.i) {} 169 iterator& operator= (const iterator &that) { 170 map = that.map; i = that.i; it = that.it; 171 return *this; 172 } 173 174 reference operator* () { return *it; } 175 pointer operator-> () { return it.operator->(); } 176 177 iterator& operator++ () { 178 if ( it == map->scopes[i].end() ) { 179 if ( i == 0 ) return *this; 180 --i; 181 it = map->scopes[i].begin(); 182 } else { 183 ++it; 184 } 185 return next_valid(); 186 } 187 188 iterator& operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 189 190 iterator& operator-- () { 191 // may fail if this is the begin iterator; allowed by STL spec 192 if ( it == map->scopes[i].begin() ) { 193 ++i; 194 it = map->scopes[i].end(); 195 } 196 --it; 197 return prev_valid(); 198 } 199 iterator& operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 200 201 bool operator== (const iterator &that) { 202 return map == that.map && i == that.i && it == that.it; 203 } 204 bool operator!= (const iterator &that) { return !( *this == that ); } 205 206 private: 207 ErasableScopedMap< Key, Value > const *map; 208 wrapped_iterator it; 209 size_type i; 210 }; 211 212 template<typename Key, typename Value> 213 class ErasableScopedMap<Key, Value>::const_iterator : 214 public std::iterator< std::bidirectional_iterator_tag, value_type > { 215 friend class ErasableScopedMap; 216 typedef typename std::map< Key, Value >::iterator wrapped_iterator; 217 typedef typename std::map< Key, Value >::const_iterator wrapped_const_iterator; 218 typedef typename std::vector< std::map< Key, Value > > scope_list; 219 typedef typename scope_list::size_type size_type; 220 221 /// Checks if this iterator points to a valid item 222 bool is_valid() const { 223 return it != map->scopes[i].end() && it->second != map->erased; 224 } 225 226 /// Increments on invalid 227 const_iterator& next_valid() { 228 if ( ! is_valid() ) { ++(*this); } 229 return *this; 230 } 231 232 /// Decrements on invalid 233 const_iterator& prev_valid() { 234 if ( ! is_valid() ) { --(*this); } 235 return *this; 236 } 237 238 const_iterator(ErasableScopedMap< Key, Value > const &_map, const wrapped_const_iterator &_it, size_type _i) 239 : map(&_map), it(_it), i(_i) {} 240 public: 241 const_iterator(const iterator &that) : map(that.map), it(that.it), i(that.i) {} 242 const_iterator(const const_iterator &that) : map(that.map), it(that.it), i(that.i) {} 243 const_iterator& operator= (const iterator &that) { 244 map = that.map; i = that.i; it = that.it; 245 return *this; 246 } 247 const_iterator& operator= (const const_iterator &that) { 248 map = that.map; i = that.i; it = that.it; 249 return *this; 250 } 251 252 const_reference operator* () { return *it; } 253 const_pointer operator-> () { return it.operator->(); } 254 255 const_iterator& operator++ () { 256 if ( it == map->scopes[i].end() ) { 257 if ( i == 0 ) return *this; 258 --i; 259 it = map->scopes[i].begin(); 260 } else { 261 ++it; 262 } 263 return next_valid(); 264 } 265 const_iterator& operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 266 267 const_iterator& operator-- () { 268 // may fail if this is the begin iterator; allowed by STL spec 269 if ( it == map->scopes[i].begin() ) { 270 ++i; 271 it = map->scopes[i].end(); 272 } 273 --it; 274 return prev_valid(); 275 } 276 const_iterator& operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 277 278 bool operator== (const const_iterator &that) { 279 return map == that.map && i == that.i && it == that.it; 280 } 281 bool operator!= (const const_iterator &that) { return !( *this == that ); } 282 283 private: 284 ErasableScopedMap< Key, Value > const *map; 285 wrapped_const_iterator it; 286 size_type i; 287 }; 288 277 289 } // namespace GenPoly 278 290 -
src/GenPoly/GenPoly.cc
r7d9598d8 r2dcd80a 783 783 const ast::FunctionType * function = getFunctionType( expr->func->result ); 784 784 assertf( function, "ApplicationExpr has non-function type: %s", toString( expr->func->result ).c_str() ); 785 TypeVarMap exprTyVars = { ast::TypeD ecl::Data() };785 TypeVarMap exprTyVars = { ast::TypeData() }; 786 786 makeTypeVarMap( function, exprTyVars ); 787 787 return needsBoxing( param, arg, exprTyVars, subst ); … … 793 793 794 794 void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ) { 795 typeVars.insert( *type, ast::TypeD ecl::Data( type->base ) );795 typeVars.insert( *type, ast::TypeData( type->base ) ); 796 796 } 797 797 -
src/GenPoly/GenPoly.h
r7d9598d8 r2dcd80a 20 20 21 21 #include "ErasableScopedMap.h" // for ErasableScopedMap 22 #include "AST/Decl.hpp" // for TypeDecl::Data22 #include "AST/Decl.hpp" // for AggregateDecl 23 23 #include "AST/Fwd.hpp" // for ApplicationExpr, BaseInstType, Func... 24 #include "AST/Type.hpp" // for TypeInstType::TypeEnvKey25 24 #include "SymTab/Mangler.h" // for Mangler 26 25 #include "SynTree/Declaration.h" // for TypeDecl::Data, AggregateDecl, Type... 27 26 #include "SynTree/SynTree.h" // for Visitor Nodes 28 27 28 namespace ast { 29 struct TypeEnvKey; 30 } 31 29 32 namespace GenPoly { 30 33 31 34 typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap; 32 using TypeVarMap = ErasableScopedMap< ast::Type InstType::TypeEnvKey, ast::TypeDecl::Data >;35 using TypeVarMap = ErasableScopedMap< ast::TypeEnvKey, ast::TypeData >; 33 36 34 37 /// Replaces a TypeInstType by its referrent in the environment, if applicable -
src/Parser/DeclarationNode.cc
r7d9598d8 r2dcd80a 254 254 } // DeclarationNode::newAggregate 255 255 256 DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base ) {256 DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base, EnumHiding hiding ) { 257 257 DeclarationNode * newnode = new DeclarationNode; 258 258 newnode->type = new TypeData( TypeData::Enum ); … … 262 262 newnode->type->enumeration.anon = name == nullptr; 263 263 newnode->type->enumeration.typed = typed; 264 newnode->type->enumeration.hiding = hiding; 264 265 if ( base && base->type) { 265 266 newnode->type->base = base->type; -
src/Parser/ParseNode.h
r7d9598d8 r2dcd80a 239 239 static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ); 240 240 static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ); 241 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr );241 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible ); 242 242 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant ); 243 243 static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init ); -
src/Parser/TypeData.cc
r7d9598d8 r2dcd80a 923 923 buildList( td->enumeration.constants, ret->get_members() ); 924 924 list< Declaration * >::iterator members = ret->get_members().begin(); 925 ret->hide = td->enumeration.hiding == EnumHiding::Hide ? EnumDecl::EnumHiding::Hide : EnumDecl::EnumHiding::Visible; 925 926 for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) { 926 927 if ( cur->enumInLine ) { -
src/Parser/TypeData.h
r7d9598d8 r2dcd80a 60 60 bool anon; 61 61 bool typed; 62 EnumHiding hiding; 62 63 }; 63 64 -
src/Parser/parser.yy
r7d9598d8 r2dcd80a 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Nov 2 21:31:21202213 // Update Count : 58 1012 // Last Modified On : Mon Nov 21 22:34:30 2022 13 // Update Count : 5848 14 14 // 15 15 … … 383 383 %type<ifctl> conditional_declaration 384 384 %type<fctl> for_control_expression for_control_expression_list 385 %type<compop> up down updowneq downupdowneq385 %type<compop> upupeq updown updowneq downupdowneq 386 386 %type<en> subrange 387 387 %type<decl> asm_name_opt … … 489 489 %type<decl> type_parameter type_parameter_list type_initializer_opt 490 490 491 %type<en> type_parameters_opt type_list 491 %type<en> type_parameters_opt type_list array_type_list 492 492 493 493 %type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list … … 551 551 552 552 %% 553 // ************************* Namespace Management ********************************553 // ************************ Namespace Management ******************************** 554 554 555 555 // The C grammar is not context free because it relies on the distinct terminal symbols "identifier" and "TYPEDEFname", … … 588 588 ; 589 589 590 // ************************* CONSTANTS ********************************590 // ************************ CONSTANTS ******************************** 591 591 592 592 constant: … … 634 634 ; 635 635 636 // ************************* EXPRESSIONS ********************************636 // ************************ EXPRESSIONS ******************************** 637 637 638 638 primary_expression: … … 1101 1101 ; 1102 1102 1103 // *************************** STATEMENTS *******************************1103 // ************************** STATEMENTS ******************************* 1104 1104 1105 1105 statement: … … 1758 1758 ; 1759 1759 1760 // ******************************* DECLARATIONS *********************************1760 // ****************************** DECLARATIONS ********************************* 1761 1761 1762 1762 declaration_list_opt: // used at beginning of switch statement … … 2558 2558 { typedefTable.makeTypedef( *$3 ); } 2559 2559 hide_opt '{' enumerator_list comma_opt '}' 2560 { $$ = DeclarationNode::newEnum( $3, $7, true, false)->addQualifiers( $2 ); }2560 { $$ = DeclarationNode::newEnum( $3, $7, true, false, nullptr, $5 )->addQualifiers( $2 ); } 2561 2561 | ENUM attribute_list_opt typedef_name // unqualified type name 2562 2562 hide_opt '{' enumerator_list comma_opt '}' 2563 { $$ = DeclarationNode::newEnum( $3->name, $6, true, false )->addQualifiers( $2 ); }2563 { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); } 2564 2564 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2565 2565 { … … 2580 2580 hide_opt '{' enumerator_list comma_opt '}' 2581 2581 { 2582 $$ = DeclarationNode::newEnum( $6, $11, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );2582 $$ = DeclarationNode::newEnum( $6, $11, true, true, $3, $9 )->addQualifiers( $5 )->addQualifiers( $7 ); 2583 2583 } 2584 2584 | ENUM '(' ')' attribute_list_opt identifier attribute_list_opt 2585 2585 hide_opt '{' enumerator_list comma_opt '}' 2586 2586 { 2587 $$ = DeclarationNode::newEnum( $5, $9, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 );2587 $$ = DeclarationNode::newEnum( $5, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 ); 2588 2588 } 2589 2589 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt 2590 2590 hide_opt '{' enumerator_list comma_opt '}' 2591 2591 { 2592 $$ = DeclarationNode::newEnum( $6->name, $10, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );2592 $$ = DeclarationNode::newEnum( $6->name, $10, true, true, $3, $8 )->addQualifiers( $5 )->addQualifiers( $7 ); 2593 2593 } 2594 2594 | ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt 2595 2595 hide_opt '{' enumerator_list comma_opt '}' 2596 2596 { 2597 $$ = DeclarationNode::newEnum( $5->name, $9, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 );2597 $$ = DeclarationNode::newEnum( $5->name, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 ); 2598 2598 } 2599 2599 | enum_type_nobody … … 2991 2991 ; 2992 2992 2993 // ***************************** EXTERNAL DEFINITIONS *****************************2993 // **************************** EXTERNAL DEFINITIONS ***************************** 2994 2994 2995 2995 translation_unit: … … 3653 3653 | '[' ']' multi_array_dimension 3654 3654 { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $3 ); } 3655 | '[' push assignment_expression pop ',' comma_expression ']' 3655 // Cannot use constant_expression because of tuples => semantic check 3656 | '[' push assignment_expression pop ',' comma_expression ']' // CFA 3656 3657 { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); } 3657 3658 // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; } 3659 | '[' push array_type_list pop ']' // CFA 3660 { SemanticError( yylloc, "Type array dimension is currently unimplemented." ); $$ = nullptr; } 3658 3661 | multi_array_dimension 3659 3662 ; 3663 3664 array_type_list: 3665 basic_type_name 3666 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3667 | type_name 3668 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 3669 | assignment_expression upupeq assignment_expression 3670 | array_type_list ',' basic_type_name 3671 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3672 | array_type_list ',' type_name 3673 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 3674 | array_type_list ',' assignment_expression upupeq assignment_expression 3675 ; 3676 3677 upupeq: 3678 '~' 3679 { $$ = OperKinds::LThan; } 3680 | ErangeUpEq 3681 { $$ = OperKinds::LEThan; } 3682 ; 3660 3683 3661 3684 multi_array_dimension: … … 3990 4013 // declaration lists (not prototype-format parameter type and identifier declarators) is an obsolescent feature. 3991 4014 3992 // ************************* MISCELLANEOUS ********************************4015 // ************************ MISCELLANEOUS ******************************** 3993 4016 3994 4017 comma_opt: // redundant comma -
src/ResolvExpr/CandidateFinder.cpp
r7d9598d8 r2dcd80a 221 221 ) { 222 222 for ( auto & tyvar : type->forall ) { 223 unifiableVars[ *tyvar ] = ast::TypeD ecl::Data{ tyvar->base };223 unifiableVars[ *tyvar ] = ast::TypeData{ tyvar->base }; 224 224 } 225 225 for ( auto & assn : type->assertions ) { -
src/ResolvExpr/FindOpenVars.cc
r7d9598d8 r2dcd80a 113 113 if ( nextIsOpen ) { 114 114 for ( auto & decl : type->forall ) { 115 open[ *decl ] = ast::TypeD ecl::Data{ decl->base };115 open[ *decl ] = ast::TypeData{ decl->base }; 116 116 } 117 117 for ( auto & assert : type->assertions ) { … … 120 120 } else { 121 121 for ( auto & decl : type->forall ) { 122 closed[ *decl ] = ast::TypeD ecl::Data{ decl->base };122 closed[ *decl ] = ast::TypeData{ decl->base }; 123 123 } 124 124 for ( auto & assert : type->assertions ) { -
src/ResolvExpr/RenameVars.cc
r7d9598d8 r2dcd80a 42 42 int next_usage_id = 1; 43 43 ScopedMap< std::string, std::string > nameMap; 44 ScopedMap< std::string, ast::Type InstType::TypeEnvKey > idMap;44 ScopedMap< std::string, ast::TypeEnvKey > idMap; 45 45 public: 46 46 void reset() { … … 121 121 assert(false); 122 122 } 123 idMap[ td->name ] = ast::Type InstType::TypeEnvKey(*mut);124 123 idMap[ td->name ] = ast::TypeEnvKey( *mut ); 124 125 125 td = mut; 126 126 } -
src/ResolvExpr/Unify.cc
r7d9598d8 r2dcd80a 1166 1166 if ( entry1->second.kind != entry2->second.kind ) return false; 1167 1167 return env.bindVarToVar( 1168 var1, var2, ast::TypeD ecl::Data{ entry1->second, entry2->second }, need, have,1168 var1, var2, ast::TypeData{ entry1->second, entry2->second }, need, have, 1169 1169 open, widen, symtab ); 1170 1170 } else if ( isopen1 ) { -
src/SynTree/Declaration.h
r7d9598d8 r2dcd80a 340 340 bool isTyped; 341 341 Type * base; 342 enum EnumHiding { Visible, Hide } hide; 342 343 343 344 EnumDecl( const std::string & name, … … 345 346 bool isTyped = false, LinkageSpec::Spec linkage = LinkageSpec::Cforall, 346 347 Type * baseType = nullptr ) 347 : Parent( name, attributes, linkage ), isTyped(isTyped), base( baseType ) {}348 : Parent( name, attributes, linkage ), isTyped(isTyped), base( baseType ) {} 348 349 EnumDecl( const EnumDecl & other ) 349 350 : Parent( other ), isTyped( other.isTyped), base( other.base ) {}
Note:
See TracChangeset
for help on using the changeset viewer.