Changeset 95b8aa7 for src/ResolvExpr


Ignore:
Timestamp:
Jan 11, 2019, 3:36:48 PM (7 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
Children:
e1f7eef
Parents:
ff5caaf (diff), 52ffa30 (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:

Pull fixes for deferred_resn from other branch

Location:
src/ResolvExpr
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Alternative.cc

    rff5caaf r95b8aa7  
    105105
    106106        Alternative::~Alternative() {
     107                for ( AssertionItem& n : need ) { delete n.decl; }
    107108                delete expr;
    108109        }
     
    119120                        os << "Null expression!" << std::endl;
    120121                } // if
    121                 os << indent << "Environment: ";
     122                os << indent << "Environment:";
    122123                env.print( os, indent+1 );
    123124                os << std::endl;
  • src/ResolvExpr/AlternativeFinder.cc

    rff5caaf r95b8aa7  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 23:52:08 2015
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Fri Oct -5 10:01:00 2018
    13 // Update Count     : 34
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Nov  1 21:00:56 2018
     13// Update Count     : 35
    1414//
    1515
     
    500500                                needAssertions[ *assert ].isUsed = true;
    501501                        }
    502 ///     needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() );
    503                 }
    504         }
    505 
    506 //      template< typename ForwardIterator, typename OutputIterator >
    507 //      void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) {
    508 //              if ( newAlt.cost == Cost::infinity ) return; // don't proceed down this dead end
    509 //              if ( begin == end ) {
    510 //                      if ( newNeed.empty() ) {
    511 //                              PRINT(
    512 //                                      std::cerr << "all assertions satisfied, output alternative: ";
    513 //                                      newAlt.print( std::cerr );
    514 //                                      std::cerr << std::endl;
    515 //                              );
    516 //                              *out++ = newAlt;
    517 //                              return;
    518 //                      } else if ( level >= recursionLimit ) {
    519 //                              SemanticError( newAlt.expr->location, "Too many recursive assertions" );
    520 //                      } else {
    521 //                              AssertionSet newerNeed;
    522 //                              PRINT(
    523 //                                      std::cerr << "recursing with new set:" << std::endl;
    524 //                                      printAssertionSet( newNeed, std::cerr, 8 );
    525 //                              )
    526 //                              inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
    527 //                              return;
    528 //                      }
    529 //              }
    530 
    531 //              ForwardIterator cur = begin++;
    532 //              if ( ! cur->second.isUsed ) {
    533 //                      inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
    534 //                      return; // xxx - should this continue? previously this wasn't here, and it looks like it should be
    535 //              }
    536 //              DeclarationWithType *curDecl = cur->first;
    537 
    538 //              PRINT(
    539 //                      std::cerr << "inferRecursive: assertion is ";
    540 //                      curDecl->print( std::cerr );
    541 //                      std::cerr << std::endl;
    542 //              )
    543 //              std::list< SymTab::Indexer::IdData > candidates;
    544 //              decls.lookupId( curDecl->get_name(), candidates );
    545 // ///   if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; }
    546 //              for ( const auto & data : candidates ) {
    547 //                      DeclarationWithType * candidate = data.id;
    548 //                      PRINT(
    549 //                              std::cerr << "inferRecursive: candidate is ";
    550 //                              candidate->print( std::cerr );
    551 //                              std::cerr << std::endl;
    552 //                      )
    553 
    554 //                      AssertionSet newHave, newerNeed( newNeed );
    555 //                      TypeEnvironment newEnv( newAlt.env );
    556 //                      OpenVarSet newOpenVars( openVars );
    557 //                      Type *adjType = candidate->get_type()->clone();
    558 //                      adjustExprType( adjType, newEnv, indexer );
    559 //                      renameTyVars( adjType );
    560 //                      PRINT(
    561 //                              std::cerr << "unifying ";
    562 //                              curDecl->get_type()->print( std::cerr );
    563 //                              std::cerr << " with ";
    564 //                              adjType->print( std::cerr );
    565 //                              std::cerr << std::endl;
    566 //                      )
    567 //                      if ( unify( curDecl->get_type(), adjType, newEnv, newerNeed, newHave, newOpenVars, indexer ) ) {
    568 //                              PRINT(
    569 //                                      std::cerr << "success!" << std::endl;
    570 //                              )
    571 //                              SymTab::Indexer newDecls( decls );
    572 //                              addToIndexer( newHave, newDecls );
    573 //                              Alternative newerAlt( newAlt );
    574 //                              newerAlt.env = newEnv;
    575 //                              assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
    576 
    577 //                              // everything with an empty idChain was pulled in by the current assertion.
    578 //                              // add current assertion's idChain + current assertion's ID so that the correct inferParameters can be found.
    579 //                              for ( auto & a : newerNeed ) {
    580 //                                      if ( a.second.idChain.empty() ) {
    581 //                                              a.second.idChain = cur->second.idChain;
    582 //                                              a.second.idChain.push_back( curDecl->get_uniqueId() );
    583 //                                      }
    584 //                              }
    585 
    586 //                              Expression *varExpr = data.combine( newerAlt.cvtCost );
    587 //                              delete varExpr->get_result();
    588 //                              varExpr->set_result( adjType->clone() );
    589 //                              PRINT(
    590 //                                      std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
    591 //                                      curDecl->print( std::cerr );
    592 //                                      std::cerr << " with declaration " << candidate->get_uniqueId() << " ";
    593 //                                      candidate->print( std::cerr );
    594 //                                      std::cerr << std::endl;
    595 //                              )
    596 //                              // follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter).
    597 //                              InferredParams * inferParameters = &newerAlt.expr->inferParams;
    598 //                              for ( UniqueId id : cur->second.idChain ) {
    599 //                                      inferParameters = (*inferParameters)[ id ].inferParams.get();
    600 //                              }
    601 //                              // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    602 //                              (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    603 //                              inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
    604 //                      } else {
    605 //                              delete adjType;
    606 //                      }
    607 //              }
    608 //      }
     502                }
     503        }
    609504
    610505        /// Unique identifier for matching expression resolutions to their requesting expression
     
    613508        template< typename OutputIterator >
    614509        void AlternativeFinder::Finder::inferParameters( Alternative &newAlt, OutputIterator out ) {
    615                 // SymTab::Indexer decls( indexer );
    616                 // addToIndexer( have, decls );
    617                 // AssertionSet newNeed;
    618                 // PRINT(
    619                 //      std::cerr << "env is: " << std::endl;
    620                 //      newAlt.env.print( std::cerr, 0 );
    621                 //      std::cerr << std::endl;
    622                 // )
    623 
    624                 // inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
    625 
    626510                // Set need bindings for any unbound assertions
    627511                UniqueId crntResnSlot = 0;  // matching ID for this expression's assertions
     
    13451229                                Alternative newAlt{
    13461230                                        restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ),
    1347                                         alt.env, openVars, needAssertions, alt.cost, thisCost };
     1231                                        alt.env, openVars, needAssertions, alt.cost + thisCost, thisCost };
    13481232                                inferParameters( newAlt, back_inserter( candidates ) );
    13491233                        } // if
     
    13731257                /// Gets name from untyped member expression (member must be NameExpr)
    13741258                const std::string& get_member_name( UntypedMemberExpr *memberExpr ) {
     1259                        if ( dynamic_cast< ConstantExpr * >( memberExpr->get_member() ) ) {
     1260                                SemanticError( memberExpr, "Indexed access to struct fields unsupported: " );
     1261                        } // if
    13751262                        NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() );
    13761263                        assert( nameExpr );
  • src/ResolvExpr/ConversionCost.cc

    rff5caaf r95b8aa7  
    2929namespace ResolvExpr {
    3030        const Cost Cost::zero =      Cost{  0,  0,  0,  0,  0,  0 };
    31         const Cost Cost::infinity =  Cost{ -1, -1, -1,  1, -1, -1 };
     31        const Cost Cost::infinity =  Cost{ -1, -1, -1, -1,  1, -1 };
    3232        const Cost Cost::unsafe =    Cost{  1,  0,  0,  0,  0,  0 };
    3333        const Cost Cost::poly =      Cost{  0,  1,  0,  0,  0,  0 };
    34         const Cost Cost::var =       Cost{  0,  0,  1,  0,  0,  0 };
    35         const Cost Cost::spec =      Cost{  0,  0,  0, -1,  0,  0 };
    36         const Cost Cost::safe =      Cost{  0,  0,  0,  0,  1,  0 };
     34        const Cost Cost::safe =      Cost{  0,  0,  1,  0,  0,  0 };
     35        const Cost Cost::var =       Cost{  0,  0,  0,  1,  0,  0 };
     36        const Cost Cost::spec =      Cost{  0,  0,  0,  0, -1,  0 };
    3737        const Cost Cost::reference = Cost{  0,  0,  0,  0,  0,  1 };
    3838
  • src/ResolvExpr/Cost.h

    rff5caaf r95b8aa7  
    2121        class Cost {
    2222          private:
    23                 Cost( int unsafeCost, int polyCost, int varCost, int specCost, int safeCost,
    24                       int referenceCost );
     23                Cost( int unsafeCost, int polyCost, int safeCost, int varCost, int specCost,
     24                        int referenceCost );
    2525
    2626          public:
    2727                Cost & incUnsafe( int inc = 1 );
    2828                Cost & incPoly( int inc = 1 );
     29                Cost & incSafe( int inc = 1 );
    2930                Cost & incVar( int inc = 1 );
    3031                Cost & decSpec( int inc = 1 );
    31                 Cost & incSafe( int inc = 1 );
    3232                Cost & incReference( int inc = 1 );
    3333
    3434                int get_unsafeCost() const { return unsafeCost; }
    3535                int get_polyCost() const { return polyCost; }
     36                int get_safeCost() const { return safeCost; }
    3637                int get_varCost() const { return varCost; }
    3738                int get_specCost() const { return specCost; }
    38                 int get_safeCost() const { return safeCost; }
    3939                int get_referenceCost() const { return referenceCost; }
    4040
     
    5454                static const Cost unsafe;
    5555                static const Cost poly;
     56                static const Cost safe;
    5657                static const Cost var;
    5758                static const Cost spec;
    58                 static const Cost safe;
    5959                static const Cost reference;
    6060
     
    6262                int unsafeCost;     ///< Unsafe (narrowing) conversions
    6363                int polyCost;       ///< Count of parameters and return values bound to some poly type
     64                int safeCost;       ///< Safe (widening) conversions
    6465                int varCost;        ///< Count of polymorphic type variables
    6566                int specCost;       ///< Polymorphic type specializations (type assertions), negative cost
    66                 int safeCost;       ///< Safe (widening) conversions
    6767                int referenceCost;  ///< reference conversions
    6868        };
    6969
    70         inline Cost::Cost( int unsafeCost, int polyCost, int varCost, int specCost, int safeCost,
     70        inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int varCost, int specCost,
    7171                        int referenceCost )
    72                 : unsafeCost( unsafeCost ), polyCost( polyCost ), varCost( varCost ), specCost( specCost ),
    73                   safeCost( safeCost ), referenceCost( referenceCost ) {}
     72                : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), varCost( varCost ),
     73                  specCost( specCost ), referenceCost( referenceCost ) {}
    7474
    7575        inline Cost & Cost::incUnsafe( int inc ) {
     
    8585        }
    8686
     87        inline Cost & Cost::incSafe( int inc ) {
     88                if ( *this == infinity ) return *this;
     89                safeCost += inc;
     90                return *this;
     91        }
     92
    8793        inline Cost & Cost::incVar( int inc ) {
    8894                if ( *this == infinity ) return *this;
     
    94100                if ( *this == infinity ) return *this;
    95101                specCost -= dec;
    96                 return *this;
    97         }
    98 
    99         inline Cost & Cost::incSafe( int inc ) {
    100                 if ( *this == infinity ) return *this;
    101                 safeCost += inc;
    102102                return *this;
    103103        }
     
    112112                if ( *this == infinity || other == infinity ) return infinity;
    113113                return Cost{
    114                         unsafeCost + other.unsafeCost, polyCost + other.polyCost,
     114                        unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost,
    115115                        varCost + other.varCost, specCost + other.specCost,
    116                         safeCost + other.safeCost, referenceCost + other.referenceCost };
     116                        referenceCost + other.referenceCost };
    117117        }
    118118
     
    120120                if ( *this == infinity || other == infinity ) return infinity;
    121121                return Cost{
    122                         unsafeCost - other.unsafeCost, polyCost - other.polyCost,
     122                        unsafeCost - other.unsafeCost, polyCost - other.polyCost, safeCost - other.safeCost,
    123123                        varCost - other.varCost, specCost - other.specCost,
    124                         safeCost - other.safeCost, referenceCost - other.referenceCost };
     124                        referenceCost - other.referenceCost };
    125125        }
    126126
     
    133133                unsafeCost += other.unsafeCost;
    134134                polyCost += other.polyCost;
     135                safeCost += other.safeCost;
    135136                varCost += other.varCost;
    136137                specCost += other.specCost;
    137                 safeCost += other.safeCost;
    138138                referenceCost += other.referenceCost;
    139139                return *this;
     
    152152                } else if ( polyCost < other.polyCost ) {
    153153                        return true;
     154                } else if ( safeCost > other.safeCost ) {
     155                        return false;
     156                } else if ( safeCost < other.safeCost ) {
     157                        return true;
    154158                } else if ( varCost > other.varCost ) {
    155159                        return false;
     
    159163                        return false;
    160164                } else if ( specCost > other.specCost ) {
    161                         return true;
    162                 } else if ( safeCost > other.safeCost ) {
    163                         return false;
    164                 } else if ( safeCost < other.safeCost ) {
    165165                        return true;
    166166                } else if ( referenceCost > other.referenceCost ) {
     
    179179                int c = unsafeCost - other.unsafeCost; if ( c ) return c;
    180180                c = polyCost - other.polyCost; if ( c ) return c;
     181                c = safeCost - other.safeCost; if ( c ) return c;
    181182                c = varCost - other.varCost; if ( c ) return c;
    182183                c = specCost - other.specCost; if ( c ) return c;
    183                 c = safeCost - other.safeCost; if ( c ) return c;
    184184                return referenceCost - other.referenceCost;
    185185        }
     
    188188                return unsafeCost == other.unsafeCost
    189189                        && polyCost == other.polyCost
     190                        && safeCost == other.safeCost
    190191                        && varCost == other.varCost
    191192                        && specCost == other.specCost
    192                         && safeCost == other.safeCost
    193193                        && referenceCost == other.referenceCost;
    194194        }
     
    200200        inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) {
    201201                return os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", "
    202                           << cost.varCost << ", " << cost.specCost << ", "
    203                           << cost.safeCost << ", " << cost.referenceCost << " )";
     202                          << cost.safeCost << ", " << cost.varCost << ", " << cost.specCost << ", "
     203                          << cost.referenceCost << " )";
    204204        }
    205205} // namespace ResolvExpr
  • src/ResolvExpr/ResolveAssertions.cc

    rff5caaf r95b8aa7  
    275275                                        std::move(newNeed), std::move(newOpenVars), crntResnSlot );
    276276                        } else {
    277                                 //delete adjType;
     277                                delete adjType;
    278278                        }
    279279                }
     
    396396                                                Cost resCost = coster.get( compat );
    397397                                                auto it = found.emplace( SymTab::Mangler::mangleType( resType ), resCost );
     398                                                delete resType;
    398399                                                if ( it.second == false && it.first->second < resCost ) continue;
    399400
  • src/ResolvExpr/ResolveTypeof.cc

    rff5caaf r95b8aa7  
    6767                std::cerr << std::endl;
    6868#endif
    69                 if ( typeofType->expr ) {
     69                // pass on null expression
     70                if ( ! typeofType->expr ) return typeofType;
     71
     72                bool isBasetypeof = typeofType->is_basetypeof;
     73                auto oldQuals = typeofType->get_qualifiers().val;
     74
     75                Type* newType;
     76                if ( TypeExpr* tyExpr = dynamic_cast<TypeExpr*>(typeofType->expr) ) {
     77                        // typeof wrapping type
     78                        newType = tyExpr->type;
     79                        tyExpr->type = nullptr;
     80                        delete tyExpr;
     81                } else {
     82                        // typeof wrapping expression
    7083                        Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer );
    7184                        assert( newExpr->result && ! newExpr->result->isVoid() );
    72                         Type * newType = newExpr->result;
     85                        newType = newExpr->result;
    7386                        newExpr->result = nullptr;
    7487                        delete typeofType;
    7588                        delete newExpr;
    76                         return newType;
    77                 } // if
    78                 return typeofType;
     89                }
     90
     91                // clear qualifiers for base, combine with typeoftype quals in any case
     92                if ( isBasetypeof ) {
     93                        // replace basetypeof(<enum>) by int
     94                        if ( dynamic_cast<EnumInstType*>(newType) ) {
     95                                Type* newerType =
     96                                        new BasicType{ newType->get_qualifiers(), BasicType::SignedInt,
     97                                        newType->attributes };
     98                                delete newType;
     99                                newType = newerType;
     100                        }
     101                        newType->get_qualifiers().val
     102                                = ( newType->get_qualifiers().val & ~Type::Qualifiers::Mask ) | oldQuals;
     103                } else {
     104                        newType->get_qualifiers().val |= oldQuals;
     105                }
     106               
     107                return newType;
    79108        }
    80109} // namespace ResolvExpr
Note: See TracChangeset for help on using the changeset viewer.