Changeset 2dcd80a for src


Ignore:
Timestamp:
Dec 14, 2022, 12:23:42 PM (3 years ago)
Author:
caparson <caparson@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src
Files:
25 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r7d9598d8 r2dcd80a  
    17641764                        { old->linkage.val },
    17651765                        GET_ACCEPT_1(base, Type),
     1766                        old->hide == EnumDecl::EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible,
    17661767                        old->enumValues
    17671768                );
  • src/AST/Decl.cpp

    r7d9598d8 r2dcd80a  
    125125}
    126126
    127 std::ostream & operator<< ( std::ostream & out, const TypeDecl::Data & data ) {
     127std::ostream & operator<< ( std::ostream & out, const TypeData & data ) {
    128128        return out << data.kind << ", " << data.isComplete;
    129129}
  • src/AST/Decl.hpp

    r7d9598d8 r2dcd80a  
    1010// Created On       : Thu May 9 10:00:00 2019
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thu May  5 12:09:00 2022
    13 // Update Count     : 33
     12// Last Modified On : Thu Nov 24  9:44:00 2022
     13// Update Count     : 34
    1414//
    1515
     
    191191        ptr<Type> init;
    192192
    193         /// Data extracted from a type decl
    194         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 
    208193        TypeDecl(
    209194                const CodeLocation & loc, const std::string & name, Storage::Classes storage,
     
    225210};
    226211
    227 std::ostream & operator<< ( std::ostream &, const TypeDecl::Data & );
     212/// Data extracted from a TypeDecl.
     213struct 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
     227std::ostream & operator<< ( std::ostream &, const TypeData & );
    228228
    229229/// C-style typedef `typedef Foo Bar`
     
    315315        // enum (type_optional) Name {...}
    316316        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,
    319320                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall,
    320                 Type const * base = nullptr,
     321                Type const * base = nullptr, EnumHiding hide = EnumHiding::Hide,
    321322                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) {}
    323324
    324325        /// gets the integer value for this enumerator, returning true iff value found
  • src/AST/Pass.impl.hpp

    r7d9598d8 r2dcd80a  
    686686
    687687        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                }
    693700        }
    694701
  • src/AST/Type.cpp

    r7d9598d8 r2dcd80a  
    1010// Created On       : Mon May 13 15:00:00 2019
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thu Jul 23 14:16:00 2020
    13 // Update Count     : 5
     12// Last Modified On : Thu Nov 24  9:49:00 2022
     13// Update Count     : 6
    1414//
    1515
     
    147147// --- TypeInstType
    148148
     149TypeInstType::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
    149152bool TypeInstType::operator==( const TypeInstType & other ) const {
    150153        return base == other.base
     
    164167bool TypeInstType::isComplete() const { return base->sized; }
    165168
    166 std::string TypeInstType::TypeEnvKey::typeString() const {
     169std::string TypeEnvKey::typeString() const {
    167170        return std::string("_") + std::to_string(formal_usage)
    168171                + "_" + std::to_string(expr_id) + "_" + base->name;
    169172}
    170173
    171 bool TypeInstType::TypeEnvKey::operator==(
    172                 const TypeInstType::TypeEnvKey & other ) const {
     174bool TypeEnvKey::operator==(
     175                const TypeEnvKey & other ) const {
    173176        return base == other.base
    174177                && formal_usage == other.formal_usage
     
    176179}
    177180
    178 bool TypeInstType::TypeEnvKey::operator<(
    179                 const TypeInstType::TypeEnvKey & other ) const {
     181bool TypeEnvKey::operator<(
     182                const TypeEnvKey & other ) const {
    180183        // TypeEnvKey ordering is an arbitrary total ordering.
    181184        // It doesn't mean anything but allows for a sorting.
  • src/AST/Type.hpp

    r7d9598d8 r2dcd80a  
    1010// Created On       : Thu May 9 10:00:00 2019
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jul 14 15:54:00 2021
    13 // Update Count     : 7
     12// Last Modified On : Thu Nov 24  9:47:00 2022
     13// Update Count     : 8
    1414//
    1515
     
    390390};
    391391
     392struct TypeEnvKey;
     393
    392394/// instance of named type alias (typedef or variable)
    393395class TypeInstType final : public BaseInstType {
     
    401403        int expr_id = 0;
    402404
    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 
    419405        bool operator==(const TypeInstType & other) const;
    420406
     
    433419        TypeInstType( const TypeInstType & o ) = default;
    434420
    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 );
    437422
    438423        /// sets `base`, updating `kind` correctly
     
    453438        TypeInstType * clone() const override { return new TypeInstType{ *this }; }
    454439        MUTATE_FRIEND
     440};
     441
     442/// Compact representation of TypeInstType used for map lookups.
     443struct 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;
    455456};
    456457
     
    560561namespace std {
    561562        template<>
    562         struct hash<typename ast::TypeInstType::TypeEnvKey> {
    563                 size_t operator() (const ast::TypeInstType::TypeEnvKey & x) const {
     563        struct hash<typename ast::TypeEnvKey> {
     564                size_t operator() (const ast::TypeEnvKey & x) const {
    564565                        const size_t p = 1000007;
    565566                        size_t res = reinterpret_cast<size_t>(x.base);
  • src/AST/TypeEnvironment.cpp

    r7d9598d8 r2dcd80a  
    8282}
    8383
    84 const EqvClass * TypeEnvironment::lookup( const TypeInstType::TypeEnvKey & var ) const {
     84const EqvClass * TypeEnvironment::lookup( const TypeEnvKey & var ) const {
    8585        for ( ClassList::const_iterator i = env.begin(); i != env.end(); ++i ) {
    8686                if ( i->vars.find( var ) != i->vars.end() ) return &*i;
     
    122122void TypeEnvironment::writeToSubstitution( TypeSubstitution & sub ) const {
    123123        for ( const auto & clz : env ) {
    124                 TypeInstType::TypeEnvKey clzRep;
     124                TypeEnvKey clzRep;
    125125                bool first = true;
    126126                for ( const auto & var : clz.vars ) {
     
    146146        struct Occurs : public ast::WithVisitorRef<Occurs> {
    147147                bool result;
    148                 std::unordered_set< TypeInstType::TypeEnvKey > vars;
     148                std::unordered_set< TypeEnvKey > vars;
    149149                const TypeEnvironment & tenv;
    150150
    151                 Occurs( const TypeInstType::TypeEnvKey & var, const TypeEnvironment & env )
     151                Occurs( const TypeEnvKey & var, const TypeEnvironment & env )
    152152                : result( false ), vars(), tenv( env ) {
    153153                        if ( const EqvClass * clz = tenv.lookup( var ) ) {
     
    170170
    171171        /// true if `var` occurs in `ty` under `env`
    172         bool occurs( const Type * ty, const TypeInstType::TypeEnvKey & var, const TypeEnvironment & env ) {
     172        bool occurs( const Type * ty, const TypeEnvKey & var, const TypeEnvironment & env ) {
    173173                Pass<Occurs> occur{ var, env };
    174174                maybe_accept( ty, occur );
     
    258258namespace {
    259259        /// true if the given type can be bound to the given type variable
    260         bool tyVarCompatible( const TypeDecl::Data & data, const Type * type ) {
     260        bool tyVarCompatible( const TypeData & data, const Type * type ) {
    261261                switch ( data.kind ) {
    262262                  case TypeDecl::Dtype:
     
    279279
    280280bool TypeEnvironment::bindVar(
    281                 const TypeInstType * typeInst, const Type * bindTo, const TypeDecl::Data & data,
     281                const TypeInstType * typeInst, const Type * bindTo, const TypeData & data,
    282282                AssertionSet & need, AssertionSet & have, const OpenVarSet & open, WidenMode widen,
    283283                const SymbolTable & symtab
     
    319319
    320320bool TypeEnvironment::bindVarToVar(
    321                 const TypeInstType * var1, const TypeInstType * var2, TypeDecl::Data && data,
     321                const TypeInstType * var1, const TypeInstType * var2, TypeData && data,
    322322                AssertionSet & need, AssertionSet & have, const OpenVarSet & open,
    323323                WidenMode widen, const SymbolTable & symtab
     
    457457}
    458458
    459 TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const TypeInstType::TypeEnvKey & var ) {
     459TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const TypeEnvKey & var ) {
    460460        for ( ClassList::iterator i = env.begin(); i != env.end(); ++i ) {
    461461                if ( i->vars.count( var ) ) return i;
  • src/AST/TypeEnvironment.hpp

    r7d9598d8 r2dcd80a  
    7979
    8080/// Set of open variables
    81 using OpenVarSet = std::unordered_map< TypeInstType::TypeEnvKey, TypeDecl::Data >;
     81using OpenVarSet = std::unordered_map< TypeEnvKey, TypeData >;
    8282
    8383/// Merges one set of open vars into another
     
    9595/// they bind to.
    9696struct EqvClass {
    97         std::unordered_set< TypeInstType::TypeEnvKey > vars;
     97        std::unordered_set< TypeEnvKey > vars;
    9898        ptr<Type> bound;
    9999        bool allowWidening;
    100         TypeDecl::Data data;
     100        TypeData data;
    101101
    102102        EqvClass() : vars(), bound(), allowWidening( true ), data() {}
     
    111111
    112112        /// Singleton class constructor from substitution
    113         EqvClass( const TypeInstType::TypeEnvKey & v, const Type * b )
     113        EqvClass( const TypeEnvKey & v, const Type * b )
    114114        : vars{ v }, bound( b ), allowWidening( false ), data( TypeDecl::Dtype, false ) {}
    115115
    116116        /// Single-var constructor (strips qualifiers from bound type)
    117         EqvClass( const TypeInstType::TypeEnvKey & v, const Type * b, bool w, const TypeDecl::Data & d )
     117        EqvClass( const TypeEnvKey & v, const Type * b, bool w, const TypeData & d )
    118118        : vars{ v }, bound( b ), allowWidening( w ), data( d ) {
    119119                reset_qualifiers( bound );
     
    121121
    122122        /// Double-var constructor
    123         EqvClass( const TypeInstType::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 )
    124124        : vars{ v, u }, bound(), allowWidening( w ), data( d ) {}
    125125
     
    137137public:
    138138        /// Finds the equivalence class containing a variable; nullptr for none such
    139         const EqvClass * lookup( const TypeInstType::TypeEnvKey & var ) const;
     139        const EqvClass * lookup( const TypeEnvKey & var ) const;
    140140
    141141        /// Add a new equivalence class for each type variable
     
    181181        /// needed. Returns false on failure.
    182182        bool bindVar(
    183                 const TypeInstType * typeInst, const Type * bindTo, const TypeDecl::Data & data,
     183                const TypeInstType * typeInst, const Type * bindTo, const TypeData & data,
    184184                AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars,
    185185                ResolvExpr::WidenMode widen, const SymbolTable & symtab );
     
    188188        /// classes if needed. Returns false on failure.
    189189        bool bindVarToVar(
    190                 const TypeInstType * var1, const TypeInstType * var2, TypeDecl::Data && data,
     190                const TypeInstType * var1, const TypeInstType * var2, TypeData && data,
    191191                AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars,
    192192                ResolvExpr::WidenMode widen, const SymbolTable & symtab );
     
    213213
    214214        /// Private lookup API; returns array index of string, or env.size() for not found
    215         ClassList::iterator internal_lookup( const TypeInstType::TypeEnvKey & );
     215        ClassList::iterator internal_lookup( const TypeEnvKey & );
    216216};
    217217
  • src/AST/TypeSubstitution.cpp

    r7d9598d8 r2dcd80a  
    5252}
    5353
    54 void TypeSubstitution::add( const TypeInstType::TypeEnvKey & key, const Type * actualType) {
     54void TypeSubstitution::add( const TypeEnvKey & key, const Type * actualType) {
    5555        typeMap[ key ] = actualType;
    5656}
     
    6464
    6565const Type *TypeSubstitution::lookup(
    66                 const TypeInstType::TypeEnvKey & formalType ) const {
     66                const TypeEnvKey & formalType ) const {
    6767        TypeMap::const_iterator i = typeMap.find( formalType );
    6868
     
    8585
    8686const Type *TypeSubstitution::lookup( const TypeInstType * formalType ) const {
    87         return lookup( ast::TypeInstType::TypeEnvKey( *formalType ) );
     87        return lookup( ast::TypeEnvKey( *formalType ) );
    8888}
    8989
  • src/AST/TypeSubstitution.hpp

    r7d9598d8 r2dcd80a  
    7272
    7373        void add( const TypeInstType * formalType, const Type *actualType );
    74         void add( const TypeInstType::TypeEnvKey & key, const Type *actualType );
     74        void add( const TypeEnvKey & key, const Type *actualType );
    7575        void add( const TypeSubstitution &other );
    7676        void remove( const TypeInstType * formalType );
    77         const Type *lookup( const TypeInstType::TypeEnvKey & formalType ) const;
     77        const Type *lookup( const TypeEnvKey & formalType ) const;
    7878        const Type *lookup( const TypeInstType * formalType ) const;
    7979        bool empty() const;
     
    105105        friend class Pass;
    106106
    107         typedef std::unordered_map< TypeInstType::TypeEnvKey, ptr<Type> > TypeMap;
     107        typedef std::unordered_map< TypeEnvKey, ptr<Type> > TypeMap;
    108108        TypeMap typeMap;
    109109
     
    184184                int subCount = 0;
    185185                bool freeOnly;
    186                 typedef std::unordered_set< TypeInstType::TypeEnvKey > BoundVarsType;
     186                typedef std::unordered_set< TypeEnvKey > BoundVarsType;
    187187                BoundVarsType boundVars;
    188188
  • src/CodeGen/CodeGenerator.cc

    r7d9598d8 r2dcd80a  
    290290                                        if ( obj->get_init() ) {
    291291                                                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();
    293297                                        } else {
    294298                                                output << ++last_val;
  • src/GenPoly/Box.cc

    r7d9598d8 r2dcd80a  
    3737#include "InitTweak/InitTweak.h"         // for getFunctionName, isAssignment
    3838#include "Lvalue.h"                      // for generalizedLvalue
    39 #include "ResolvExpr/TypeEnvironment.h"  // for EqvClass
    4039#include "ResolvExpr/typeops.h"          // for typesCompatible
    4140#include "ScopedSet.h"                   // for ScopedSet, ScopedSet<>::iter...
     
    9594                  private:
    9695                        /// 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 );
    9898                        /// passes extra type parameters into a polymorphic function application
    9999                        /// Returns an iterator to the first argument after the added
     
    488488                                makeTyVarMap( functionType, scopeTyVars );
    489489
    490                                 std::list< DeclarationWithType *> &paramList = functionType->parameters;
    491490                                std::list< FunctionType const *> functions;
    492491                                for ( TypeDecl * const tyVar : functionType->forall ) {
     
    495494                                        } // for
    496495                                } // for
    497                                 for ( DeclarationWithType * const arg : paramList ) {
     496                                for ( DeclarationWithType * const arg : functionType->parameters ) {
    498497                                        findFunction( arg->get_type(), functions, scopeTyVars, needsAdapter );
    499498                                } // for
     
    532531                }
    533532
    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 ) {
    535534                        Type *polyType = isPolyType( parmType, exprTyVars );
    536535                        if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) {
    537536                                std::string typeName = mangleType( polyType );
    538                                 if ( seenTypes.count( typeName ) ) return;
     537                                if ( seenTypes.count( typeName ) ) return arg;
    539538
    540539                                arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) );
     
    556555                                seenTypes.insert( typeName );
    557556                        }
     557                        return arg;
    558558                }
    559559
     
    562562                        std::list< Expression *>::iterator arg = appExpr->args.begin();
    563563                        // 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.)
    564570                        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++;
    577581                        } // for
    578582
     
    582586                        assert( funcType );
    583587
    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 seen
     588                        // 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;
    588592
    589593                        // a polymorphic return type may need to be added to the argument list
    590594                        if ( polyRetType ) {
    591595                                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;
    594601                        }
    595602
    596603                        // add type information args for presently unseen types in parameter list
     604                        std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();
    597605                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
    598                                 if ( ! (*fnArg)->get_result() ) continue;
    599606                                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 );
    601609                        }
    602610                        return arg;
     
    680688                Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function ) {
    681689                        Expression *ret = appExpr;
    682 //                      if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {
    683690                        if ( isDynRet( function, scopeTyVars ) ) {
    684691                                ret = addRetParam( appExpr, function->returnVals.front()->get_type() );
     
    772779
    773780                void Pass1::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) {
    774                         std::list< Expression *>::iterator cur = arg;
    775781                        for ( TypeDecl * const tyVar : functionType->forall ) {
    776782                                for ( DeclarationWithType * const assert : tyVar->assertions ) {
     
    779785                                        Expression *newExpr = inferParam->second.expr->clone();
    780786                                        boxParam( newExpr, assert->get_type(), tyVars );
    781                                         appExpr->get_args().insert( cur, newExpr );
     787                                        arg = appExpr->get_args().insert( arg, newExpr );
     788                                        ++arg;
    782789                                } // for
    783790                        } // for
     
    922929                                // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this
    923930                                // 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 ) {
    926933
    927934                                        // apply substitution to type variables to figure out what the adapter's type should look like
     
    11061113
    11071114                        Expression *ret = appExpr;
     1115                        // Save iterator to the first original parameter (works with lists).
    11081116                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    11091117
     
    11721180
    11731181                void Pass1::premutate( AddressExpr * ) { visit_children = false; }
     1182
    11741183                Expression * Pass1::postmutate( AddressExpr * addrExpr ) {
    11751184                        assert( addrExpr->arg->result && ! addrExpr->arg->result->isVoid() );
     
    12321241
    12331242                void Pass2::addAdapters( FunctionType *functionType ) {
    1234                         std::list< DeclarationWithType *> &paramList = functionType->parameters;
    12351243                        std::list< FunctionType const *> functions;
    12361244                        for ( DeclarationWithType * const arg : functionType->parameters ) {
     
    12451253                                        std::string adapterName = makeAdapterName( mangleName );
    12461254                                        // 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" ) } ) );
    12481257                                        adaptersDone.insert( adaptersDone.begin(), mangleName );
    12491258                                }
    12501259                        }
    1251 //  deleteAll( functions );
    12521260                }
    12531261
  • src/GenPoly/ErasableScopedMap.h

    r7d9598d8 r2dcd80a  
    2323
    2424namespace 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.
     33template<typename Key, typename Value>
     34class 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;
     42public:
     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 );
    5988                        }
    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 );
    65104                        }
    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
     139template<typename Key, typename Value>
     140class 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
     167public:
     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
     206private:
     207        ErasableScopedMap< Key, Value > const *map;
     208        wrapped_iterator it;
     209        size_type i;
     210};
     211
     212template<typename Key, typename Value>
     213class 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) {}
     240public:
     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
     283private:
     284        ErasableScopedMap< Key, Value > const *map;
     285        wrapped_const_iterator it;
     286        size_type i;
     287};
     288
    277289} // namespace GenPoly
    278290
  • src/GenPoly/GenPoly.cc

    r7d9598d8 r2dcd80a  
    783783        const ast::FunctionType * function = getFunctionType( expr->func->result );
    784784        assertf( function, "ApplicationExpr has non-function type: %s", toString( expr->func->result ).c_str() );
    785         TypeVarMap exprTyVars = { ast::TypeDecl::Data() };
     785        TypeVarMap exprTyVars = { ast::TypeData() };
    786786        makeTypeVarMap( function, exprTyVars );
    787787        return needsBoxing( param, arg, exprTyVars, subst );
     
    793793
    794794void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ) {
    795         typeVars.insert( *type, ast::TypeDecl::Data( type->base ) );
     795        typeVars.insert( *type, ast::TypeData( type->base ) );
    796796}
    797797
  • src/GenPoly/GenPoly.h

    r7d9598d8 r2dcd80a  
    2020
    2121#include "ErasableScopedMap.h"    // for ErasableScopedMap
    22 #include "AST/Decl.hpp"           // for TypeDecl::Data
     22#include "AST/Decl.hpp"           // for AggregateDecl
    2323#include "AST/Fwd.hpp"            // for ApplicationExpr, BaseInstType, Func...
    24 #include "AST/Type.hpp"           // for TypeInstType::TypeEnvKey
    2524#include "SymTab/Mangler.h"       // for Mangler
    2625#include "SynTree/Declaration.h"  // for TypeDecl::Data, AggregateDecl, Type...
    2726#include "SynTree/SynTree.h"      // for Visitor Nodes
    2827
     28namespace ast {
     29        struct TypeEnvKey;
     30}
     31
    2932namespace GenPoly {
    3033
    3134        typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap;
    32         using TypeVarMap = ErasableScopedMap< ast::TypeInstType::TypeEnvKey, ast::TypeDecl::Data >;
     35        using TypeVarMap = ErasableScopedMap< ast::TypeEnvKey, ast::TypeData >;
    3336
    3437        /// Replaces a TypeInstType by its referrent in the environment, if applicable
  • src/Parser/DeclarationNode.cc

    r7d9598d8 r2dcd80a  
    254254} // DeclarationNode::newAggregate
    255255
    256 DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base) {
     256DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base, EnumHiding hiding ) {
    257257        DeclarationNode * newnode = new DeclarationNode;
    258258        newnode->type = new TypeData( TypeData::Enum );
     
    262262        newnode->type->enumeration.anon = name == nullptr;
    263263        newnode->type->enumeration.typed = typed;
     264        newnode->type->enumeration.hiding = hiding;
    264265        if ( base && base->type)  {
    265266                newnode->type->base = base->type;
  • src/Parser/ParseNode.h

    r7d9598d8 r2dcd80a  
    239239        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
    240240        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 );
    242242        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
    243243        static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
  • src/Parser/TypeData.cc

    r7d9598d8 r2dcd80a  
    923923        buildList( td->enumeration.constants, ret->get_members() );
    924924        list< Declaration * >::iterator members = ret->get_members().begin();
     925        ret->hide = td->enumeration.hiding == EnumHiding::Hide ? EnumDecl::EnumHiding::Hide : EnumDecl::EnumHiding::Visible;
    925926        for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
    926927                if ( cur->enumInLine ) {
  • src/Parser/TypeData.h

    r7d9598d8 r2dcd80a  
    6060                bool anon;
    6161                bool typed;
     62                EnumHiding hiding;
    6263        };
    6364
  • src/Parser/parser.yy

    r7d9598d8 r2dcd80a  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Nov  2 21:31:21 2022
    13 // Update Count     : 5810
     12// Last Modified On : Mon Nov 21 22:34:30 2022
     13// Update Count     : 5848
    1414//
    1515
     
    383383%type<ifctl> conditional_declaration
    384384%type<fctl> for_control_expression              for_control_expression_list
    385 %type<compop> updown updowneq downupdowneq
     385%type<compop> upupeq updown updowneq downupdowneq
    386386%type<en> subrange
    387387%type<decl> asm_name_opt
     
    489489%type<decl> type_parameter type_parameter_list type_initializer_opt
    490490
    491 %type<en> type_parameters_opt type_list
     491%type<en> type_parameters_opt type_list array_type_list
    492492
    493493%type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list
     
    551551
    552552%%
    553 //************************* Namespace Management ********************************
     553// ************************ Namespace Management ********************************
    554554
    555555// The C grammar is not context free because it relies on the distinct terminal symbols "identifier" and "TYPEDEFname",
     
    588588        ;
    589589
    590 //************************* CONSTANTS ********************************
     590// ************************ CONSTANTS ********************************
    591591
    592592constant:
     
    634634        ;
    635635
    636 //************************* EXPRESSIONS ********************************
     636// ************************ EXPRESSIONS ********************************
    637637
    638638primary_expression:
     
    11011101        ;
    11021102
    1103 //*************************** STATEMENTS *******************************
     1103// ************************** STATEMENTS *******************************
    11041104
    11051105statement:
     
    17581758        ;
    17591759
    1760 //******************************* DECLARATIONS *********************************
     1760// ****************************** DECLARATIONS *********************************
    17611761
    17621762declaration_list_opt:                                                                   // used at beginning of switch statement
     
    25582558                { typedefTable.makeTypedef( *$3 ); }
    25592559          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 ); }
    25612561        | ENUM attribute_list_opt typedef_name                          // unqualified type name
    25622562          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 ); }
    25642564        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    25652565                {
     
    25802580          hide_opt '{' enumerator_list comma_opt '}'
    25812581                {
    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 );
    25832583                }
    25842584        | ENUM '(' ')' attribute_list_opt identifier attribute_list_opt
    25852585          hide_opt '{' enumerator_list comma_opt '}'
    25862586                {
    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 );
    25882588                }
    25892589        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt
    25902590          hide_opt '{' enumerator_list comma_opt '}'
    25912591                {
    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 );
    25932593                }
    25942594        | ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt
    25952595          hide_opt '{' enumerator_list comma_opt '}'
    25962596                {
    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 );
    25982598                }
    25992599        | enum_type_nobody
     
    29912991        ;
    29922992
    2993 //***************************** EXTERNAL DEFINITIONS *****************************
     2993// **************************** EXTERNAL DEFINITIONS *****************************
    29942994
    29952995translation_unit:
     
    36533653        | '[' ']' multi_array_dimension
    36543654                { $$ = 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
    36563657                { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); }
    36573658                // { 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; }
    36583661        | multi_array_dimension
    36593662        ;
     3663
     3664array_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
     3677upupeq:
     3678        '~'
     3679                { $$ = OperKinds::LThan; }
     3680        | ErangeUpEq
     3681                { $$ = OperKinds::LEThan; }
     3682        ;
    36603683
    36613684multi_array_dimension:
     
    39904013//    declaration lists (not prototype-format parameter type and identifier declarators) is an obsolescent feature.
    39914014
    3992 //************************* MISCELLANEOUS ********************************
     4015// ************************ MISCELLANEOUS ********************************
    39934016
    39944017comma_opt:                                                                                              // redundant comma
  • src/ResolvExpr/CandidateFinder.cpp

    r7d9598d8 r2dcd80a  
    221221        ) {
    222222                for ( auto & tyvar : type->forall ) {
    223                         unifiableVars[ *tyvar ] = ast::TypeDecl::Data{ tyvar->base };
     223                        unifiableVars[ *tyvar ] = ast::TypeData{ tyvar->base };
    224224                }
    225225                for ( auto & assn : type->assertions ) {
  • src/ResolvExpr/FindOpenVars.cc

    r7d9598d8 r2dcd80a  
    113113                                if ( nextIsOpen ) {
    114114                                        for ( auto & decl : type->forall ) {
    115                                                 open[ *decl ] = ast::TypeDecl::Data{ decl->base };
     115                                                open[ *decl ] = ast::TypeData{ decl->base };
    116116                                        }
    117117                                        for ( auto & assert : type->assertions ) {
     
    120120                                } else {
    121121                                        for ( auto & decl : type->forall ) {
    122                                                 closed[ *decl ] = ast::TypeDecl::Data{ decl->base };   
     122                                                closed[ *decl ] = ast::TypeData{ decl->base };
    123123                                        }
    124124                                        for ( auto & assert : type->assertions ) {
  • src/ResolvExpr/RenameVars.cc

    r7d9598d8 r2dcd80a  
    4242                int next_usage_id = 1;
    4343                ScopedMap< std::string, std::string > nameMap;
    44                 ScopedMap< std::string, ast::TypeInstType::TypeEnvKey > idMap;
     44                ScopedMap< std::string, ast::TypeEnvKey > idMap;
    4545        public:
    4646                void reset() {
     
    121121                                        assert(false);
    122122                                }
    123                                 idMap[ td->name ] = ast::TypeInstType::TypeEnvKey(*mut);
    124                                
     123                                idMap[ td->name ] = ast::TypeEnvKey( *mut );
     124
    125125                                td = mut;
    126126                        }
  • src/ResolvExpr/Unify.cc

    r7d9598d8 r2dcd80a  
    11661166                        if ( entry1->second.kind != entry2->second.kind ) return false;
    11671167                        return env.bindVarToVar(
    1168                                 var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have,
     1168                                var1, var2, ast::TypeData{ entry1->second, entry2->second }, need, have,
    11691169                                open, widen, symtab );
    11701170                } else if ( isopen1 ) {
  • src/SynTree/Declaration.h

    r7d9598d8 r2dcd80a  
    340340        bool isTyped;
    341341        Type * base;
     342        enum EnumHiding { Visible, Hide } hide;
    342343
    343344        EnumDecl( const std::string & name,
     
    345346          bool isTyped = false, LinkageSpec::Spec linkage = LinkageSpec::Cforall,
    346347          Type * baseType = nullptr )
    347           : Parent( name, attributes, linkage ),isTyped(isTyped), base( baseType ) {}
     348          : Parent( name, attributes, linkage ), isTyped(isTyped), base( baseType ) {}
    348349        EnumDecl( const EnumDecl & other )
    349350          : Parent( other ), isTyped( other.isTyped), base( other.base ) {}
Note: See TracChangeset for help on using the changeset viewer.