Changeset f80e0218 for src/ResolvExpr


Ignore:
Timestamp:
Jun 30, 2016, 4:32:56 PM (10 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, stuck-waitfor-destruct, with_gc
Children:
ea29e73
Parents:
1b5c81ed (diff), 84d4d6f (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' into gc_noraii

Conflicts:

Jenkinsfile
src/SymTab/Validate.cc

Location:
src/ResolvExpr
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r1b5c81ed rf80e0218  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 23:52:08 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Feb 10 17:00:04 2016
    13 // Update Count     : 24
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Jun 13 16:13:54 2016
     13// Update Count     : 25
    1414//
    1515
     
    1919#include <functional>
    2020#include <cassert>
     21#include <unordered_map>
     22#include <utility>
     23#include <vector>
    2124
    2225#include "AlternativeFinder.h"
     
    3942#include "Tuples/NameMatcher.h"
    4043#include "Common/utility.h"
     44#include "InitTweak/InitTweak.h"
    4145
    4246extern bool resolvep;
     
    407411        }
    408412
    409         static const int recursionLimit = 10;
     413        // /// Map of declaration uniqueIds (intended to be the assertions in an AssertionSet) to their parents and the number of times they've been included
     414        //typedef std::unordered_map< UniqueId, std::unordered_map< UniqueId, unsigned > > AssertionParentSet;
     415       
     416        static const int recursionLimit = /*10*/ 4;  ///< Limit to depth of recursion satisfaction
     417        //static const unsigned recursionParentLimit = 1;  ///< Limit to the number of times an assertion can recursively use itself
    410418
    411419        void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
     
    416424                }
    417425        }
    418 
     426       
    419427        template< typename ForwardIterator, typename OutputIterator >
    420         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 ) {
     428        void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, /*const AssertionParentSet &needParents,*/
     429                                                 int level, const SymTab::Indexer &indexer, OutputIterator out ) {
    421430                if ( begin == end ) {
    422431                        if ( newNeed.empty() ) {
     
    431440                                        printAssertionSet( newNeed, std::cerr, 8 );
    432441                                )
    433                                 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
     442                                inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, /*needParents,*/ level+1, indexer, out );
    434443                                return;
    435444                        }
     
    438447                ForwardIterator cur = begin++;
    439448                if ( ! cur->second ) {
    440                         inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
     449                        inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out );
    441450                }
    442451                DeclarationWithType *curDecl = cur->first;
     
    455464                                std::cerr << std::endl;
    456465                        )
     466                       
    457467                        AssertionSet newHave, newerNeed( newNeed );
    458468                        TypeEnvironment newEnv( newAlt.env );
     
    477487                                newerAlt.env = newEnv;
    478488                                assert( (*candidate)->get_uniqueId() );
    479                                 Expression *varExpr = new VariableExpr( static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ) );
     489                                DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) );
     490                                //AssertionParentSet newNeedParents( needParents );
     491                                // skip repeatingly-self-recursive assertion satisfaction
     492                                // DOESN'T WORK: grandchild nodes conflict with their cousins
     493                                //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
     494                                Expression *varExpr = new VariableExpr( candDecl );
    480495                                deleteAll( varExpr->get_results() );
    481496                                varExpr->get_results().clear();
     
    491506                                // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    492507                                appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    493                                 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
     508                                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
    494509                        } else {
    495510                                delete adjType;
     
    513528                addToIndexer( have, decls );
    514529                AssertionSet newNeed;
    515                 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
     530                //AssertionParentSet needParents;
     531                inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, /*needParents,*/ 0, indexer, out );
    516532//      PRINT(
    517533//          std::cerr << "declaration 14 is ";
     
    546562
    547563                {
    548                         NameExpr *fname = 0;;
    549                         if ( ( fname = dynamic_cast<NameExpr *>( untypedExpr->get_function()))
    550                                  && ( fname->get_name() == std::string("&&")) ) {
     564                        std::string fname = InitTweak::getFunctionName( untypedExpr );
     565                        if ( fname == "&&" ) {
    551566                                VoidType v = Type::Qualifiers();                // resolve to type void *
    552567                                PointerType pt( Type::Qualifiers(), v.clone() );
     
    757772                for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
    758773                        VariableExpr newExpr( *i, nameExpr->get_argName() );
     774                        newExpr.set_extension( nameExpr->get_extension() );
    759775                        alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
    760776                        PRINT(
     
    982998                } // for
    983999        }
     1000
     1001        void AlternativeFinder::visit( ImplicitCopyCtorExpr * impCpCtorExpr ) {
     1002                alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) );
     1003        }
    9841004} // namespace ResolvExpr
    9851005
  • src/ResolvExpr/AlternativeFinder.h

    r1b5c81ed rf80e0218  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // AlternativeFinder.h -- 
     7// AlternativeFinder.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 23:56:12 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May 16 23:58:43 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Apr 19 11:44:53 2016
    1313// Update Count     : 2
    14 // 
     14//
    1515
    1616#ifndef ALTERNATIVEFINDER_H
     
    5454                virtual void visit( NameExpr *variableExpr );
    5555                virtual void visit( VariableExpr *variableExpr );
    56                 virtual void visit( ConstantExpr *constantExpr ); 
     56                virtual void visit( ConstantExpr *constantExpr );
    5757                virtual void visit( SizeofExpr *sizeofExpr );
    5858                virtual void visit( AlignofExpr *alignofExpr );
     
    6565                virtual void visit( CommaExpr *commaExpr );
    6666                virtual void visit( TupleExpr *tupleExpr );
     67                virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr );
    6768          public:  // xxx - temporary hack - should make Tuples::TupleAssignment a friend
    6869                template< typename InputIterator, typename OutputIterator >
  • src/ResolvExpr/CommonType.cc

    r1b5c81ed rf80e0218  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CommonType.cc -- 
     7// CommonType.cc --
    88//
    99// Author           : Richard C. Bilson
     
    134134                                result = new BasicType( basicType->get_qualifiers() + otherBasic->get_qualifiers(), newType );
    135135                        } // if
     136                } else if ( EnumInstType *enumInstType = dynamic_cast< EnumInstType * > ( type2 ) ) {
     137                        // use signed int in lieu of the enum type
     138                        BasicType::Kind newType = combinedType[ basicType->get_kind() ][ BasicType::SignedInt ];
     139                        if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= enumInstType->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= enumInstType->get_qualifiers() ) || widenSecond ) ) {
     140                                result = new BasicType( basicType->get_qualifiers() + enumInstType->get_qualifiers(), newType );
     141                        } // if
    136142                } // if
    137143        }
     
    183189        }
    184190
    185         void CommonType::visit( EnumInstType *aggregateUseType ) {
     191        void CommonType::visit( EnumInstType *enumInstType ) {
     192                if ( dynamic_cast< BasicType * >( type2 ) ) {
     193                        // reuse BasicType, EnumInstType code by swapping type2 with enumInstType
     194                        Type * temp = type2;
     195                        type2 = enumInstType;
     196                        temp->accept( *this );
     197                        type2 = temp;
     198                } // if
    186199        }
    187200
  • src/ResolvExpr/ConversionCost.cc

    r1b5c81ed rf80e0218  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ConversionCost.cc -- 
     7// ConversionCost.cc --
    88//
    99// Author           : Richard C. Bilson
     
    157157                                cost = Cost( 0, 0, tableResult );
    158158                        } // if
    159                 } // if
     159                } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
     160                        // xxx - not positive this is correct, but appears to allow casting int => enum
     161                        cost = Cost( 1, 0, 0 );
     162    } // if
    160163        }
    161164
  • src/ResolvExpr/RenameVars.cc

    r1b5c81ed rf80e0218  
    4545        void RenameVars::visit( PointerType *pointerType ) {
    4646                typeBefore( pointerType );
    47 ///   std::cout << "do pointer" << std::endl;
    4847                maybeAccept( pointerType->get_base(), *this );
    49 ///   std::cout << "done pointer" << std::endl;
    5048                typeAfter( pointerType );
    5149        }
     
    6058        void RenameVars::visit( FunctionType *functionType ) {
    6159                typeBefore( functionType );
    62 ///   std::cout << "return vals" << std::endl;
    6360                acceptAll( functionType->get_returnVals(), *this );
    64 ///   std::cout << functionType->get_parameters().size() << " parameters" << std::endl;
    6561                acceptAll( functionType->get_parameters(), *this );
    66 ///   std::cout << "done function" << std::endl;
    6762                typeAfter( functionType );
    6863        }
     
    9590        void RenameVars::visit( TypeInstType *instType ) {
    9691                typeBefore( instType );
    97 ///   std::cout << "instance of type " << instType->get_name() << std::endl;
    9892                std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->get_name() );
    9993                if ( i != mapStack.front().end() ) {
    100 ///     std::cout << "found name " << i->second << std::endl;
    10194                        instType->set_name( i->second );
    10295                } else {
    103 ///     std::cout << "no name found" << std::endl;
    10496                } // if
    10597                acceptAll( instType->get_parameters(), *this );
     
    120112        void RenameVars::typeBefore( Type *type ) {
    121113                if ( ! type->get_forall().empty() ) {
    122 ///     std::cout << "type with forall: ";
    123 ///     type->print( std::cout );
    124 ///     std::cout << std::endl;
    125114                        // copies current name mapping into new mapping
    126115                        mapStack.push_front( mapStack.front() );
  • src/ResolvExpr/Resolver.cc

    r1b5c81ed rf80e0218  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Resolver.cc -- 
     7// Resolver.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:17:01 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 24 16:43:11 2016
    13 // Update Count     : 181
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Fri May 13 11:36:40 2016
     13// Update Count     : 203
    1414//
    1515
     
    2525#include "SymTab/Indexer.h"
    2626#include "Common/utility.h"
     27#include "InitTweak/InitTweak.h"
    2728
    2829#include <iostream>
     
    3334          public:
    3435                Resolver() : SymTab::Indexer( false ), switchType( 0 ) {}
    35  
     36
    3637                virtual void visit( FunctionDecl *functionDecl );
    3738                virtual void visit( ObjectDecl *functionDecl );
    3839                virtual void visit( TypeDecl *typeDecl );
     40                virtual void visit( EnumDecl * enumDecl );
    3941
    4042                virtual void visit( ArrayType * at );
     
    5153                virtual void visit( BranchStmt *branchStmt );
    5254                virtual void visit( ReturnStmt *returnStmt );
     55                virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt );
    5356
    5457                virtual void visit( SingleInit *singleInit );
    5558                virtual void visit( ListInit *listInit );
     59                virtual void visit( ConstructorInit *ctorInit );
    5660          private:
    5761        typedef std::list< Initializer * >::iterator InitIterator;
     
    5963          void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & );
    6064          void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & );
    61 
     65          void fallbackInit( ConstructorInit * ctorInit );
    6266                std::list< Type * > functionReturn;
    6367                Type *initContext;
    6468                Type *switchType;
     69                bool inEnumDecl = false;
    6570        };
    6671
     
    8287        }
    8388
     89
    8490        namespace {
    8591                void finishExpr( Expression *expr, const TypeEnvironment &env ) {
     
    8793                        env.makeSubstitution( *expr->get_env() );
    8894                }
    89 
    90                 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    91                         global_renamer.reset();
    92                         TypeEnvironment env;
    93                         Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
    94                         finishExpr( newExpr, env );
    95                         return newExpr;
    96                 }
    97  
     95        } // namespace
     96
     97        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     98                global_renamer.reset();
     99                TypeEnvironment env;
     100                Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
     101                finishExpr( newExpr, env );
     102                return newExpr;
     103        }
     104
     105        namespace {
    98106                Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    99107                        TypeEnvironment env;
     
    126134                        } // if
    127135                }
    128  
     136
    129137                Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    130138                        TypeEnvironment env;
     
    159167                        return newExpr;
    160168                }
    161  
    162         }
    163  
     169
     170        }
     171
    164172        void Resolver::visit( ObjectDecl *objectDecl ) {
    165173                Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
     
    172180                Type *temp = initContext;
    173181                initContext = new_type;
     182                if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     183                        // enumerator initializers should not use the enum type to initialize, since
     184                        // the enum type is still incomplete at this point. Use signed int instead.
     185                        initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt );
     186                }
    174187                SymTab::Indexer::visit( objectDecl );
     188                if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     189                        // delete newly created signed int type
     190                        delete initContext;
     191                }
    175192                initContext = temp;
    176193        }
     
    212229        }
    213230
     231        void Resolver::visit( EnumDecl * enumDecl ) {
     232                // in case we decide to allow nested enums
     233                bool oldInEnumDecl = inEnumDecl;
     234                inEnumDecl = true;
     235                SymTab::Indexer::visit( enumDecl );
     236                inEnumDecl = oldInEnumDecl;
     237        }
     238
    214239        void Resolver::visit( ExprStmt *exprStmt ) {
    215240                if ( exprStmt->get_expr() ) {
     
    258283                        forStmt->set_condition( newExpr );
    259284                } // if
    260                
     285
    261286                if ( forStmt->get_increment() ) {
    262287                        Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this );
     
    272297                delete switchStmt->get_condition();
    273298                switchStmt->set_condition( newExpr );
    274  
     299
    275300                visitor.Visitor::visit( switchStmt );
    276301        }
     
    314339        bool isCharType( T t ) {
    315340                if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
    316                         return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || 
     341                        return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
    317342                                bt->get_kind() == BasicType::UnsignedChar;
    318343                }
     
    326351                                string n = ne->get_name();
    327352                                if (n == "0") {
    328                                         initContext = new BasicType(Type::Qualifiers(), 
     353                                        initContext = new BasicType(Type::Qualifiers(),
    329354                                                                                                BasicType::SignedInt);
    330355                                } else {
     
    332357                                        initContext = decl->get_type();
    333358                                }
    334                         } else if (ConstantExpr * e = 
     359                        } else if (ConstantExpr * e =
    335360                                           dynamic_cast<ConstantExpr*>(singleInit->get_value())) {
    336361                                Constant *c = e->get_constant();
     
    355380                                                        singleInit->set_value( ce->get_arg() );
    356381                                                        ce->set_arg( NULL );
    357                                                         delete ce;                                                                     
     382                                                        delete ce;
    358383                                                }
    359384                                        }
     
    471496#endif
    472497        }
     498
     499        // ConstructorInit - fall back on C-style initializer
     500        void Resolver::fallbackInit( ConstructorInit * ctorInit ) {
     501                // could not find valid constructor, or found an intrinsic constructor
     502                // fall back on C-style initializer
     503                delete ctorInit->get_ctor();
     504                ctorInit->set_ctor( NULL );
     505                delete ctorInit->get_dtor();
     506                ctorInit->set_dtor( NULL );
     507                maybeAccept( ctorInit->get_init(), *this );
     508        }
     509
     510        void Resolver::visit( ConstructorInit *ctorInit ) {
     511                try {
     512                        maybeAccept( ctorInit->get_ctor(), *this );
     513                        maybeAccept( ctorInit->get_dtor(), *this );
     514                } catch ( SemanticError ) {
     515                        // no alternatives for the constructor initializer - fallback on C-style initializer
     516                        // xxx - not sure if this makes a ton of sense - should maybe never be able to have this situation?
     517                        fallbackInit( ctorInit );
     518                        return;
     519                }
     520
     521                // found a constructor - can get rid of C-style initializer
     522                delete ctorInit->get_init();
     523                ctorInit->set_init( NULL );
     524
     525                // intrinsic single parameter constructors and destructors do nothing. Since this was
     526                // implicitly generated, there's no way for it to have side effects, so get rid of it
     527                // to clean up generated code.
     528                if ( InitTweak::isInstrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {
     529                        delete ctorInit->get_ctor();
     530                        ctorInit->set_ctor( NULL );
     531                }
     532                if ( InitTweak::isInstrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {
     533                        delete ctorInit->get_dtor();
     534                        ctorInit->set_dtor( NULL );
     535                }
     536        }
     537
     538        void Resolver::visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) {
     539                // before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed).
     540                // Do this through a cast expression to greatly simplify the code.
     541                Expression * callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt );
     542                assert( callExpr );
     543                Expression *& constructee = InitTweak::getCallArg( callExpr, 0 );
     544                Type * type = 0;
     545
     546                // need to find the type of the first argument, which is unfortunately not uniform since array construction
     547                // includes an untyped '+' expression.
     548                if ( UntypedExpr * plusExpr = dynamic_cast< UntypedExpr * >( constructee ) ) {
     549                        // constructee is <array>+<index>
     550                        // get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed
     551                        Expression * arr = InitTweak::getCallArg( plusExpr, 0 );
     552                        assert( dynamic_cast< VariableExpr * >( arr ) );
     553                        assert( arr && arr->get_results().size() == 1 );
     554                        type = arr->get_results().front()->clone();
     555                } else {
     556                        // otherwise, constructing a plain object, which means the object's address is being taken.
     557                        // Need to get the type of the VariableExpr object, because the AddressExpr is rebuilt and uses the
     558                        // type of the VariableExpr to do so.
     559                        assert( constructee->get_results().size() == 1 );
     560                        AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
     561                        assert( addrExpr && addrExpr->get_results().size() == 1);
     562                        type = addrExpr->get_results().front()->clone();
     563                }
     564                // cast to T* with qualifiers removed.
     565                // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     566                // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     567                // remove lvalue as a qualifier, this can change to
     568                //   type->get_qualifiers() = Type::Qualifiers();
     569                Type * base = InitTweak::getPointerBase( type );
     570                assert( base );
     571                base->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
     572                // if pointer has lvalue qualifier, cast won't appear in output
     573                type->set_isLvalue( false );
     574                constructee = new CastExpr( constructee, type );
     575
     576                // finally, resolve the ctor/dtor
     577                impCtorDtorStmt->get_callStmt()->accept( *this );
     578        }
    473579} // namespace ResolvExpr
    474580
  • src/ResolvExpr/Resolver.h

    r1b5c81ed rf80e0218  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Resolver.h -- 
     7// Resolver.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:18:34 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 17 12:19:32 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:06:53 2016
    1313// Update Count     : 2
    1414//
     
    2424        void resolve( std::list< Declaration * > translationUnit );
    2525        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
     26        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer );
    2627} // namespace ResolvExpr
    2728
  • src/ResolvExpr/typeops.h

    r1b5c81ed rf80e0218  
    5454 
    5555        // in AdjustExprType.cc
     56        /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function
    5657        void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    5758
Note: See TracChangeset for help on using the changeset viewer.