Changeset aa8f9df for src/ResolvExpr


Ignore:
Timestamp:
Sep 15, 2016, 3:22:50 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
4ab9536
Parents:
fd782b2 (diff), 906e24d (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 'replace-results-list' into tuples

Conflicts:

src/ResolvExpr/AlternativeFinder.cc
src/SymTab/Indexer.cc
src/SynTree/Mutator.cc
src/SynTree/Visitor.cc
src/Tuples/TupleAssignment.cc
src/Tuples/TupleAssignment.h

Location:
src/ResolvExpr
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified src/ResolvExpr/Alternative.cc

    rfd782b2 raa8f9df  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Alternative.cc -- 
     7// Alternative.cc --
    88//
    99// Author           : Richard C. Bilson
     
    1212// Last Modified On : Sat May 16 23:54:23 2015
    1313// Update Count     : 2
    14 // 
     14//
    1515
    1616#include "Alternative.h"
     
    5454                        expr->print( os, indent );
    5555                        os << "(types:" << std::endl;
    56                         printAll( expr->get_results(), os, indent + 4 );
    57                         os << ")" << std::endl;
     56                        os << std::string( indent+4, ' ' );
     57                        expr->get_result()->print( os, indent + 4 );
     58                        os << std::endl << ")" << std::endl;
    5859                } else {
    5960                        os << "Null expression!" << std::endl;
  • TabularUnified src/ResolvExpr/AlternativeFinder.cc

    rfd782b2 raa8f9df  
    100100                                PruneStruct current( candidate );
    101101                                std::string mangleName;
    102                                 for ( std::list< Type* >::const_iterator retType = candidate->expr->get_results().begin(); retType != candidate->expr->get_results().end(); ++retType ) {
    103                                         Type *newType = (*retType)->clone();
     102                                {
     103                                        Type * newType = candidate->expr->get_result()->clone();
    104104                                        candidate->env.apply( newType );
    105                                         mangleName += SymTab::Mangler::mangle( newType );
     105                                        mangleName = SymTab::Mangler::mangle( newType );
    106106                                        delete newType;
    107107                                }
     
    132132                                if ( ! target->second.isAmbiguous ) {
    133133                                        Alternative &alt = *target->second.candidate;
    134                                         for ( std::list< Type* >::iterator result = alt.expr->get_results().begin(); result != alt.expr->get_results().end(); ++result ) {
    135                                                 alt.env.applyFree( *result );
    136                                         }
     134                                        alt.env.applyFree( alt.expr->get_result() );
    137135                                        *out++ = alt;
    138136                                }
    139137                        }
    140 
    141138                }
    142139
     
    149146
    150147                void renameTypes( Expression *expr ) {
    151                         for ( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
    152                                 (*i)->accept( global_renamer );
    153                         }
    154                 }
    155 
    156                 // flatten tuple type into list of types
    157                 template< typename OutputIterator >
    158                 void flatten( Type * type, OutputIterator out ) {
    159                         if ( TupleType * tupleType = dynamic_cast< TupleType * >( type ) ) {
    160                                 for ( Type * t : *tupleType ) {
    161                                         flatten( t, out );
    162                                 }
    163                         } else {
    164                                 *out++ = type;
    165                         }
     148                        expr->get_result()->accept( global_renamer );
    166149                }
    167150        }
     
    195178                for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
    196179                        if ( adjust ) {
    197                                 adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );
     180                                adjustExprType( i->expr->get_result(), i->env, indexer );
    198181                        }
    199182                }
     
    265248        Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
    266249                ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
    267                 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
     250                PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    268251                FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
    269252
     
    282265                                (*actualExpr)->print( std::cerr, 8 );
    283266                                std::cerr << "--- results are" << std::endl;
    284                                 printAll( (*actualExpr)->get_results(), std::cerr, 8 );
     267                                (*actualExpr)->get_result()->print( std::cerr, 8 );
    285268                        )
    286269                        std::list< DeclarationWithType* >::iterator startFormal = formal;
    287270                        Cost actualCost;
    288                         for ( std::list< Type* >::iterator actualType = (*actualExpr)->get_results().begin(); actualType != (*actualExpr)->get_results().end(); ++actualType ) {
     271                        std::list< Type * > flatActualTypes;
     272                        flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) );
     273                        for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) {
     274
    289275
    290276                                // tuple handling code
     
    399385
    400386                for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    401                         std::list< Type* > & actualTypes = actualExpr->expr->get_results();
    402                         for ( std::list< Type* >::iterator actualType = actualTypes.begin(); actualType != actualTypes.end(); ++actualType ) {
     387                        std::list< Type * > flatActualTypes;
     388                        flatten( actualExpr->expr->get_result(), back_inserter( flatActualTypes ) );
     389                        for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType, ++formalType ) {
    403390                                if ( formalType == formalTypes.end() ) {
    404391                                        // the type of the formal parameter may be a tuple type. To make this easier to work with,
     
    416403                                PRINT(
    417404                                        std::cerr << "formal type is ";
    418                                         (*formal)->get_type()->print( std::cerr );
     405                                        (*formalType)->print( std::cerr );
    419406                                        std::cerr << std::endl << "actual type is ";
    420407                                        (*actualType)->print( std::cerr );
     
    424411                                        return false;
    425412                                }
    426                                 ++formalType;
    427413                        }
    428414                }
     
    532518                                //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
    533519                                Expression *varExpr = new VariableExpr( candDecl );
    534                                 deleteAll( varExpr->get_results() );
    535                                 varExpr->get_results().clear();
    536                                 varExpr->get_results().push_front( adjType->clone() );
     520                                delete varExpr->get_result();
     521                                varExpr->set_result( adjType->clone() );
    537522                                PRINT(
    538523                                        std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
     
    606591                                PointerType pt( Type::Qualifiers(), v.clone() );
    607592                                UntypedExpr *vexpr = untypedExpr->clone();
    608                                 vexpr->get_results().push_front( pt.clone() );
     593                                vexpr->set_result( pt.clone() );
    609594                                alternatives.push_back( Alternative( vexpr, env, Cost()) );
    610595                                return;
     
    634619                                // check if the type is pointer to function
    635620                                PointerType *pointer;
    636                                 if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
     621                                if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) {
    637622                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    638623                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    670655                                                // check if the type is pointer to function
    671656                                                PointerType *pointer;
    672                                                 if ( funcOp->expr->get_results().size() == 1
    673                                                         && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
     657                                                if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) {
    674658                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    675659                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    696680                        PRINT(
    697681                                ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( withFunc->expr );
    698                                 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
     682                                PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    699683                                FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
    700684                                std::cerr << "Case +++++++++++++" << std::endl;
     
    719703
    720704        bool isLvalue( Expression *expr ) {
    721                 for ( std::list< Type* >::const_iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
    722                         if ( !(*i)->get_isLvalue() ) return false;
    723                 } // for
    724                 return true;
     705                // xxx - recurse into tuples?
     706                return expr->has_result() && expr->get_result()->get_isLvalue();
    725707        }
    726708
     
    736718
    737719        void AlternativeFinder::visit( CastExpr *castExpr ) {
    738                 for ( std::list< Type* >::iterator i = castExpr->get_results().begin(); i != castExpr->get_results().end(); ++i ) {
    739                         *i = resolveTypeof( *i, indexer );
    740                         SymTab::validateType( *i, &indexer );
    741                         adjustExprType( *i, env, indexer );
    742                 } // for
     720                Type *& toType = castExpr->get_result();
     721                toType = resolveTypeof( toType, indexer );
     722                SymTab::validateType( toType, &indexer );
     723                adjustExprType( toType, env, indexer );
    743724
    744725                AlternativeFinder finder( indexer, env );
     
    754735                        // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    755736                        // to.
    756                         int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size();
     737                        int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size();
    757738                        if ( discardedValues < 0 ) continue;
    758                         std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin();
    759                         std::advance( candidate_end, castExpr->get_results().size() );
     739                        // xxx - may need to go into tuple types and extract relavent types and use unifyList
    760740                        // unification run for side-effects
    761                         unifyList( castExpr->get_results().begin(), castExpr->get_results().end(),
    762                                            (*i).expr->get_results().begin(), candidate_end,
    763                                    i->env, needAssertions, haveAssertions, openVars, indexer );
    764                         Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end,
    765                                                                                   castExpr->get_results().begin(), castExpr->get_results().end(),
    766                                                                                   indexer, i->env );
     741                        unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );
     742                        Cost thisCost = castCost( (*i).expr->get_result(), castExpr->get_result(), indexer, i->env );
    767743                        if ( thisCost != Cost::infinity ) {
    768744                                // count one safe conversion for each value that is thrown away
     
    787763
    788764                for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
    789                         if ( agg->expr->get_results().size() == 1 ) {
    790                                 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) {
    791                                         addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    792                                 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) {
    793                                         addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    794                                 } // if
     765                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() ) ) {
     766                                addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
     767                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) {
     768                                addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    795769                        } // if
    796770                } // for
     
    923897                        alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
    924898                        for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
    925                                 alternatives.back().expr->get_results().push_back( (*i)->get_type()->clone() );
     899                                alternatives.back().expr->set_result( (*i)->get_type()->clone() );
    926900                        } // for
    927901                } // if
     
    946920                                                        finder.find( attrExpr->get_expr() );
    947921                                                        for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
    948                                                                 if ( choice->expr->get_results().size() == 1 ) {
    949                                                                         resolveAttr(*i, function, choice->expr->get_results().front(), choice->env );
     922                                                                if ( choice->expr->get_result()->size() == 1 ) {
     923                                                                        resolveAttr(*i, function, choice->expr->get_result(), choice->env );
    950924                                                                } // fi
    951925                                                        } // for
     
    989963                                        AssertionSet needAssertions, haveAssertions;
    990964                                        Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost );
    991                                         std::list< Type* > commonTypes;
    992                                         if ( unifyList( second->expr->get_results().begin(), second->expr->get_results().end(), third->expr->get_results().begin(), third->expr->get_results().end(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
     965                                        Type* commonType;
     966                                        if ( unify( second->expr->get_result(), third->expr->get_result(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    993967                                                ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
    994                                                 std::list< Type* >::const_iterator original = second->expr->get_results().begin();
    995                                                 std::list< Type* >::const_iterator commonType = commonTypes.begin();
    996                                                 for ( ; original != second->expr->get_results().end() && commonType != commonTypes.end(); ++original, ++commonType ) {
    997                                                         if ( *commonType ) {
    998                                                                 newExpr->get_results().push_back( *commonType );
    999                                                         } else {
    1000                                                                 newExpr->get_results().push_back( (*original)->clone() );
    1001                                                         } // if
    1002                                                 } // for
     968                                                newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() );
    1003969                                                newAlt.expr = newExpr;
    1004970                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     
    1028994                        TupleExpr *newExpr = new TupleExpr;
    1029995                        makeExprList( *i, newExpr->get_exprs() );
    1030                         for ( std::list< Expression* >::const_iterator resultExpr = newExpr->get_exprs().begin(); resultExpr != newExpr->get_exprs().end(); ++resultExpr ) {
    1031                                 for ( std::list< Type* >::const_iterator resultType = (*resultExpr)->get_results().begin(); resultType != (*resultExpr)->get_results().end(); ++resultType ) {
    1032                                         newExpr->get_results().push_back( (*resultType)->clone() );
    1033                                 } // for
     996                        TupleType *tupleType = new TupleType( Type::Qualifiers(true, true, true, true, true, true) );
     997                        Type::Qualifiers &qualifiers = tupleType->get_qualifiers();
     998                        for ( Expression * resultExpr : newExpr->get_exprs() ) {
     999                                Type * type = resultExpr->get_result()->clone();
     1000                                tupleType->get_types().push_back( type );
     1001                                qualifiers &= type->get_qualifiers();
    10341002                        } // for
     1003                        newExpr->set_result( tupleType );
    10351004
    10361005                        TypeEnvironment compositeEnv;
     
    10571026                alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
    10581027        }
     1028
     1029        void AlternativeFinder::visit( TupleAssignExpr *tupleAssignExpr ) {
     1030                alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) );
     1031        }
    10591032} // namespace ResolvExpr
    10601033
  • TabularUnified src/ResolvExpr/AlternativeFinder.h

    rfd782b2 raa8f9df  
    6868                virtual void visit( ConstructorExpr * ctorExpr );
    6969                virtual void visit( TupleIndexExpr *tupleExpr );
     70                virtual void visit( TupleAssignExpr *tupleExpr );
    7071                /// Runs a new alternative finder on each element in [begin, end)
    7172                /// and writes each alternative finder to out.
  • TabularUnified src/ResolvExpr/AlternativePrinter.cc

    rfd782b2 raa8f9df  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // AlternativePrinter.cc -- 
     7// AlternativePrinter.cc --
    88//
    99// Author           : Richard C. Bilson
     
    3333                for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    3434                        os << "Alternative " << count++ << " ==============" << std::endl;
    35                         printAll( i->expr->get_results(), os );
     35                        i->expr->get_result()->print( os );
    3636                        //    i->print( os );
    3737                        os << std::endl;
  • TabularUnified src/ResolvExpr/ResolveTypeof.cc

    rfd782b2 raa8f9df  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ResolveTypeof.cc -- 
     7// ResolveTypeof.cc --
    88//
    99// Author           : Richard C. Bilson
     
    5858                if ( typeofType->get_expr() ) {
    5959                        Expression *newExpr = resolveInVoidContext( typeofType->get_expr(), indexer );
    60                         assert( newExpr->get_results().size() > 0 );
    61                         Type *newType;
    62                         if ( newExpr->get_results().size() > 1 ) {
    63                                 TupleType *tupleType = new TupleType( Type::Qualifiers() );
    64                                 cloneAll( newExpr->get_results(), tupleType->get_types() );
    65                                 newType = tupleType;
    66                         } else {
    67                                 newType = newExpr->get_results().front()->clone();
    68                         } // if
     60                        assert( newExpr->has_result() && ! newExpr->get_result()->isVoid() );
     61                        Type *newType = newExpr->get_result();
    6962                        delete typeofType;
    7063                        return newType;
  • TabularUnified src/ResolvExpr/Resolver.cc

    rfd782b2 raa8f9df  
    1919#include "RenameVars.h"
    2020#include "ResolveTypeof.h"
     21#include "typeops.h"
    2122#include "SynTree/Statement.h"
    2223#include "SynTree/Type.h"
     
    6768          void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & );
    6869          void fallbackInit( ConstructorInit * ctorInit );
    69                 std::list< Type * > functionReturn;
     70                Type * functionReturn;
    7071                Type *initContext;
    7172                Type *switchType;
     
    155156                        const TypeEnvironment *newEnv = 0;
    156157                        for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    157                                 if ( i->expr->get_results().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) {
     158                                if ( i->expr->get_result()->size() == 1 && isIntegralType( i->expr->get_result() ) ) {
    158159                                        if ( newExpr ) {
    159160                                                throw SemanticError( "Too many interpretations for case control expression", untyped );
     
    232233                Type *new_type = resolveTypeof( functionDecl->get_type(), *this );
    233234                functionDecl->set_type( new_type );
    234                 std::list< Type * > oldFunctionReturn = functionReturn;
    235                 functionReturn.clear();
    236                 for ( std::list< DeclarationWithType * >::const_iterator i = functionDecl->get_functionType()->get_returnVals().begin(); i != functionDecl->get_functionType()->get_returnVals().end(); ++i ) {
    237                         functionReturn.push_back( (*i)->get_type() );
    238                 } // for
     235                ValueGuard< Type * > oldFunctionReturn( functionReturn );
     236                functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() );
    239237                SymTab::Indexer::visit( functionDecl );
    240                 functionReturn = oldFunctionReturn;
    241238        }
    242239
     
    336333        void Resolver::visit( ReturnStmt *returnStmt ) {
    337334                if ( returnStmt->get_expr() ) {
    338                         CastExpr *castExpr = new CastExpr( returnStmt->get_expr() );
    339                         cloneAll( functionReturn, castExpr->get_results() );
     335                        CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() );
    340336                        Expression *newExpr = findSingleExpression( castExpr, *this );
    341337                        delete castExpr;
     
    382378                                if ( isCharType( at->get_base() ) ) {
    383379                                        // check if the resolved type is char *
    384                                         if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_results().front() ) ) {
     380                                        if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
    385381                                                if ( isCharType( pt->get_base() ) ) {
    386382                                                        // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
  • TabularUnified src/ResolvExpr/Unify.cc

    rfd782b2 raa8f9df  
    588588        }
    589589
     590        // xxx - compute once and store in the FunctionType?
     591        Type * extractResultType( FunctionType * function ) {
     592                if ( function->get_returnVals().size() == 0 ) {
     593                        return new VoidType( Type::Qualifiers() );
     594                } else if ( function->get_returnVals().size() == 1 ) {
     595                        return function->get_returnVals().front()->get_type()->clone();
     596                } else {
     597                        TupleType * tupleType = new TupleType( Type::Qualifiers() );
     598                        for ( DeclarationWithType * decl : function->get_returnVals() ) {
     599                                tupleType->get_types().push_back( decl->get_type()->clone() );
     600                        } // for
     601                        return tupleType;
     602                }
     603        }
     604
    590605} // namespace ResolvExpr
    591606
  • TabularUnified src/ResolvExpr/typeops.h

    rfd782b2 raa8f9df  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // typeops.h -- 
     7// typeops.h --
    88//
    99// Author           : Richard C. Bilson
     
    3030                typedef typename InputIterator::value_type SetType;
    3131                typedef typename std::list< typename SetType::value_type > ListType;
    32  
     32
    3333                if ( begin == end )     {
    3434                        *out++ = ListType();
    3535                        return;
    3636                } // if
    37  
     37
    3838                InputIterator current = begin;
    3939                begin++;
     
    4141                std::list< ListType > recursiveResult;
    4242                combos( begin, end, back_inserter( recursiveResult ) );
    43  
     43
    4444                for ( typename std::list< ListType >::const_iterator i = recursiveResult.begin(); i != recursiveResult.end(); ++i ) {
    4545                        for ( typename ListType::const_iterator j = current->begin(); j != current->end(); ++j ) {
     
    5252                } // for
    5353        }
    54  
     54
    5555        // in AdjustExprType.cc
    5656        /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function
     
    144144        }
    145145
     146        /// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value.
     147        Type * extractResultType( FunctionType * functionType );
     148
    146149        // in CommonType.cc
    147150        Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
     
    152155        // in Occurs.cc
    153156        bool occurs( Type *type, std::string varName, const TypeEnvironment &env );
     157
     158        // flatten tuple type into list of types
     159        template< typename OutputIterator >
     160        void flatten( Type * type, OutputIterator out ) {
     161                if ( TupleType * tupleType = dynamic_cast< TupleType * >( type ) ) {
     162                        for ( Type * t : tupleType->get_types() ) {
     163                                flatten( t, out );
     164                        }
     165                } else {
     166                        *out++ = type;
     167                }
     168        }
    154169} // namespace ResolvExpr
    155170
Note: See TracChangeset for help on using the changeset viewer.