Changeset a2d4d1c


Ignore:
Timestamp:
Sep 26, 2017, 10:15:38 AM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
19c43b7
Parents:
4dfa562 (diff), a139c11 (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:
6 deleted
24 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r4dfa562 ra2d4d1c  
    443443        void CodeGenerator::postvisit( UntypedExpr * untypedExpr ) {
    444444                extension( untypedExpr );
    445                 if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
     445                if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->function ) ) {
    446446                        OperatorInfo opInfo;
    447                         if ( operatorLookup( nameExpr->get_name(), opInfo ) ) {
    448                                 std::list< Expression* >::iterator arg = untypedExpr->get_args().begin();
     447                        if ( operatorLookup( nameExpr->name, opInfo ) ) {
     448                                std::list< Expression* >::iterator arg = untypedExpr->args.begin();
    449449                                switch ( opInfo.type ) {
    450450                                  case OT_INDEX:
    451                                         assert( untypedExpr->get_args().size() == 2 );
     451                                        assert( untypedExpr->args.size() == 2 );
    452452                                        (*arg++)->accept( *visitor );
    453453                                        output << "[";
     
    461461                                  case OT_CTOR:
    462462                                  case OT_DTOR:
    463                                         if ( untypedExpr->get_args().size() == 1 ) {
     463                                        if ( untypedExpr->args.size() == 1 ) {
    464464                                                // the expression fed into a single parameter constructor or destructor may contain side
    465465                                                // effects, so must still output this expression
     
    480480                                                (*arg++)->accept( *visitor );
    481481                                                output << opInfo.symbol << "{ ";
    482                                                 genCommaList( arg, untypedExpr->get_args().end() );
     482                                                genCommaList( arg, untypedExpr->args.end() );
    483483                                                output << "}) /* " << opInfo.inputName << " */";
    484484                                        } // if
     
    488488                                  case OT_PREFIXASSIGN:
    489489                                  case OT_LABELADDRESS:
    490                                         assert( untypedExpr->get_args().size() == 1 );
     490                                        assert( untypedExpr->args.size() == 1 );
    491491                                        output << "(";
    492492                                        output << opInfo.symbol;
     
    497497                                  case OT_POSTFIX:
    498498                                  case OT_POSTFIXASSIGN:
    499                                         assert( untypedExpr->get_args().size() == 1 );
     499                                        assert( untypedExpr->args.size() == 1 );
    500500                                        (*arg)->accept( *visitor );
    501501                                        output << opInfo.symbol;
     
    504504                                  case OT_INFIX:
    505505                                  case OT_INFIXASSIGN:
    506                                         assert( untypedExpr->get_args().size() == 2 );
     506                                        assert( untypedExpr->args.size() == 2 );
    507507                                        output << "(";
    508508                                        (*arg++)->accept( *visitor );
     
    517517                                } // switch
    518518                        } else {
    519                                 if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2
    520                                         assert( untypedExpr->get_args().size() == 2 );
    521                                         (*untypedExpr->get_args().begin())->accept( *visitor );
    522                                         output << " ... ";
    523                                         (*--untypedExpr->get_args().end())->accept( *visitor );
    524                                 } else {                                                                // builtin routines
    525                                         nameExpr->accept( *visitor );
    526                                         output << "(";
    527                                         genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
    528                                         output << ")";
    529                                 } // if
     519                                // builtin routines
     520                                nameExpr->accept( *visitor );
     521                                output << "(";
     522                                genCommaList( untypedExpr->args.begin(), untypedExpr->args.end() );
     523                                output << ")";
    530524                        } // if
    531525                } else {
    532                         untypedExpr->get_function()->accept( *visitor );
     526                        untypedExpr->function->accept( *visitor );
    533527                        output << "(";
    534                         genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
     528                        genCommaList( untypedExpr->args.begin(), untypedExpr->args.end() );
    535529                        output << ")";
    536530                } // if
     
    538532
    539533        void CodeGenerator::postvisit( RangeExpr * rangeExpr ) {
    540                 rangeExpr->get_low()->accept( *visitor );
     534                rangeExpr->low->accept( *visitor );
    541535                output << " ... ";
    542                 rangeExpr->get_high()->accept( *visitor );
     536                rangeExpr->high->accept( *visitor );
    543537        }
    544538
  • src/GenPoly/Box.cc

    r4dfa562 ra2d4d1c  
    3232#include "Common/UniqueName.h"           // for UniqueName
    3333#include "Common/utility.h"              // for toString
    34 #include "DeclMutator.h"                 // for DeclMutator
    3534#include "FindFunction.h"                // for findFunction, findAndReplace...
    3635#include "GenPoly/ErasableScopedMap.h"   // for ErasableScopedMap<>::const_i...
     
    3938#include "Lvalue.h"                      // for generalizedLvalue
    4039#include "Parser/LinkageSpec.h"          // for C, Spec, Cforall, Intrinsic
    41 #include "PolyMutator.h"                 // for PolyMutator
    4240#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass
    4341#include "ResolvExpr/typeops.h"          // for typesCompatible
     
    6260                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6361
     62                class BoxPass {
     63                protected:
     64                        BoxPass() : scopeTyVars( TypeDecl::Data{} ) {}
     65                        TyVarMap scopeTyVars;
     66                };
     67
    6468                /// Adds layout-generation functions to polymorphic types
    65                 class LayoutFunctionBuilder final : public DeclMutator {
    66                         unsigned int functionNesting;  // current level of nested functions
     69                class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting {
     70                        unsigned int functionNesting = 0;  // current level of nested functions
    6771                public:
    68                         LayoutFunctionBuilder() : functionNesting( 0 ) {}
    69 
    70                         using DeclMutator::mutate;
    71                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
    72                         virtual Declaration *mutate( StructDecl *structDecl ) override;
    73                         virtual Declaration *mutate( UnionDecl *unionDecl ) override;
     72                        void previsit( FunctionDecl *functionDecl );
     73                        void previsit( StructDecl *structDecl );
     74                        void previsit( UnionDecl *unionDecl );
    7475                };
    7576
    7677                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    77                 class Pass1 final : public PolyMutator {
     78                class Pass1 final : public BoxPass, public WithTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {
    7879                  public:
    7980                        Pass1();
    8081
    81                         using PolyMutator::mutate;
    82                         virtual Expression *mutate( ApplicationExpr *appExpr ) override;
    83                         virtual Expression *mutate( AddressExpr *addrExpr ) override;
    84                         virtual Expression *mutate( UntypedExpr *expr ) override;
    85                         virtual DeclarationWithType* mutate( FunctionDecl *functionDecl ) override;
    86                         virtual TypeDecl *mutate( TypeDecl *typeDecl ) override;
    87                         virtual Expression *mutate( CommaExpr *commaExpr ) override;
    88                         virtual Expression *mutate( ConditionalExpr *condExpr ) override;
    89                         virtual Statement * mutate( ReturnStmt *returnStmt ) override;
    90                         virtual Type *mutate( PointerType *pointerType ) override;
    91                         virtual Type * mutate( FunctionType *functionType ) override;
    92 
    93                         virtual void doBeginScope() override;
    94                         virtual void doEndScope() override;
     82                        void premutate( FunctionDecl * functionDecl );
     83                        void premutate( TypeDecl * typeDecl );
     84                        void premutate( CommaExpr * commaExpr );
     85                        Expression * postmutate( ApplicationExpr * appExpr );
     86                        Expression * postmutate( UntypedExpr *expr );
     87                        void premutate( AddressExpr * addrExpr );
     88                        Expression * postmutate( AddressExpr * addrExpr );
     89                        void premutate( ReturnStmt * returnStmt );
     90                        void premutate( PointerType * pointerType );
     91                        void premutate( FunctionType * functionType );
     92
     93                        void beginScope();
     94                        void endScope();
    9595                  private:
    9696                        /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application
     
    129129                /// * Moves polymorphic returns in function types to pointer-type parameters
    130130                /// * adds type size and assertion parameters to parameter lists
    131                 class Pass2 final : public PolyMutator {
    132                   public:
    133                         template< typename DeclClass >
    134                         DeclClass *handleDecl( DeclClass *decl );
    135                         template< typename AggDecl >
    136                         AggDecl * handleAggDecl( AggDecl * aggDecl );
    137 
    138                         typedef PolyMutator Parent;
    139                         using Parent::mutate;
    140                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
    141                         virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override;
    142                         virtual StructDecl *mutate( StructDecl *structDecl ) override;
    143                         virtual UnionDecl *mutate( UnionDecl *unionDecl ) override;
    144                         virtual TraitDecl *mutate( TraitDecl *unionDecl ) override;
    145                         virtual TypeDecl *mutate( TypeDecl *typeDecl ) override;
    146                         virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ) override;
    147                         virtual Type *mutate( PointerType *pointerType ) override;
    148                         virtual Type *mutate( FunctionType *funcType ) override;
     131                struct Pass2 final : public BoxPass, public WithGuards {
     132                        void handleAggDecl();
     133
     134                        DeclarationWithType * postmutate( FunctionDecl *functionDecl );
     135                        void premutate( StructDecl *structDecl );
     136                        void premutate( UnionDecl *unionDecl );
     137                        void premutate( TraitDecl *unionDecl );
     138                        void premutate( TypeDecl *typeDecl );
     139                        void premutate( PointerType *pointerType );
     140                        void premutate( FunctionType *funcType );
    149141
    150142                  private:
     
    158150                /// * Calculates polymorphic offsetof expressions from offset array
    159151                /// * Inserts dynamic calculation of polymorphic type layouts where needed
    160                 class PolyGenericCalculator final : public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
     152                class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
    161153                public:
    162154                        PolyGenericCalculator();
     
    197189                        ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
    198190                        UniqueName bufNamer;                           ///< Namer for VLA buffers
    199                         TyVarMap scopeTyVars;
    200191                };
    201192
    202193                /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, sizeof expressions of polymorphic types with the proper variable, and strips fields from generic struct declarations.
    203                 class Pass3 final : public PolyMutator {
    204                   public:
     194                struct Pass3 final : public BoxPass, public WithGuards {
    205195                        template< typename DeclClass >
    206                         DeclClass *handleDecl( DeclClass *decl, Type *type );
    207 
    208                         using PolyMutator::mutate;
    209                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
    210                         virtual Declaration *mutate( StructDecl *structDecl ) override;
    211                         virtual Declaration *mutate( UnionDecl *unionDecl ) override;
    212                         virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override;
    213                         virtual TypedefDecl *mutate( TypedefDecl *objectDecl ) override;
    214                         virtual TypeDecl *mutate( TypeDecl *objectDecl ) override;
    215                         virtual Type *mutate( PointerType *pointerType ) override;
    216                         virtual Type *mutate( FunctionType *funcType ) override;
    217                   private:
     196                        void handleDecl( DeclClass * decl, Type * type );
     197
     198                        void premutate( ObjectDecl * objectDecl );
     199                        void premutate( FunctionDecl * functionDecl );
     200                        void premutate( TypedefDecl * typedefDecl );
     201                        void premutate( StructDecl * structDecl );
     202                        void premutate( UnionDecl * unionDecl );
     203                        void premutate( TypeDecl * typeDecl );
     204                        void premutate( PointerType * pointerType );
     205                        void premutate( FunctionType * funcType );
    218206                };
    219207        } // anonymous namespace
     
    247235
    248236        void box( std::list< Declaration *>& translationUnit ) {
    249                 LayoutFunctionBuilder layoutBuilder;
    250                 Pass1 pass1;
    251                 Pass2 pass2;
     237                PassVisitor<LayoutFunctionBuilder> layoutBuilder;
     238                PassVisitor<Pass1> pass1;
     239                PassVisitor<Pass2> pass2;
    252240                PassVisitor<PolyGenericCalculator> polyCalculator;
    253                 Pass3 pass3;
    254 
    255                 layoutBuilder.mutateDeclarationList( translationUnit );
    256                 mutateTranslationUnit/*All*/( translationUnit, pass1 );
    257                 mutateTranslationUnit/*All*/( translationUnit, pass2 );
     241                PassVisitor<Pass3> pass3;
     242
     243                acceptAll( translationUnit, layoutBuilder );
     244                mutateAll( translationUnit, pass1 );
     245                mutateAll( translationUnit, pass2 );
    258246                mutateAll( translationUnit, polyCalculator );
    259                 mutateTranslationUnit/*All*/( translationUnit, pass3 );
     247                mutateAll( translationUnit, pass3 );
    260248        }
    261249
    262250        ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
    263251
    264         DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) {
    265                 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
     252        void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) {
     253                visit_children = false;
     254                maybeAccept( functionDecl->get_functionType(), *visitor );
    266255                ++functionNesting;
    267                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     256                maybeAccept( functionDecl->get_statements(), *visitor );
    268257                --functionNesting;
    269                 return functionDecl;
    270258        }
    271259
     
    356344        }
    357345
    358         Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
     346        void LayoutFunctionBuilder::previsit( StructDecl *structDecl ) {
    359347                // do not generate layout function for "empty" tag structs
    360                 if ( structDecl->get_members().empty() ) return structDecl;
     348                visit_children = false;
     349                if ( structDecl->get_members().empty() ) return;
    361350
    362351                // get parameters that can change layout, exiting early if none
    363352                std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() );
    364                 if ( otypeParams.empty() ) return structDecl;
     353                if ( otypeParams.empty() ) return;
    365354
    366355                // build layout function signature
     
    413402                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    414403
    415                 addDeclarationAfter( layoutDecl );
    416                 return structDecl;
     404                declsToAddAfter.push_back( layoutDecl );
    417405        }
    418406
    419         Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
     407        void LayoutFunctionBuilder::previsit( UnionDecl *unionDecl ) {
    420408                // do not generate layout function for "empty" tag unions
    421                 if ( unionDecl->get_members().empty() ) return unionDecl;
     409                visit_children = false;
     410                if ( unionDecl->get_members().empty() ) return;
    422411
    423412                // get parameters that can change layout, exiting early if none
    424413                std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
    425                 if ( otypeParams.empty() ) return unionDecl;
     414                if ( otypeParams.empty() ) return;
    426415
    427416                // build layout function signature
     
    456445                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    457446
    458                 addDeclarationAfter( layoutDecl );
    459                 return unionDecl;
     447                declsToAddAfter.push_back( layoutDecl );
    460448        }
    461449
     
    501489                Pass1::Pass1() : tempNamer( "_temp" ) {}
    502490
    503                 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
     491                void Pass1::premutate( FunctionDecl *functionDecl ) {
    504492                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    505493                                // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl;
    506                                 doBeginScope();
    507                                 scopeTyVars.beginScope();
    508 
    509                                 DeclarationWithType *oldRetval = retval;
     494                                GuardScope( scopeTyVars );
     495                                GuardValue( retval );
    510496
    511497                                // process polymorphic return value
    512498                                retval = nullptr;
    513                                 if ( isDynRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() != LinkageSpec::C ) {
    514                                         retval = functionDecl->get_functionType()->get_returnVals().front();
     499                                FunctionType *functionType = functionDecl->type;
     500                                if ( isDynRet( functionType ) && functionDecl->linkage != LinkageSpec::C ) {
     501                                        retval = functionType->returnVals.front();
    515502
    516503                                        // give names to unnamed return values
    517                                         if ( retval->get_name() == "" ) {
    518                                                 retval->set_name( "_retparm" );
    519                                                 retval->set_linkage( LinkageSpec::C );
     504                                        if ( retval->name == "" ) {
     505                                                retval->name = "_retparm";
     506                                                retval->linkage = LinkageSpec::C;
    520507                                        } // if
    521508                                } // if
    522509
    523                                 FunctionType *functionType = functionDecl->get_functionType();
    524                                 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
    525 
    526                                 std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
     510                                makeTyVarMap( functionType, scopeTyVars );
     511
     512                                std::list< DeclarationWithType *> &paramList = functionType->parameters;
    527513                                std::list< FunctionType *> functions;
    528                                 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    529                                         for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
     514                                for ( Type::ForallList::iterator tyVar = functionType->forall.begin(); tyVar != functionType->forall.end(); ++tyVar ) {
     515                                        for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {
    530516                                                findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );
    531517                                        } // for
     
    542528                                        } // if
    543529                                } // for
    544 
    545                                 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
    546 
    547                                 scopeTyVars.endScope();
    548                                 retval = oldRetval;
    549                                 doEndScope();
    550530                                // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl;
    551531                        } // if
    552                         return functionDecl;
    553                 }
    554 
    555                 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
     532                }
     533
     534                void Pass1::premutate( TypeDecl *typeDecl ) {
    556535                        addToTyVarMap( typeDecl, scopeTyVars );
    557                         return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
    558                 }
    559 
    560                 Expression *Pass1::mutate( CommaExpr *commaExpr ) {
     536                }
     537
     538                void Pass1::premutate( CommaExpr *commaExpr ) {
    561539                        // Attempting to find application expressions that were mutated by the copy constructor passes
    562540                        // to use an explicit return variable, so that the variable can be reused as a parameter to the
     
    574552                                }
    575553                        }
    576 
    577                         commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) );
    578                         commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) );
    579                         return commaExpr;
    580                 }
    581 
    582                 Expression *Pass1::mutate( ConditionalExpr *condExpr ) {
    583                         condExpr->set_arg1( maybeMutate( condExpr->get_arg1(), *this ) );
    584                         condExpr->set_arg2( maybeMutate( condExpr->get_arg2(), *this ) );
    585                         condExpr->set_arg3( maybeMutate( condExpr->get_arg3(), *this ) );
    586                         return condExpr;
    587 
    588554                }
    589555
     
    659625                ObjectDecl *Pass1::makeTemporary( Type *type ) {
    660626                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, type, 0 );
    661                         stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
     627                        stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
    662628                        return newObj;
    663629                }
     
    775741                                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 );
    776742                                        newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
    777                                         stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
     743                                        stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
    778744                                        UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax?
    779745                                        assign->get_args().push_back( new VariableExpr( newObj ) );
    780746                                        assign->get_args().push_back( arg );
    781                                         stmtsToAdd.push_back( new ExprStmt( noLabels, assign ) );
     747                                        stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) );
    782748                                        arg = new AddressExpr( new VariableExpr( newObj ) );
    783749                                } // if
     
    961927                                                std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    962928                                                adapter = answer.first;
    963                                                 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
     929                                                stmtsToAddBefore.push_back( new DeclStmt( noLabels, newAdapter ) );
    964930                                        } // if
    965931                                        assert( adapter != adapters.end() );
     
    11181084                }
    11191085
    1120                 Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
     1086                Expression *Pass1::postmutate( ApplicationExpr *appExpr ) {
    11211087                        // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl;
    11221088                        // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     
    11241090                        // }
    11251091                        // std::cerr << "\n";
    1126                         appExpr->get_function()->acceptMutator( *this );
    1127                         mutateAll( appExpr->get_args(), *this );
    1128 
    1129                         assert( appExpr->get_function()->has_result() );
    1130                         FunctionType * function = getFunctionType( appExpr->get_function()->get_result() );
    1131                         assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->get_function()->get_result() ).c_str() );
     1092
     1093                        assert( appExpr->function->result );
     1094                        FunctionType * function = getFunctionType( appExpr->function->result );
     1095                        assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() );
    11321096
    11331097                        if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
     
    11821146                }
    11831147
    1184                 Expression *Pass1::mutate( UntypedExpr *expr ) {
    1185                         if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
    1186                                 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
     1148                Expression * Pass1::postmutate( UntypedExpr *expr ) {
     1149                        if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
     1150                                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
    11871151                                        if ( name->get_name() == "*?" ) {
    1188                                                 Expression *ret = expr->get_args().front();
    1189                                                 expr->get_args().clear();
     1152                                                Expression *ret = expr->args.front();
     1153                                                expr->args.clear();
    11901154                                                delete expr;
    1191                                                 return ret->acceptMutator( *this );
     1155                                                return ret;
    11921156                                        } // if
    11931157                                } // if
    11941158                        } // if
    1195                         return PolyMutator::mutate( expr );
    1196                 }
    1197 
    1198                 Expression *Pass1::mutate( AddressExpr *addrExpr ) {
     1159                        return expr;
     1160                }
     1161
     1162                void Pass1::premutate( AddressExpr * ) { visit_children = false; }
     1163                Expression * Pass1::postmutate( AddressExpr * addrExpr ) {
    11991164                        assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() );
    12001165
     
    12161181                        // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
    12171182                        // out of the if condition.
    1218                         addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
     1183                        addrExpr->arg = addrExpr->get_arg()->acceptMutator( *visitor );
    12191184                        // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment
    12201185                        bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env );
     
    12311196                }
    12321197
    1233                 Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    1234                         if ( retval && returnStmt->get_expr() ) {
    1235                                 assert( returnStmt->get_expr()->has_result() && ! returnStmt->get_expr()->get_result()->isVoid() );
    1236                                 delete returnStmt->get_expr();
    1237                                 returnStmt->set_expr( 0 );
    1238                         } else {
    1239                                 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
     1198                void Pass1::premutate( ReturnStmt *returnStmt ) {
     1199                        if ( retval && returnStmt->expr ) {
     1200                                assert( returnStmt->expr->result && ! returnStmt->expr->result->isVoid() );
     1201                                delete returnStmt->expr;
     1202                                returnStmt->expr = nullptr;
    12401203                        } // if
    1241                         return returnStmt;
    1242                 }
    1243 
    1244                 Type * Pass1::mutate( PointerType *pointerType ) {
    1245                         scopeTyVars.beginScope();
     1204                }
     1205
     1206                void Pass1::premutate( PointerType *pointerType ) {
     1207                        GuardScope( scopeTyVars );
    12461208                        makeTyVarMap( pointerType, scopeTyVars );
    1247 
    1248                         Type *ret = Mutator::mutate( pointerType );
    1249 
    1250                         scopeTyVars.endScope();
    1251                         return ret;
    1252                 }
    1253 
    1254                 Type * Pass1::mutate( FunctionType *functionType ) {
    1255                         scopeTyVars.beginScope();
     1209                }
     1210
     1211                void Pass1::premutate( FunctionType *functionType ) {
     1212                        GuardScope( scopeTyVars );
    12561213                        makeTyVarMap( functionType, scopeTyVars );
    1257 
    1258                         Type *ret = Mutator::mutate( functionType );
    1259 
    1260                         scopeTyVars.endScope();
    1261                         return ret;
    1262                 }
    1263 
    1264                 void Pass1::doBeginScope() {
     1214                }
     1215
     1216                void Pass1::beginScope() {
    12651217                        adapters.beginScope();
    12661218                }
    12671219
    1268                 void Pass1::doEndScope() {
     1220                void Pass1::endScope() {
    12691221                        adapters.endScope();
    12701222                }
     
    12931245                }
    12941246
    1295                 template< typename DeclClass >
    1296                 DeclClass * Pass2::handleDecl( DeclClass *decl ) {
    1297                         DeclClass *ret = static_cast< DeclClass *>( Parent::mutate( decl ) );
    1298 
    1299                         return ret;
    1300                 }
    1301 
    1302                 DeclarationWithType * Pass2::mutate( FunctionDecl *functionDecl ) {
    1303                         functionDecl = strict_dynamic_cast< FunctionDecl * > ( handleDecl( functionDecl ) );
     1247                DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) {
    13041248                        FunctionType * ftype = functionDecl->get_functionType();
    13051249                        if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) {
     
    13251269                }
    13261270
    1327                 ObjectDecl * Pass2::mutate( ObjectDecl *objectDecl ) {
    1328                         return handleDecl( objectDecl );
    1329                 }
    1330 
    1331                 template< typename AggDecl >
    1332                 AggDecl * Pass2::handleAggDecl( AggDecl * aggDecl ) {
     1271                void Pass2::premutate( StructDecl * ) {
    13331272                        // prevent tyVars from leaking into containing scope
    1334                         scopeTyVars.beginScope();
    1335                         Parent::mutate( aggDecl );
    1336                         scopeTyVars.endScope();
    1337                         return aggDecl;
    1338                 }
    1339 
    1340                 StructDecl * Pass2::mutate( StructDecl *aggDecl ) {
    1341                         return handleAggDecl( aggDecl );
    1342                 }
    1343 
    1344                 UnionDecl * Pass2::mutate( UnionDecl *aggDecl ) {
    1345                         return handleAggDecl( aggDecl );
    1346                 }
    1347 
    1348                 TraitDecl * Pass2::mutate( TraitDecl *aggDecl ) {
    1349                         return handleAggDecl( aggDecl );
    1350                 }
    1351 
    1352                 TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) {
     1273                        GuardScope( scopeTyVars );
     1274                }
     1275
     1276                void Pass2::premutate( UnionDecl * ) {
     1277                        // prevent tyVars from leaking into containing scope
     1278                        GuardScope( scopeTyVars );
     1279                }
     1280
     1281                void Pass2::premutate( TraitDecl * ) {
     1282                        // prevent tyVars from leaking into containing scope
     1283                        GuardScope( scopeTyVars );
     1284                }
     1285
     1286                void Pass2::premutate( TypeDecl *typeDecl ) {
    13531287                        addToTyVarMap( typeDecl, scopeTyVars );
    1354                         if ( typeDecl->get_base() ) {
    1355                                 return handleDecl( typeDecl );
    1356                         } else {
    1357                                 return dynamic_cast<TypeDecl*>( Parent::mutate( typeDecl ) );
    1358                         }
    1359                 }
    1360 
    1361                 TypedefDecl * Pass2::mutate( TypedefDecl *typedefDecl ) {
    1362                         return handleDecl( typedefDecl );
    1363                 }
    1364 
    1365                 Type * Pass2::mutate( PointerType *pointerType ) {
    1366                         scopeTyVars.beginScope();
     1288                }
     1289
     1290                void Pass2::premutate( PointerType *pointerType ) {
     1291                        GuardScope( scopeTyVars );
    13671292                        makeTyVarMap( pointerType, scopeTyVars );
    1368 
    1369                         Type *ret = Parent::mutate( pointerType );
    1370 
    1371                         scopeTyVars.endScope();
    1372                         return ret;
    1373                 }
    1374 
    1375                 Type *Pass2::mutate( FunctionType *funcType ) {
    1376                         scopeTyVars.beginScope();
    1377 
     1293                }
     1294
     1295                void Pass2::premutate( FunctionType *funcType ) {
     1296                        GuardScope( scopeTyVars );
    13781297                        makeTyVarMap( funcType, scopeTyVars );
    13791298
     
    14141333                                // move all assertions into parameter list
    14151334                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
    1416 //      *assert = (*assert)->acceptMutator( *this );
    14171335                                        // assertion parameters may not be used in body, pass along with unused attribute.
    14181336                                        (*assert)->get_attributes().push_back( new Attribute( "unused" ) );
     
    14501368                                                }
    14511369                                        }
    1452 
    14531370                                        seenTypes.insert( typeName );
    14541371                                }
     
    14581375                        funcType->get_parameters().splice( last, inferredParams );
    14591376                        addAdapters( funcType );
    1460                         mutateAll( funcType->get_returnVals(), *this );
    1461                         mutateAll( funcType->get_parameters(), *this );
    1462 
    1463                         scopeTyVars.endScope();
    1464                         return funcType;
    14651377                }
    14661378
     
    14681380
    14691381                PolyGenericCalculator::PolyGenericCalculator()
    1470                         : knownLayouts(), knownOffsets(), bufNamer( "_buf" ), scopeTyVars( TypeDecl::Data{} ) {}
     1382                        : knownLayouts(), knownOffsets(), bufNamer( "_buf" ) {}
    14711383
    14721384                void PolyGenericCalculator::beginTypeScope( Type *ty ) {
     
    18291741
    18301742                template< typename DeclClass >
    1831                 DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) {
    1832                         scopeTyVars.beginScope();
     1743                void Pass3::handleDecl( DeclClass * decl, Type * type ) {
     1744                        GuardScope( scopeTyVars );
    18331745                        makeTyVarMap( type, scopeTyVars );
    1834 
    1835                         DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
    1836                         // ScrubTyVars::scrub( decl, scopeTyVars );
    18371746                        ScrubTyVars::scrubAll( decl );
    1838 
    1839                         scopeTyVars.endScope();
    1840                         return ret;
    1841                 }
    1842 
    1843                 ObjectDecl * Pass3::mutate( ObjectDecl *objectDecl ) {
    1844                         return handleDecl( objectDecl, objectDecl->get_type() );
    1845                 }
    1846 
    1847                 DeclarationWithType * Pass3::mutate( FunctionDecl *functionDecl ) {
    1848                         return handleDecl( functionDecl, functionDecl->get_functionType() );
    1849                 }
    1850 
    1851                 TypedefDecl * Pass3::mutate( TypedefDecl *typedefDecl ) {
    1852                         return handleDecl( typedefDecl, typedefDecl->get_base() );
     1747                }
     1748
     1749                void Pass3::premutate( ObjectDecl * objectDecl ) {
     1750                        handleDecl( objectDecl, objectDecl->type );
     1751                }
     1752
     1753                void Pass3::premutate( FunctionDecl * functionDecl ) {
     1754                        handleDecl( functionDecl, functionDecl->type );
     1755                }
     1756
     1757                void Pass3::premutate( TypedefDecl * typedefDecl ) {
     1758                        handleDecl( typedefDecl, typedefDecl->base );
    18531759                }
    18541760
    18551761                /// Strips the members from a generic aggregate
    1856                 void stripGenericMembers(AggregateDecl* decl) {
    1857                         if ( ! decl->get_parameters().empty() ) decl->get_members().clear();
    1858                 }
    1859 
    1860                 Declaration *Pass3::mutate( StructDecl *structDecl ) {
     1762                void stripGenericMembers(AggregateDecl * decl) {
     1763                        if ( ! decl->parameters.empty() ) decl->members.clear();
     1764                }
     1765
     1766                void Pass3::premutate( StructDecl * structDecl ) {
    18611767                        stripGenericMembers( structDecl );
    1862                         return structDecl;
    1863                 }
    1864 
    1865                 Declaration *Pass3::mutate( UnionDecl *unionDecl ) {
     1768                }
     1769
     1770                void Pass3::premutate( UnionDecl * unionDecl ) {
    18661771                        stripGenericMembers( unionDecl );
    1867                         return unionDecl;
    1868                 }
    1869 
    1870                 TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) {
    1871 //   Initializer *init = 0;
    1872 //   std::list< Expression *> designators;
    1873 //   addToTyVarMap( typeDecl, scopeTyVars );
    1874 //   if ( typeDecl->get_base() ) {
    1875 //     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
    1876 //   }
    1877 //   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
    1878 
     1772                }
     1773
     1774                void Pass3::premutate( TypeDecl * typeDecl ) {
    18791775                        addToTyVarMap( typeDecl, scopeTyVars );
    1880                         return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
    1881                 }
    1882 
    1883                 Type * Pass3::mutate( PointerType *pointerType ) {
    1884                         scopeTyVars.beginScope();
     1776                }
     1777
     1778                void Pass3::premutate( PointerType * pointerType ) {
     1779                        GuardScope( scopeTyVars );
    18851780                        makeTyVarMap( pointerType, scopeTyVars );
    1886 
    1887                         Type *ret = Mutator::mutate( pointerType );
    1888 
    1889                         scopeTyVars.endScope();
    1890                         return ret;
    1891                 }
    1892 
    1893                 Type * Pass3::mutate( FunctionType *functionType ) {
    1894                         scopeTyVars.beginScope();
     1781                }
     1782
     1783                void Pass3::premutate( FunctionType * functionType ) {
     1784                        GuardScope( scopeTyVars );
    18951785                        makeTyVarMap( functionType, scopeTyVars );
    1896 
    1897                         Type *ret = Mutator::mutate( functionType );
    1898 
    1899                         scopeTyVars.endScope();
    1900                         return ret;
    19011786                }
    19021787        } // anonymous namespace
  • src/GenPoly/Specialize.cc

    r4dfa562 ra2d4d1c  
    2222#include <utility>                       // for pair
    2323
     24#include "Common/PassVisitor.h"
    2425#include "Common/SemanticError.h"        // for SemanticError
    2526#include "Common/UniqueName.h"           // for UniqueName
     
    2829#include "InitTweak/InitTweak.h"         // for isIntrinsicCallExpr
    2930#include "Parser/LinkageSpec.h"          // for C
    30 #include "PolyMutator.h"                 // for PolyMutator
    3131#include "ResolvExpr/FindOpenVars.h"     // for findOpenVars
    3232#include "ResolvExpr/TypeEnvironment.h"  // for OpenVarSet, AssertionSet
     
    4343
    4444namespace GenPoly {
    45         class Specialize final : public PolyMutator {
    46           public:
    47                 using PolyMutator::mutate;
    48                 virtual Expression * mutate( ApplicationExpr *applicationExpr ) override;
    49                 virtual Expression * mutate( AddressExpr *castExpr ) override;
    50                 virtual Expression * mutate( CastExpr *castExpr ) override;
    51                 // virtual Expression * mutate( LogicalExpr *logicalExpr );
    52                 // virtual Expression * mutate( ConditionalExpr *conditionalExpr );
    53                 // virtual Expression * mutate( CommaExpr *commaExpr );
     45        struct Specialize final : public WithTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> {
     46                Expression * postmutate( ApplicationExpr *applicationExpr );
     47                Expression * postmutate( AddressExpr *castExpr );
     48                Expression * postmutate( CastExpr *castExpr );
    5449
    5550                void handleExplicitParams( ApplicationExpr *appExpr );
     
    204199        }
    205200
    206         struct EnvTrimmer : public Visitor {
     201        struct EnvTrimmer {
    207202                TypeSubstitution * env, * newEnv;
    208203                EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
    209                 virtual void visit( TypeDecl * tyDecl ) {
     204                void previsit( TypeDecl * tyDecl ) {
    210205                        // transfer known bindings for seen type variables
    211                         if ( Type * t = env->lookup( tyDecl->get_name() ) ) {
    212                                 newEnv->add( tyDecl->get_name(), t );
     206                        if ( Type * t = env->lookup( tyDecl->name ) ) {
     207                                newEnv->add( tyDecl->name, t );
    213208                        }
    214209                }
     
    219214                if ( env ) {
    220215                        TypeSubstitution * newEnv = new TypeSubstitution();
    221                         EnvTrimmer trimmer( env, newEnv );
     216                        PassVisitor<EnvTrimmer> trimmer( env, newEnv );
    222217                        expr->accept( trimmer );
    223218                        return newEnv;
     
    277272                std::string oldParamPrefix = paramPrefix;
    278273                paramPrefix += "p";
    279                 // save stmtsToAdd in oldStmts
     274                // save stmtsToAddBefore in oldStmts
    280275                std::list< Statement* > oldStmts;
    281                 oldStmts.splice( oldStmts.end(), stmtsToAdd );
    282                 mutate( appExpr );
     276                oldStmts.splice( oldStmts.end(), stmtsToAddBefore );
     277                appExpr->acceptMutator( *visitor );
    283278                paramPrefix = oldParamPrefix;
    284279                // write any statements added for recursive specializations into the thunk body
    285                 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd );
    286                 // restore oldStmts into stmtsToAdd
    287                 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts );
     280                thunkFunc->statements->kids.splice( thunkFunc->statements->kids.end(), stmtsToAddBefore );
     281                // restore oldStmts into stmtsToAddBefore
     282                stmtsToAddBefore.splice( stmtsToAddBefore.end(), oldStmts );
    288283
    289284                // add return (or valueless expression) to the thunk
    290285                Statement *appStmt;
    291                 if ( funType->get_returnVals().empty() ) {
     286                if ( funType->returnVals.empty() ) {
    292287                        appStmt = new ExprStmt( noLabels, appExpr );
    293288                } else {
    294289                        appStmt = new ReturnStmt( noLabels, appExpr );
    295290                } // if
    296                 thunkFunc->get_statements()->get_kids().push_back( appStmt );
     291                thunkFunc->statements->kids.push_back( appStmt );
    297292
    298293                // add thunk definition to queue of statements to add
    299                 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) );
     294                stmtsToAddBefore.push_back( new DeclStmt( noLabels, thunkFunc ) );
    300295                // return address of thunk function as replacement expression
    301296                return new AddressExpr( new VariableExpr( thunkFunc ) );
     
    304299        void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) {
    305300                // create thunks for the explicit parameters
    306                 assert( appExpr->get_function()->has_result() );
    307                 FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
     301                assert( appExpr->function->result );
     302                FunctionType *function = getFunctionType( appExpr->function->result );
    308303                assert( function );
    309304                std::list< DeclarationWithType* >::iterator formal;
    310305                std::list< Expression* >::iterator actual;
    311306                for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) {
    312                         *actual = doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() );
    313                 }
    314         }
    315 
    316         Expression * Specialize::mutate( ApplicationExpr *appExpr ) {
    317                 appExpr->get_function()->acceptMutator( *this );
    318                 mutateAll( appExpr->get_args(), *this );
    319 
     307                        *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() );
     308                }
     309        }
     310
     311        Expression * Specialize::postmutate( ApplicationExpr *appExpr ) {
    320312                if ( ! InitTweak::isIntrinsicCallExpr( appExpr ) ) {
    321313                        // create thunks for the inferred parameters
     
    331323        }
    332324
    333         Expression * Specialize::mutate( AddressExpr *addrExpr ) {
    334                 addrExpr->get_arg()->acceptMutator( *this );
    335                 assert( addrExpr->has_result() );
    336                 addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) );
     325        Expression * Specialize::postmutate( AddressExpr *addrExpr ) {
     326                assert( addrExpr->result );
     327                addrExpr->set_arg( doSpecialization( addrExpr->result, addrExpr->arg ) );
    337328                return addrExpr;
    338329        }
    339330
    340         Expression * Specialize::mutate( CastExpr *castExpr ) {
    341                 castExpr->get_arg()->acceptMutator( *this );
    342                 if ( castExpr->get_result()->isVoid() ) {
     331        Expression * Specialize::postmutate( CastExpr *castExpr ) {
     332                if ( castExpr->result->isVoid() ) {
    343333                        // can't specialize if we don't have a return value
    344334                        return castExpr;
    345335                }
    346                 Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() );
    347                 if ( specialized != castExpr->get_arg() ) {
     336                Expression *specialized = doSpecialization( castExpr->result, castExpr->arg );
     337                if ( specialized != castExpr->arg ) {
    348338                        // assume here that the specialization incorporates the cast
    349339                        return specialized;
     
    353343        }
    354344
    355         // Removing these for now. Richard put these in for some reason, but it's not clear why.
    356         // In particular, copy constructors produce a comma expression, and with this code the parts
    357         // of that comma expression are not specialized, which causes problems.
    358 
    359         // Expression * Specialize::mutate( LogicalExpr *logicalExpr ) {
    360         //      return logicalExpr;
    361         // }
    362 
    363         // Expression * Specialize::mutate( ConditionalExpr *condExpr ) {
    364         //      return condExpr;
    365         // }
    366 
    367         // Expression * Specialize::mutate( CommaExpr *commaExpr ) {
    368         //      return commaExpr;
    369         // }
    370 
    371345        void convertSpecializations( std::list< Declaration* >& translationUnit ) {
    372                 Specialize spec;
     346                PassVisitor<Specialize> spec;
    373347                mutateAll( translationUnit, spec );
    374348        }
  • src/GenPoly/module.mk

    r4dfa562 ra2d4d1c  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## module.mk -- 
     8## module.mk --
    99##
    1010## Author           : Richard C. Bilson
     
    1717SRC += GenPoly/Box.cc \
    1818       GenPoly/GenPoly.cc \
    19        GenPoly/PolyMutator.cc \
    2019       GenPoly/ScrubTyVars.cc \
    2120       GenPoly/Lvalue.cc \
     
    2322       GenPoly/CopyParams.cc \
    2423       GenPoly/FindFunction.cc \
    25        GenPoly/DeclMutator.cc \
    2624       GenPoly/InstantiateGeneric.cc
  • src/InitTweak/FixInit.cc

    r4dfa562 ra2d4d1c  
    3636#include "FixGlobalInit.h"             // for fixGlobalInit
    3737#include "GenInit.h"                   // for genCtorDtor
    38 #include "GenPoly/DeclMutator.h"       // for DeclMutator
    3938#include "GenPoly/GenPoly.h"           // for getFunctionType
    40 #include "GenPoly/PolyMutator.h"       // for PolyMutator
    4139#include "InitTweak.h"                 // for getFunctionName, getCallArg
    4240#include "Parser/LinkageSpec.h"        // for C, Spec, Cforall, isBuiltin
     
    4644#include "SymTab/Indexer.h"            // for Indexer
    4745#include "SymTab/Mangler.h"            // for Mangler
    48 #include "SynTree/AddStmtVisitor.h"    // for AddStmtVisitor
    4946#include "SynTree/Attribute.h"         // for Attribute
    5047#include "SynTree/Constant.h"          // for Constant
     
    5855#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution, operator<<
    5956#include "SynTree/Visitor.h"           // for acceptAll, maybeAccept
    60 #include "Tuples/Tuples.h"             // for isTtype
    6157
    6258bool ctordtorp = false; // print all debug
     
    187183                };
    188184
    189                 class FixCopyCtors final : public GenPoly::PolyMutator {
     185                class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors> {
    190186                  public:
    191187                        FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){}
     
    194190                        static void fixCopyCtors( std::list< Declaration * > &translationUnit, UnqCount & unqCount );
    195191
    196                         typedef GenPoly::PolyMutator Parent;
    197                         using Parent::mutate;
    198                         virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override;
    199                         virtual Expression * mutate( UniqueExpr * unqExpr ) override;
    200                         virtual Expression * mutate( StmtExpr * stmtExpr ) override;
     192                        Expression * postmutate( ImplicitCopyCtorExpr * impCpCtorExpr );
     193                        void premutate( StmtExpr * stmtExpr );
     194                        void premutate( UniqueExpr * unqExpr );
    201195
    202196                        UnqCount & unqCount;
     
    243237                };
    244238
    245                 class FixCtorExprs final : public GenPoly::DeclMutator {
    246                   public:
     239                struct FixCtorExprs final : public WithDeclsToAdd, public WithIndexer {
    247240                        /// expands ConstructorExpr nodes into comma expressions, using a temporary for the first argument
    248241                        static void fix( std::list< Declaration * > & translationUnit );
    249242
    250                         using GenPoly::DeclMutator::mutate;
    251                         virtual Expression * mutate( ConstructorExpr * ctorExpr ) override;
     243                        Expression * postmutate( ConstructorExpr * ctorExpr );
    252244                };
    253245        } // namespace
     
    316308
    317309                void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {
    318                         FixCopyCtors fixer( unqCount );
     310                        PassVisitor<FixCopyCtors> fixer( unqCount );
    319311                        mutateAll( translationUnit, fixer );
    320312                }
     
    326318
    327319                void FixCtorExprs::fix( std::list< Declaration * > & translationUnit ) {
    328                         FixCtorExprs fixer;
    329                         fixer.mutateDeclarationList( translationUnit );
     320                        PassVisitor<FixCtorExprs> fixer;
     321                        mutateAll( translationUnit, fixer );
    330322                }
    331323
     
    339331                                } else if ( DeclarationWithType * funcDecl = dynamic_cast< DeclarationWithType * > ( function->get_var() ) ) {
    340332                                        FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) );
    341                                         assert( ftype );
     333                                        assertf( ftype, "Function call without function type: %s", toString( funcDecl ).c_str() );
    342334                                        if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype->get_parameters().size() == 2 ) {
    343335                                                Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() );
     
    368360                }
    369361
    370                 bool ResolveCopyCtors::skipCopyConstruct( Type * type ) {
    371                         return dynamic_cast< VarArgsType * >( type ) || dynamic_cast< ReferenceType * >( type ) || GenPoly::getFunctionType( type ) || Tuples::isTtype( type );
    372                 }
     362                bool ResolveCopyCtors::skipCopyConstruct( Type * type ) { return ! isConstructable( type ); }
    373363
    374364                Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
     
    407397                        result = result->clone();
    408398                        env->apply( result );
    409                         ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
     399                        ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr );
    410400                        tmp->get_type()->set_const( false );
    411401
     
    421411                                if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return;
    422412                        }
     413
     414                        // set a unique name for the temporary once it's certain the call is necessary
     415                        tmp->name = tempNamer.newName();
    423416
    424417                        // replace argument to function call with temporary
     
    450443                                result = result->clone();
    451444                                env->apply( result );
    452                                 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
     445                                ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
    453446                                ret->get_type()->set_const( false );
    454447                                impCpCtorExpr->get_returnDecls().push_back( ret );
    455448                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    456449                                if ( ! dynamic_cast< ReferenceType * >( result ) ) {
    457                                         // destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
     450                                        // destructing reference returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
    458451                                        destructRet( ret, impCpCtorExpr );
    459452                                }
     
    472465                                result = result->clone();
    473466                                env->apply( result );
    474                                 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
     467                                ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
    475468                                ret->get_type()->set_const( false );
    476469                                stmtExpr->get_returnDecls().push_front( ret );
     
    509502                        } else {
    510503                                // expr isn't a call expr, so create a new temporary variable to use to hold the value of the unique expression
    511                                 unqExpr->set_object( new ObjectDecl( toString("_unq", unqExpr->get_id()), Type::StorageClasses(), LinkageSpec::C, nullptr, unqExpr->get_result()->clone(), nullptr ) );
     504                                unqExpr->set_object( ObjectDecl::newObject( toString("_unq", unqExpr->get_id()), unqExpr->get_result()->clone(), nullptr ) );
    512505                                unqExpr->set_var( new VariableExpr( unqExpr->get_object() ) );
    513506                        }
     
    515508                }
    516509
    517                 Expression * FixCopyCtors::mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
     510                Expression * FixCopyCtors::postmutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
    518511                        CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; )
    519512
    520                         impCpCtorExpr = strict_dynamic_cast< ImplicitCopyCtorExpr * >( Parent::mutate( impCpCtorExpr ) );
    521513                        std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls();
    522514                        std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls();
     
    525517                        // add all temporary declarations and their constructors
    526518                        for ( ObjectDecl * obj : tempDecls ) {
    527                                 stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
     519                                stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
    528520                        } // for
    529521                        for ( ObjectDecl * obj : returnDecls ) {
    530                                 stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
     522                                stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
    531523                        } // for
    532524
     
    536528                        } // for
    537529
    538                         // xxx - update to work with multiple return values
    539530                        ObjectDecl * returnDecl = returnDecls.empty() ? nullptr : returnDecls.front();
    540531                        Expression * callExpr = impCpCtorExpr->get_callExpr();
     
    569560                }
    570561
    571                 Expression * FixCopyCtors::mutate( StmtExpr * stmtExpr ) {
     562                void FixCopyCtors::premutate( StmtExpr * stmtExpr ) {
    572563                        // function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression,
    573564                        // since temporaries can be shared across sub-expressions, e.g.
    574565                        //   [A, A] f();
    575566                        //   g([A] x, [A] y);
    576                         //   f(g());
     567                        //   g(f());
    577568                        // f is executed once, so the return temporary is shared across the tuple constructors for x and y.
     569                        // Explicitly mutating children instead of mutating the inner compound statment forces the temporaries to be added
     570                        // to the outer context, rather than inside of the statement expression.
     571                        visit_children = false;
    578572                        std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
    579573                        for ( Statement *& stmt : stmts ) {
    580                                 stmt = stmt->acceptMutator( *this );
     574                                stmt = stmt->acceptMutator( *visitor );
    581575                        } // for
    582                         // stmtExpr = strict_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) );
    583576                        assert( stmtExpr->get_result() );
    584577                        Type * result = stmtExpr->get_result();
    585578                        if ( ! result->isVoid() ) {
    586579                                for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) {
    587                                         stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
     580                                        stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
    588581                                } // for
    589582                                // add destructors after current statement
     
    592585                                } // for
    593586                                // must have a non-empty body, otherwise it wouldn't have a result
    594                                 CompoundStmt * body = stmtExpr->get_statements();
    595                                 assert( ! body->get_kids().empty() );
     587                                assert( ! stmts.empty() );
    596588                                assert( ! stmtExpr->get_returnDecls().empty() );
    597                                 body->get_kids().push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
     589                                stmts.push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
    598590                                stmtExpr->get_returnDecls().clear();
    599591                                stmtExpr->get_dtors().clear();
     
    601593                        assert( stmtExpr->get_returnDecls().empty() );
    602594                        assert( stmtExpr->get_dtors().empty() );
    603                         return stmtExpr;
    604                 }
    605 
    606                 Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) {
     595                }
     596
     597                void FixCopyCtors::premutate( UniqueExpr * unqExpr ) {
     598                        visit_children = false;
    607599                        unqCount[ unqExpr->get_id() ]--;
    608600                        static std::unordered_map< int, std::list< Statement * > > dtors;
    609601                        static std::unordered_map< int, UniqueExpr * > unqMap;
    610                         static std::unordered_set< int > addDeref;
    611602                        // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes
    612603                        if ( unqMap.count( unqExpr->get_id() ) ) {
     
    619610                                        stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
    620611                                }
    621                                 if ( addDeref.count( unqExpr->get_id() ) ) {
    622                                         // other UniqueExpr was dereferenced because it was an lvalue return, so this one should be too
    623                                         return UntypedExpr::createDeref( unqExpr );
    624                                 }
    625                                 return unqExpr;
    626                         }
    627                         FixCopyCtors fixer( unqCount );
     612                                return;
     613                        }
     614                        PassVisitor<FixCopyCtors> fixer( unqCount );
    628615                        unqExpr->set_expr( unqExpr->get_expr()->acceptMutator( fixer ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup
    629                         stmtsToAdd.splice( stmtsToAdd.end(), fixer.stmtsToAdd );
     616                        stmtsToAddBefore.splice( stmtsToAddBefore.end(), fixer.pass.stmtsToAddBefore );
    630617                        unqMap[unqExpr->get_id()] = unqExpr;
    631618                        if ( unqCount[ unqExpr->get_id() ] == 0 ) {  // insert destructor after the last use of the unique expression
    632619                                stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
    633620                        } else { // remember dtors for last instance of unique expr
    634                                 dtors[ unqExpr->get_id() ] = fixer.stmtsToAddAfter;
    635                         }
    636                         if ( UntypedExpr * deref = dynamic_cast< UntypedExpr * >( unqExpr->get_expr() ) ) {
    637                                 // unique expression is now a dereference, because the inner expression is an lvalue returning function call.
    638                                 // Normalize the expression by dereferencing the unique expression, rather than the inner expression
    639                                 // (i.e. move the dereference out a level)
    640                                 assert( getFunctionName( deref ) == "*?" );
    641                                 unqExpr->set_expr( getCallArg( deref, 0 ) );
    642                                 getCallArg( deref, 0 ) = unqExpr;
    643                                 addDeref.insert( unqExpr->get_id() );
    644                                 return deref;
    645                         }
    646                         return unqExpr;
     621                                dtors[ unqExpr->get_id() ] = fixer.pass.stmtsToAddAfter;
     622                        }
     623                        return;
    647624                }
    648625
     
    819796                                        assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
    820797                                        Statement * dtor = ctorInit->get_dtor();
     798                                        // don't need to call intrinsic dtor, because it does nothing, but
     799                                        // non-intrinsic dtors must be called
    821800                                        if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
    822                                                 // don't need to call intrinsic dtor, because it does nothing, but
    823                                                 // non-intrinsic dtors must be called
     801                                                // set dtor location to the object's location for error messages
     802                                                ctorInit->dtor->location = objDecl->location;
    824803                                                reverseDeclOrder.front().push_front( objDecl );
    825804                                        } // if
     
    1012991                                        // skip non-DWT members
    1013992                                        if ( ! field ) continue;
     993                                        // skip non-constructable members
     994                                        if ( ! tryConstruct( field ) ) continue;
    1014995                                        // skip handled members
    1015996                                        if ( ! unhandled.count( field ) ) continue;
     
    11421123                }
    11431124
    1144                 Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
     1125                Expression * FixCtorExprs::postmutate( ConstructorExpr * ctorExpr ) {
    11451126                        static UniqueName tempNamer( "_tmp_ctor_expr" );
    11461127                        // xxx - is the size check necessary?
     
    11481129
    11491130                        // xxx - ideally we would reuse the temporary generated from the copy constructor passes from within firstArg if it exists and not generate a temporary if it's unnecessary.
    1150                         ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr );
    1151                         addDeclaration( tmp );
     1131                        ObjectDecl * tmp = ObjectDecl::newObject( tempNamer.newName(), ctorExpr->get_result()->clone(), nullptr );
     1132                        declsToAddBefore.push_back( tmp );
    11521133
    11531134                        // xxx - this can be TupleAssignExpr now. Need to properly handle this case.
     
    11581139                        delete ctorExpr;
    11591140
     1141                        // build assignment and replace constructor's first argument with new temporary
    11601142                        Expression *& firstArg = callExpr->get_args().front();
    1161 
    1162                         // xxx - hack in 'fake' assignment operator until resolver can easily be called in this pass. Once the resolver can be used in PassVisitor, this hack goes away.
    1163 
    1164                         // generate the type of assignment operator using the type of tmp minus any reference types
    1165                         Type * type = tmp->get_type()->stripReferences();
    1166                         FunctionType * ftype = SymTab::genAssignType( type );
    1167 
    1168                         // generate fake assignment decl and call it using &tmp and &firstArg
    1169                         // since tmp is guaranteed to be a reference and we want to assign pointers
    1170                         FunctionDecl * assignDecl = new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Intrinsic, ftype, nullptr );
    1171                         ApplicationExpr * assign = new ApplicationExpr( VariableExpr::functionPointer( assignDecl ) );
    1172                         assign->get_args().push_back( new AddressExpr( new VariableExpr( tmp ) ) );
    1173                         Expression * addrArg = new AddressExpr( firstArg );
    1174                         // if firstArg has type T&&, then &firstArg has type T*&.
    1175                         // Cast away the reference to a value type so that the argument
    1176                         // matches the assignment's parameter types
    1177                         if ( dynamic_cast<ReferenceType *>( addrArg->get_result() ) ) {
    1178                                 addrArg = new CastExpr( addrArg, addrArg->get_result()->stripReferences()->clone() );
    1179                         }
    1180                         assign->get_args().push_back( addrArg );
     1143                        Expression * assign = new UntypedExpr( new NameExpr( "?=?" ), { new AddressExpr( new VariableExpr( tmp ) ), new AddressExpr( firstArg ) } );
    11811144                        firstArg = new VariableExpr( tmp );
     1145
     1146                        // resolve assignment and dispose of new env
     1147                        Expression * resolvedAssign = ResolvExpr::findVoidExpression( assign, indexer );
     1148                        delete resolvedAssign->env;
     1149                        resolvedAssign->env = nullptr;
     1150                        delete assign;
    11821151
    11831152                        // for constructor expr:
     
    11881157                        //   T & tmp;
    11891158                        //   &tmp = &x, ?{}(tmp), tmp
    1190                         CommaExpr * commaExpr = new CommaExpr( assign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
     1159                        CommaExpr * commaExpr = new CommaExpr( resolvedAssign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
    11911160                        commaExpr->set_env( env );
    11921161                        return commaExpr;
  • src/InitTweak/GenInit.cc

    r4dfa562 ra2d4d1c  
    2626#include "Common/UniqueName.h"     // for UniqueName
    2727#include "Common/utility.h"        // for ValueGuard, maybeClone
    28 #include "GenPoly/DeclMutator.h"   // for DeclMutator
    2928#include "GenPoly/GenPoly.h"       // for getFunctionType, isPolyType
    3029#include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::const_iter...
     
    6261        };
    6362
    64         struct CtorDtor : public WithGuards, public WithShortCircuiting  {
     63        struct CtorDtor : public WithGuards, public WithShortCircuiting, public WithVisitorRef<CtorDtor>  {
    6564                /// create constructor and destructor statements for object declarations.
    6665                /// the actual call statements will be added in after the resolver has run
     
    7574                // that need to be constructed or destructed
    7675                void previsit( StructDecl *aggregateDecl );
    77                 void previsit( __attribute__((unused)) UnionDecl    * aggregateDecl ) { visit_children = false; }
    78                 void previsit( __attribute__((unused)) EnumDecl     * aggregateDecl ) { visit_children = false; }
    79                 void previsit( __attribute__((unused)) TraitDecl    * aggregateDecl ) { visit_children = false; }
    80                 void previsit( __attribute__((unused)) TypeDecl     * typeDecl )      { visit_children = false; }
    81                 void previsit( __attribute__((unused)) TypedefDecl  * typeDecl )      { visit_children = false; }
    82                 void previsit( __attribute__((unused)) FunctionType * funcType )      { visit_children = false; }
     76                void previsit( AggregateDecl * ) { visit_children = false; }
     77                void previsit( NamedTypeDecl * ) { visit_children = false; }
     78                void previsit( FunctionType * ) { visit_children = false; }
    8379
    8480                void previsit( CompoundStmt * compoundStmt );
     
    9692        };
    9793
    98         class HoistArrayDimension final : public GenPoly::DeclMutator {
    99           public:
    100                 typedef GenPoly::DeclMutator Parent;
    101 
     94        struct HoistArrayDimension final : public WithDeclsToAdd, public WithShortCircuiting, public WithGuards {
    10295                /// hoist dimension from array types in object declaration so that it uses a single
    10396                /// const variable of type size_t, so that side effecting array dimensions are only
     
    10598                static void hoistArrayDimension( std::list< Declaration * > & translationUnit );
    10699
    107           private:
    108                 using Parent::mutate;
    109 
    110                 virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override;
    111                 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
     100                void premutate( ObjectDecl * objectDecl );
     101                DeclarationWithType * postmutate( ObjectDecl * objectDecl );
     102                void premutate( FunctionDecl *functionDecl );
    112103                // should not traverse into any of these declarations to find objects
    113104                // that need to be constructed or destructed
    114                 virtual Declaration* mutate( StructDecl *aggregateDecl ) override { return aggregateDecl; }
    115                 virtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; }
    116                 virtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; }
    117                 virtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; }
    118                 virtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; }
    119                 virtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; }
    120 
    121                 virtual Type* mutate( FunctionType *funcType ) override { return funcType; }
     105                void premutate( AggregateDecl * ) { visit_children = false; }
     106                void premutate( NamedTypeDecl * ) { visit_children = false; }
     107                void premutate( FunctionType * ) { visit_children = false; }
    122108
    123109                void hoist( Type * type );
     
    128114
    129115        void genInit( std::list< Declaration * > & translationUnit ) {
    130                 ReturnFixer::makeReturnTemp( translationUnit );
     116                fixReturnStatements( translationUnit );
    131117                HoistArrayDimension::hoistArrayDimension( translationUnit );
    132118                CtorDtor::generateCtorDtor( translationUnit );
    133119        }
    134120
    135         void ReturnFixer::makeReturnTemp( std::list< Declaration * > & translationUnit ) {
     121        void fixReturnStatements( std::list< Declaration * > & translationUnit ) {
    136122                PassVisitor<ReturnFixer> fixer;
    137123                mutateAll( translationUnit, fixer );
     
    143129                // hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address
    144130                // is being returned
    145                 if ( returnStmt->get_expr() && returnVals.size() == 1 && ! dynamic_cast< ReferenceType * >( returnVals.front()->get_type() ) ) {
     131                if ( returnStmt->get_expr() && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {
    146132                        // explicitly construct the return value using the return expression and the retVal object
    147133                        assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() );
     
    158144                GuardValue( funcName );
    159145
    160                 ftype = functionDecl->get_functionType();
    161                 funcName = functionDecl->get_name();
     146                ftype = functionDecl->type;
     147                funcName = functionDecl->name;
    162148        }
    163149
     
    165151        // which would be incorrect if it is a side-effecting computation.
    166152        void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) {
    167                 HoistArrayDimension hoister;
    168                 hoister.mutateDeclarationList( translationUnit );
    169         }
    170 
    171         DeclarationWithType * HoistArrayDimension::mutate( ObjectDecl * objectDecl ) {
     153                PassVisitor<HoistArrayDimension> hoister;
     154                mutateAll( translationUnit, hoister );
     155        }
     156
     157        void HoistArrayDimension::premutate( ObjectDecl * objectDecl ) {
     158                GuardValue( storageClasses );
    172159                storageClasses = objectDecl->get_storageClasses();
    173                 DeclarationWithType * temp = Parent::mutate( objectDecl );
     160        }
     161
     162        DeclarationWithType * HoistArrayDimension::postmutate( ObjectDecl * objectDecl ) {
    174163                hoist( objectDecl->get_type() );
    175                 return temp;
     164                return objectDecl;
    176165        }
    177166
     
    194183
    195184                        arrayType->set_dimension( new VariableExpr( arrayDimension ) );
    196                         addDeclaration( arrayDimension );
     185                        declsToAddBefore.push_back( arrayDimension );
    197186
    198187                        hoist( arrayType->get_base() );
     
    201190        }
    202191
    203         DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) {
    204                 ValueGuard< bool > oldInFunc( inFunction );
    205                 inFunction = true;
    206                 DeclarationWithType * decl = Parent::mutate( functionDecl );
    207                 return decl;
     192        void HoistArrayDimension::premutate( FunctionDecl * ) {
     193                GuardValue( inFunction );
    208194        }
    209195
     
    214200
    215201        bool CtorDtor::isManaged( Type * type ) const {
    216                 // at least for now, references are never constructed
     202                // references are never constructed
    217203                if ( dynamic_cast< ReferenceType * >( type ) ) return false;
    218204                // need to clear and reset qualifiers when determining if a type is managed
     
    221207                if ( TupleType * tupleType = dynamic_cast< TupleType * > ( type ) ) {
    222208                        // tuple is also managed if any of its components are managed
    223                         if ( std::any_of( tupleType->get_types().begin(), tupleType->get_types().end(), [&](Type * type) { return isManaged( type ); }) ) {
     209                        if ( std::any_of( tupleType->types.begin(), tupleType->types.end(), [&](Type * type) { return isManaged( type ); }) ) {
    224210                                return true;
    225211                        }
     
    305291
    306292        void CtorDtor::previsit( FunctionDecl *functionDecl ) {
     293                visit_children = false;  // do not try and construct parameters or forall parameters
    307294                GuardValue( inFunction );
    308295                inFunction = true;
     
    318305                }
    319306
    320                 PassVisitor<CtorDtor> newCtorDtor;
    321                 newCtorDtor.pass = *this;
    322                 maybeAccept( functionDecl->get_statements(), newCtorDtor );
    323                 visit_children = false;  // do not try and construct parameters or forall parameters - must happen after maybeAccept
     307                maybeAccept( functionDecl->get_statements(), *visitor );
    324308        }
    325309
     
    340324        }
    341325
    342         void CtorDtor::previsit( __attribute__((unused)) CompoundStmt * compoundStmt ) {
     326        void CtorDtor::previsit( CompoundStmt * ) {
    343327                GuardScope( managedTypes );
    344328        }
  • src/InitTweak/GenInit.h

    r4dfa562 ra2d4d1c  
    2525        void genInit( std::list< Declaration * > & translationUnit );
    2626
    27   /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument
    28   ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr );
     27        /// Converts return statements into copy constructor calls on the hidden return variable
     28        void fixReturnStatements( std::list< Declaration * > & translationUnit );
     29
     30        /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument
     31        ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr );
    2932
    3033        /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
  • src/InitTweak/InitTweak.cc

    r4dfa562 ra2d4d1c  
    1 #include <stddef.h>                // for NULL
    21#include <algorithm>               // for find, all_of
    32#include <cassert>                 // for assertf, assert, strict_dynamic_cast
     
    2322#include "SynTree/Type.h"          // for FunctionType, ArrayType, PointerType
    2423#include "SynTree/Visitor.h"       // for Visitor, maybeAccept
     24#include "Tuples/Tuples.h"         // for Tuples::isTtype
    2525
    2626class UntypedValofExpr;
     
    184184                        callExpr->get_args().splice( callExpr->get_args().end(), args );
    185185
    186                         *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), NULL );
     186                        *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), nullptr );
    187187
    188188                        UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) );
     
    250250        // To accomplish this, generate switch statement, consuming all of expander's elements
    251251        Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
    252                 if ( ! init ) return NULL;
     252                if ( ! init ) return nullptr;
    253253                CompoundStmt * block = new CompoundStmt( noLabels );
    254254                build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) );
    255255                if ( block->get_kids().empty() ) {
    256256                        delete block;
    257                         return NULL;
     257                        return nullptr;
    258258                } else {
    259                         init = NULL; // init was consumed in creating the list init
     259                        init = nullptr; // init was consumed in creating the list init
    260260                        return block;
    261261                }
    262262        }
    263263
    264         Statement * ExprImpl::buildListInit( __attribute((unused)) UntypedExpr * dst, __attribute((unused)) std::list< Expression * > & indices ) {
    265                 return NULL;
     264        Statement * ExprImpl::buildListInit( UntypedExpr *, std::list< Expression * > & ) {
     265                return nullptr;
    266266        }
    267267
     
    270270        }
    271271
    272         bool tryConstruct( ObjectDecl * objDecl ) {
     272        bool tryConstruct( DeclarationWithType * dwt ) {
     273                ObjectDecl * objDecl = dynamic_cast< ObjectDecl * >( dwt );
     274                if ( ! objDecl ) return false;
    273275                return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
    274                         (objDecl->get_init() == NULL ||
    275                                 ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() ))
    276                         && ! objDecl->get_storageClasses().is_extern;
     276                        (objDecl->get_init() == nullptr ||
     277                                ( objDecl->get_init() != nullptr && objDecl->get_init()->get_maybeConstructed() ))
     278                        && ! objDecl->get_storageClasses().is_extern
     279                        && isConstructable( objDecl->type );
     280        }
     281
     282        bool isConstructable( Type * type ) {
     283                return ! dynamic_cast< VarArgsType * >( type ) && ! dynamic_cast< ReferenceType * >( type ) && ! dynamic_cast< FunctionType * >( type ) && ! Tuples::isTtype( type );
    277284        }
    278285
     
    314321                collectCtorDtorCalls( stmt, matches );
    315322                assert( matches.size() <= 1 );
    316                 return matches.size() == 1 ? matches.front() : NULL;
     323                return matches.size() == 1 ? matches.front() : nullptr;
    317324        }
    318325
     
    359366        ApplicationExpr * isIntrinsicCallExpr( Expression * expr ) {
    360367                ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr );
    361                 if ( ! appExpr ) return NULL;
     368                if ( ! appExpr ) return nullptr;
    362369                DeclarationWithType * function = getCalledFunction( appExpr->get_function() );
    363370                assertf( function, "getCalledFunction returned nullptr: %s", toString( appExpr->get_function() ).c_str() );
    364371                // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
    365372                // will call all member dtors, and some members may have a user defined dtor.
    366                 return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : NULL;
     373                return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : nullptr;
    367374        }
    368375
     
    482489                        return refType->get_base();
    483490                } else {
    484                         return NULL;
     491                        return nullptr;
    485492                }
    486493        }
     
    488495        Type * isPointerType( Type * type ) {
    489496                if ( getPointerBase( type ) ) return type;
    490                 else return NULL;
     497                else return nullptr;
    491498        }
    492499
  • src/InitTweak/InitTweak.h

    r4dfa562 ra2d4d1c  
    3333        std::list< Expression * > makeInitList( Initializer * init );
    3434
    35         /// True if the resolver should try to construct objDecl
    36         bool tryConstruct( ObjectDecl * objDecl );
     35        /// True if the resolver should try to construct dwt
     36        bool tryConstruct( DeclarationWithType * dwt );
     37
     38        /// True if the type can have a user-defined constructor
     39        bool isConstructable( Type * t );
    3740
    3841        /// True if the Initializer contains designations
  • src/Makefile.in

    r4dfa562 ra2d4d1c  
    172172        GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \
    173173        GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \
    174         GenPoly/driver_cfa_cpp-PolyMutator.$(OBJEXT) \
    175174        GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT) \
    176175        GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT) \
     
    178177        GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT) \
    179178        GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \
    180         GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT) \
    181179        GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) \
    182180        InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT) \
     
    253251        SynTree/driver_cfa_cpp-Visitor.$(OBJEXT) \
    254252        SynTree/driver_cfa_cpp-Mutator.$(OBJEXT) \
    255         SynTree/driver_cfa_cpp-AddStmtVisitor.$(OBJEXT) \
    256253        SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \
    257254        SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \
     
    497494        ControlStruct/ForExprMutator.cc \
    498495        ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \
    499         GenPoly/GenPoly.cc GenPoly/PolyMutator.cc \
    500         GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
    501         GenPoly/CopyParams.cc GenPoly/FindFunction.cc \
    502         GenPoly/DeclMutator.cc GenPoly/InstantiateGeneric.cc \
     496        GenPoly/GenPoly.cc GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc \
     497        GenPoly/Specialize.cc GenPoly/CopyParams.cc \
     498        GenPoly/FindFunction.cc GenPoly/InstantiateGeneric.cc \
    503499        InitTweak/GenInit.cc InitTweak/FixInit.cc \
    504500        InitTweak/FixGlobalInit.cc InitTweak/InitTweak.cc \
     
    535531        SynTree/NamedTypeDecl.cc SynTree/TypeDecl.cc \
    536532        SynTree/Initializer.cc SynTree/Visitor.cc SynTree/Mutator.cc \
    537         SynTree/AddStmtVisitor.cc SynTree/TypeSubstitution.cc \
    538         SynTree/Attribute.cc SynTree/VarExprReplacer.cc \
    539         Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
    540         Tuples/Explode.cc Virtual/ExpandCasts.cc
     533        SynTree/TypeSubstitution.cc SynTree/Attribute.cc \
     534        SynTree/VarExprReplacer.cc Tuples/TupleAssignment.cc \
     535        Tuples/TupleExpansion.cc Tuples/Explode.cc \
     536        Virtual/ExpandCasts.cc
    541537MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
    542538        ${cfa_cpplib_PROGRAMS}}
     
    717713GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT): GenPoly/$(am__dirstamp) \
    718714        GenPoly/$(DEPDIR)/$(am__dirstamp)
    719 GenPoly/driver_cfa_cpp-PolyMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \
    720         GenPoly/$(DEPDIR)/$(am__dirstamp)
    721715GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT): GenPoly/$(am__dirstamp) \
    722716        GenPoly/$(DEPDIR)/$(am__dirstamp)
     
    729723GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT):  \
    730724        GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp)
    731 GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \
    732         GenPoly/$(DEPDIR)/$(am__dirstamp)
    733725GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT):  \
    734726        GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp)
     
    929921SynTree/driver_cfa_cpp-Mutator.$(OBJEXT): SynTree/$(am__dirstamp) \
    930922        SynTree/$(DEPDIR)/$(am__dirstamp)
    931 SynTree/driver_cfa_cpp-AddStmtVisitor.$(OBJEXT):  \
    932         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    933923SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT):  \
    934924        SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
     
    1008998@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Po@am__quote@
    1009999@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-CopyParams.Po@am__quote@
    1010 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Po@am__quote@
    10111000@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po@am__quote@
    10121001@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po@am__quote@
    10131002@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po@am__quote@
    10141003@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Po@am__quote@
    1015 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po@am__quote@
    10161004@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@
    10171005@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po@am__quote@
     
    10561044@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-TypeEquality.Po@am__quote@
    10571045@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Po@am__quote@
    1058 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Po@am__quote@
    10591046@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Po@am__quote@
    10601047@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Po@am__quote@
     
    14501437@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-GenPoly.obj `if test -f 'GenPoly/GenPoly.cc'; then $(CYGPATH_W) 'GenPoly/GenPoly.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/GenPoly.cc'; fi`
    14511438
    1452 GenPoly/driver_cfa_cpp-PolyMutator.o: GenPoly/PolyMutator.cc
    1453 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-PolyMutator.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo -c -o GenPoly/driver_cfa_cpp-PolyMutator.o `test -f 'GenPoly/PolyMutator.cc' || echo '$(srcdir)/'`GenPoly/PolyMutator.cc
    1454 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po
    1455 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/PolyMutator.cc' object='GenPoly/driver_cfa_cpp-PolyMutator.o' libtool=no @AMDEPBACKSLASH@
    1456 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1457 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-PolyMutator.o `test -f 'GenPoly/PolyMutator.cc' || echo '$(srcdir)/'`GenPoly/PolyMutator.cc
    1458 
    1459 GenPoly/driver_cfa_cpp-PolyMutator.obj: GenPoly/PolyMutator.cc
    1460 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-PolyMutator.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo -c -o GenPoly/driver_cfa_cpp-PolyMutator.obj `if test -f 'GenPoly/PolyMutator.cc'; then $(CYGPATH_W) 'GenPoly/PolyMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/PolyMutator.cc'; fi`
    1461 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po
    1462 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/PolyMutator.cc' object='GenPoly/driver_cfa_cpp-PolyMutator.obj' libtool=no @AMDEPBACKSLASH@
    1463 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1464 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-PolyMutator.obj `if test -f 'GenPoly/PolyMutator.cc'; then $(CYGPATH_W) 'GenPoly/PolyMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/PolyMutator.cc'; fi`
    1465 
    14661439GenPoly/driver_cfa_cpp-ScrubTyVars.o: GenPoly/ScrubTyVars.cc
    14671440@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-ScrubTyVars.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Tpo -c -o GenPoly/driver_cfa_cpp-ScrubTyVars.o `test -f 'GenPoly/ScrubTyVars.cc' || echo '$(srcdir)/'`GenPoly/ScrubTyVars.cc
     
    15341507@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-FindFunction.obj `if test -f 'GenPoly/FindFunction.cc'; then $(CYGPATH_W) 'GenPoly/FindFunction.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/FindFunction.cc'; fi`
    15351508
    1536 GenPoly/driver_cfa_cpp-DeclMutator.o: GenPoly/DeclMutator.cc
    1537 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-DeclMutator.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo -c -o GenPoly/driver_cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc
    1538 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Po
    1539 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/DeclMutator.cc' object='GenPoly/driver_cfa_cpp-DeclMutator.o' libtool=no @AMDEPBACKSLASH@
    1540 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1541 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc
    1542 
    1543 GenPoly/driver_cfa_cpp-DeclMutator.obj: GenPoly/DeclMutator.cc
    1544 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-DeclMutator.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo -c -o GenPoly/driver_cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi`
    1545 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Po
    1546 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/DeclMutator.cc' object='GenPoly/driver_cfa_cpp-DeclMutator.obj' libtool=no @AMDEPBACKSLASH@
    1547 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1548 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi`
    1549 
    15501509GenPoly/driver_cfa_cpp-InstantiateGeneric.o: GenPoly/InstantiateGeneric.cc
    15511510@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-InstantiateGeneric.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc
     
    25832542@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    25842543@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Mutator.obj `if test -f 'SynTree/Mutator.cc'; then $(CYGPATH_W) 'SynTree/Mutator.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Mutator.cc'; fi`
    2585 
    2586 SynTree/driver_cfa_cpp-AddStmtVisitor.o: SynTree/AddStmtVisitor.cc
    2587 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AddStmtVisitor.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.o `test -f 'SynTree/AddStmtVisitor.cc' || echo '$(srcdir)/'`SynTree/AddStmtVisitor.cc
    2588 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Po
    2589 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/AddStmtVisitor.cc' object='SynTree/driver_cfa_cpp-AddStmtVisitor.o' libtool=no @AMDEPBACKSLASH@
    2590 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2591 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.o `test -f 'SynTree/AddStmtVisitor.cc' || echo '$(srcdir)/'`SynTree/AddStmtVisitor.cc
    2592 
    2593 SynTree/driver_cfa_cpp-AddStmtVisitor.obj: SynTree/AddStmtVisitor.cc
    2594 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AddStmtVisitor.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.obj `if test -f 'SynTree/AddStmtVisitor.cc'; then $(CYGPATH_W) 'SynTree/AddStmtVisitor.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AddStmtVisitor.cc'; fi`
    2595 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AddStmtVisitor.Po
    2596 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/AddStmtVisitor.cc' object='SynTree/driver_cfa_cpp-AddStmtVisitor.obj' libtool=no @AMDEPBACKSLASH@
    2597 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2598 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AddStmtVisitor.obj `if test -f 'SynTree/AddStmtVisitor.cc'; then $(CYGPATH_W) 'SynTree/AddStmtVisitor.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AddStmtVisitor.cc'; fi`
    25992544
    26002545SynTree/driver_cfa_cpp-TypeSubstitution.o: SynTree/TypeSubstitution.cc
  • src/ResolvExpr/Resolver.cc

    r4dfa562 ra2d4d1c  
    9595                PassVisitor<Resolver> resolver;
    9696                acceptAll( translationUnit, resolver );
     97        }
     98
     99        void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) {
     100                PassVisitor<Resolver> resolver( indexer );
     101                maybeAccept( decl, resolver );
    97102        }
    98103
  • src/ResolvExpr/Resolver.h

    r4dfa562 ra2d4d1c  
    2929        /// Checks types and binds syntactic constructs to typed representations
    3030        void resolve( std::list< Declaration * > translationUnit );
    31         Expression * resolveInVoidContext( Expression *expr   , const SymTab::Indexer &indexer );
    32         Expression * findVoidExpression  ( Expression *untyped, const SymTab::Indexer &indexer );
     31        void resolveDecl( Declaration *, const SymTab::Indexer &indexer );
     32        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
     33        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer );
    3334        Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer );
    3435        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer );
  • src/ResolvExpr/TypeEnvironment.cc

    r4dfa562 ra2d4d1c  
    123123                for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {
    124124                        for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) {
    125 ///       std::cout << "adding " << *theVar;
     125///       std::cerr << "adding " << *theVar;
    126126                                if ( theClass->type ) {
    127 ///         std::cout << " bound to ";
    128 ///         theClass->type->print( std::cout );
    129 ///         std::cout << std::endl;
     127///         std::cerr << " bound to ";
     128///         theClass->type->print( std::cerr );
     129///         std::cerr << std::endl;
    130130                                        sub.add( *theVar, theClass->type );
    131131                                } else if ( theVar != theClass->vars.begin() ) {
    132132                                        TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype );
    133 ///         std::cout << " bound to variable " << *theClass->vars.begin() << std::endl;
     133///         std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl;
    134134                                        sub.add( *theVar, newTypeInst );
    135135                                        delete newTypeInst;
  • src/SymTab/Autogen.cc

    r4dfa562 ra2d4d1c  
    1616#include "Autogen.h"
    1717
    18 #include <cstddef>                 // for NULL
    1918#include <algorithm>               // for count_if
    2019#include <cassert>                 // for strict_dynamic_cast, assert, assertf
     
    2726#include "AddVisit.h"              // for addVisit
    2827#include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign
     28#include "Common/PassVisitor.h"    // for PassVisitor
    2929#include "Common/ScopedMap.h"      // for ScopedMap<>::const_iterator, Scope...
    3030#include "Common/utility.h"        // for cloneAll, operator+
    31 #include "GenPoly/DeclMutator.h"   // for DeclMutator
    3231#include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::iterator
     32#include "InitTweak/GenInit.h"     // for fixReturnStatements
     33#include "ResolvExpr/Resolver.h"   // for resolveDecl
    3334#include "SymTab/Mangler.h"        // for Mangler
    3435#include "SynTree/Attribute.h"     // For Attribute
     
    5354        };
    5455
    55         class AutogenerateRoutines final : public Visitor {
    56             template< typename Visitor >
    57             friend void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
    58             template< typename Visitor >
    59             friend void addVisitStatementList( std::list< Statement* > &stmts, Visitor &visitor );
    60           public:
    61                 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    62 
    63                 typedef Visitor Parent;
    64                 using Parent::visit;
    65 
     56        struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting {
    6657                AutogenerateRoutines();
    6758
    68                 virtual void visit( EnumDecl *enumDecl );
    69                 virtual void visit( StructDecl *structDecl );
    70                 virtual void visit( UnionDecl *structDecl );
    71                 virtual void visit( TypeDecl *typeDecl );
    72                 virtual void visit( TraitDecl *ctxDecl );
    73                 virtual void visit( FunctionDecl *functionDecl );
    74 
    75                 virtual void visit( FunctionType *ftype );
    76                 virtual void visit( PointerType *ftype );
    77 
    78                 virtual void visit( CompoundStmt *compoundStmt );
    79                 virtual void visit( SwitchStmt *switchStmt );
     59                void previsit( EnumDecl * enumDecl );
     60                void previsit( StructDecl * structDecl );
     61                void previsit( UnionDecl * structDecl );
     62                void previsit( TypeDecl * typeDecl );
     63                void previsit( TraitDecl * traitDecl );
     64                void previsit( FunctionDecl * functionDecl );
     65
     66                void previsit( FunctionType * ftype );
     67                void previsit( PointerType * ptype );
     68
     69                void previsit( CompoundStmt * compoundStmt );
    8070
    8171          private:
    82                 template< typename StmtClass > void visitStatement( StmtClass *stmt );
    83 
    84                 std::list< Declaration * > declsToAdd, declsToAddAfter;
    85                 std::set< std::string > structsDone;
     72                GenPoly::ScopedSet< std::string > structsDone;
    8673                unsigned int functionNesting = 0;     // current level of nested functions
    8774                /// Note: the following maps could be ScopedSets, but it should be easier to work
     
    9380
    9481        /// generates routines for tuple types.
    95         /// Doesn't really need to be a mutator, but it's easier to reuse DeclMutator than it is to use AddVisit
    96         /// or anything we currently have that supports adding new declarations for visitors
    97         class AutogenTupleRoutines : public GenPoly::DeclMutator {
    98           public:
    99                 typedef GenPoly::DeclMutator Parent;
    100                 using Parent::mutate;
    101 
    102                 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
    103 
    104                 virtual Type * mutate( TupleType *tupleType );
    105 
    106                 virtual CompoundStmt * mutate( CompoundStmt *compoundStmt );
     82        struct AutogenTupleRoutines : public WithDeclsToAdd, public WithVisitorRef<AutogenTupleRoutines>, public WithGuards, public WithShortCircuiting {
     83                void previsit( FunctionDecl *functionDecl );
     84
     85                void postvisit( TupleType *tupleType );
     86
     87                void previsit( CompoundStmt *compoundStmt );
    10788
    10889          private:
     
    11293
    11394        void autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    114                 AutogenerateRoutines generator;
    115                 acceptAndAdd( translationUnit, generator );
     95                PassVisitor<AutogenerateRoutines> generator;
     96                acceptAll( translationUnit, generator );
    11697
    11798                // needs to be done separately because AutogenerateRoutines skips types that appear as function arguments, etc.
    11899                // AutogenTupleRoutines tupleGenerator;
    119                 // tupleGenerator.mutateDeclarationList( translationUnit );
     100                // acceptAll( translationUnit, tupleGenerator );
    120101        }
    121102
    122103        bool isUnnamedBitfield( ObjectDecl * obj ) {
    123                 return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL;
     104                return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr;
    124105        }
    125106
     
    128109                FunctionDecl * decl = functionDecl->clone();
    129110                delete decl->get_statements();
    130                 decl->set_statements( NULL );
     111                decl->set_statements( nullptr );
    131112                declsToAdd.push_back( decl );
    132113                decl->fixUniqueId();
     
    339320                                assert( ! func->get_functionType()->get_parameters().empty() );
    340321                                ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() );
    341                                 ObjectDecl * srcParam = NULL;
     322                                ObjectDecl * srcParam = nullptr;
    342323                                if ( func->get_functionType()->get_parameters().size() == 2 ) {
    343324                                        srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
     
    346327                                assert( dstParam );
    347328
    348                                 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
     329                                Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr;
    349330                                makeStructMemberOp( dstParam, srcselect, field, func, forward );
    350331                        } // if
     
    385366                                } else {
    386367                                        // no matching parameter, initialize field with default ctor
    387                                         makeStructMemberOp( dstParam, NULL, field, func );
     368                                        makeStructMemberOp( dstParam, nullptr, field, func );
    388369                                }
    389370                        }
     
    401382        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
    402383                // Builtins do not use autogeneration.
    403                 if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA ||
    404                          aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) {
     384                if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) {
    405385                        return;
    406386                }
    407387
    408388                // Make function polymorphic in same parameters as generic struct, if applicable
    409                 const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
     389                const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    410390
    411391                // generate each of the functions based on the supplied FuncData objects
     
    572552                // the order here determines the order that these functions are generated.
    573553                // assignment should come last since it uses copy constructor in return.
    574                 data.push_back( FuncData( "?{}", genDefaultType, constructable ) );
    575                 data.push_back( FuncData( "?{}", genCopyType, copyable ) );
    576                 data.push_back( FuncData( "^?{}", genDefaultType, destructable ) );
    577                 data.push_back( FuncData( "?=?", genAssignType, assignable ) );
    578         }
    579 
    580         void AutogenerateRoutines::visit( EnumDecl *enumDecl ) {
     554                data.emplace_back( "?{}", genDefaultType, constructable );
     555                data.emplace_back( "?{}", genCopyType, copyable );
     556                data.emplace_back( "^?{}", genDefaultType, destructable );
     557                data.emplace_back( "?=?", genAssignType, assignable );
     558        }
     559
     560        void AutogenerateRoutines::previsit( EnumDecl * enumDecl ) {
     561                visit_children = false;
    581562                if ( ! enumDecl->get_members().empty() ) {
    582563                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
     
    586567        }
    587568
    588         void AutogenerateRoutines::visit( StructDecl *structDecl ) {
    589                 if ( structDecl->has_body() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
    590                         StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
    591                         for ( TypeDecl * typeDecl : structDecl->get_parameters() ) {
     569        void AutogenerateRoutines::previsit( StructDecl * structDecl ) {
     570                visit_children = false;
     571                if ( structDecl->has_body() && structsDone.find( structDecl->name ) == structsDone.end() ) {
     572                        StructInstType structInst( Type::Qualifiers(), structDecl->name );
     573                        for ( TypeDecl * typeDecl : structDecl->parameters ) {
    592574                                // need to visit assertions so that they are added to the appropriate maps
    593                                 acceptAll( typeDecl->get_assertions(), *this );
    594                                 structInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) );
     575                                acceptAll( typeDecl->assertions, *visitor );
     576                                structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );
    595577                        }
    596578                        structInst.set_baseStruct( structDecl );
    597579                        makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data );
    598                         structsDone.insert( structDecl->get_name() );
     580                        structsDone.insert( structDecl->name );
    599581                } // if
    600582        }
    601583
    602         void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
     584        void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) {
     585                visit_children = false;
    603586                if ( ! unionDecl->get_members().empty() ) {
    604587                        UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
     
    619602
    620603        // generate ctor/dtors/assign for typedecls, e.g., otype T = int *;
    621         void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
     604        void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) {
     605                visit_children = false;
    622606                if ( ! typeDecl->base ) return;
    623607
     
    664648        }
    665649
    666         void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) {
    667                 for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
    668                         statements.insert( i, new DeclStmt( noLabels, *decl ) );
    669                 } // for
    670                 declsToAdd.clear();
    671         }
    672 
    673         void AutogenerateRoutines::visit( FunctionType *) {
     650        void AutogenerateRoutines::previsit( FunctionType *) {
    674651                // ensure that we don't add assignment ops for types defined as part of the function
    675         }
    676 
    677         void AutogenerateRoutines::visit( PointerType *) {
     652                visit_children = false;
     653        }
     654
     655        void AutogenerateRoutines::previsit( PointerType *) {
    678656                // ensure that we don't add assignment ops for types defined as part of the pointer
    679         }
    680 
    681         void AutogenerateRoutines::visit( TraitDecl *) {
     657                visit_children = false;
     658        }
     659
     660        void AutogenerateRoutines::previsit( TraitDecl * ) {
    682661                // ensure that we don't add assignment ops for types defined as part of the trait
    683         }
    684 
    685         template< typename StmtClass >
    686         inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) {
    687                 std::set< std::string > oldStructs = structsDone;
    688                 addVisit( stmt, *this );
    689                 structsDone = oldStructs;
    690         }
    691 
    692         void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) {
     662                visit_children = false;
     663        }
     664
     665        void AutogenerateRoutines::previsit( FunctionDecl * functionDecl ) {
     666                visit_children = false;
    693667                // record the existence of this function as appropriate
    694668                insert( functionDecl, constructable, InitTweak::isDefaultConstructor );
     
    697671                insert( functionDecl, destructable, InitTweak::isDestructor );
    698672
    699                 maybeAccept( functionDecl->get_functionType(), *this );
     673                maybeAccept( functionDecl->type, *visitor );
    700674                functionNesting += 1;
    701                 maybeAccept( functionDecl->get_statements(), *this );
     675                maybeAccept( functionDecl->statements, *visitor );
    702676                functionNesting -= 1;
    703677        }
    704678
    705         void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) {
    706                 constructable.beginScope();
    707                 assignable.beginScope();
    708                 copyable.beginScope();
    709                 destructable.beginScope();
    710                 visitStatement( compoundStmt );
    711                 constructable.endScope();
    712                 assignable.endScope();
    713                 copyable.endScope();
    714                 destructable.endScope();
    715         }
    716 
    717         void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) {
    718                 visitStatement( switchStmt );
     679        void AutogenerateRoutines::previsit( CompoundStmt * ) {
     680                GuardScope( constructable );
     681                GuardScope( assignable );
     682                GuardScope( copyable );
     683                GuardScope( destructable );
     684                GuardScope( structsDone );
    719685        }
    720686
     
    734700        }
    735701
    736         Type * AutogenTupleRoutines::mutate( TupleType * tupleType ) {
    737                 tupleType = strict_dynamic_cast< TupleType * >( Parent::mutate( tupleType ) );
     702        void AutogenTupleRoutines::postvisit( TupleType * tupleType ) {
    738703                std::string mangleName = SymTab::Mangler::mangleType( tupleType );
    739                 if ( seenTuples.find( mangleName ) != seenTuples.end() ) return tupleType;
     704                if ( seenTuples.find( mangleName ) != seenTuples.end() ) return;
    740705                seenTuples.insert( mangleName );
    741706
     
    785750                makeTupleFunctionBody( dtorDecl );
    786751
    787                 addDeclaration( ctorDecl );
    788                 addDeclaration( copyCtorDecl );
    789                 addDeclaration( dtorDecl );
    790                 addDeclaration( assignDecl ); // assignment should come last since it uses copy constructor in return
    791 
    792                 return tupleType;
    793         }
    794 
    795         DeclarationWithType * AutogenTupleRoutines::mutate( FunctionDecl *functionDecl ) {
    796                 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
     752                declsToAddBefore.push_back( ctorDecl );
     753                declsToAddBefore.push_back( copyCtorDecl );
     754                declsToAddBefore.push_back( dtorDecl );
     755                declsToAddBefore.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return
     756        }
     757
     758        void AutogenTupleRoutines::previsit( FunctionDecl *functionDecl ) {
     759                visit_children = false;
     760                maybeAccept( functionDecl->type, *visitor );
    797761                functionNesting += 1;
    798                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     762                maybeAccept( functionDecl->statements, *visitor );
    799763                functionNesting -= 1;
    800                 return functionDecl;
    801         }
    802 
    803         CompoundStmt * AutogenTupleRoutines::mutate( CompoundStmt *compoundStmt ) {
    804                 seenTuples.beginScope();
    805                 compoundStmt = strict_dynamic_cast< CompoundStmt * >( Parent::mutate( compoundStmt ) );
    806                 seenTuples.endScope();
    807                 return compoundStmt;
     764        }
     765
     766        void AutogenTupleRoutines::previsit( CompoundStmt * ) {
     767                GuardScope( seenTuples );
    808768        }
    809769} // SymTab
  • src/SymTab/FixFunction.cc

    r4dfa562 ra2d4d1c  
    2727
    2828        DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) {
     29                // can't delete function type because it may contain assertions, so transfer ownership to new object
    2930                ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClasses(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type() ), 0, functionDecl->get_attributes() );
    3031                functionDecl->get_attributes().clear();
    31                 // can't delete function type because it may contain assertions, but can't transfer ownership without a clone since set_type checks for nullptr
    32                 functionDecl->set_type( functionDecl->get_type()->clone() );
     32                functionDecl->type = nullptr;
    3333                delete functionDecl;
    3434                return pointer;
  • src/SymTab/Indexer.cc

    r4dfa562 ra2d4d1c  
    4040
    4141namespace SymTab {
    42         struct NewScope {
    43                 NewScope( SymTab::Indexer & indexer ) : indexer( indexer ) { indexer.enterScope(); }
    44                 ~NewScope() { indexer.leaveScope(); }
    45                 SymTab::Indexer & indexer;
    46         };
    47 
    48         template< typename TreeType, typename VisitorType >
    49         inline void acceptNewScope( TreeType *tree, VisitorType &visitor ) {
    50                 visitor.enterScope();
    51                 maybeAccept( tree, visitor );
    52                 visitor.leaveScope();
    53         }
    54 
    5542        typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable;
    5643        typedef std::unordered_map< std::string, MangleTable > IdTable;
     
    198185        }
    199186
    200         Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug ) {}
    201 
    202         Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug ) {}
    203 
    204         Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug ) {
     187        Indexer::Indexer() : tables( 0 ), scope( 0 ) {}
     188
     189        Indexer::Indexer( const Indexer &that ) : doDebug( that.doDebug ), tables( newRef( that.tables ) ), scope( that.scope ) {}
     190
     191        Indexer::Indexer( Indexer &&that ) : doDebug( that.doDebug ), tables( that.tables ), scope( that.scope ) {
    205192                that.tables = 0;
    206193        }
  • src/SymTab/Indexer.h

    r4dfa562 ra2d4d1c  
    2626        class Indexer {
    2727          public:
    28                 explicit Indexer( bool useDebug = false );
     28                explicit Indexer();
    2929
    3030                Indexer( const Indexer &that );
     
    7676                void addTrait( TraitDecl *decl );
    7777
     78                bool doDebug = false; ///< Display debugging trace?
    7879          private:
    7980                struct Impl;
     
    8182                Impl *tables;         ///< Copy-on-write instance of table data structure
    8283                unsigned long scope;  ///< Scope index of this pointer
    83                 bool doDebug;         ///< Display debugging trace?
    8484
    8585                /// Takes a new ref to a table (returns null if null)
  • src/SymTab/Mangler.cc

    r4dfa562 ra2d4d1c  
    3131
    3232namespace SymTab {
    33         std::string Mangler::mangleType( Type *ty ) {
     33        std::string Mangler::mangleType( Type * ty ) {
    3434                Mangler mangler( false, true );
    3535                maybeAccept( ty, mangler );
     
    4848        }
    4949
    50         void Mangler::mangleDecl( DeclarationWithType *declaration ) {
     50        void Mangler::mangleDecl( DeclarationWithType * declaration ) {
    5151                bool wasTopLevel = isTopLevel;
    5252                if ( isTopLevel ) {
     
    7979        }
    8080
    81         void Mangler::visit( ObjectDecl *declaration ) {
     81        void Mangler::visit( ObjectDecl * declaration ) {
    8282                mangleDecl( declaration );
    8383        }
    8484
    85         void Mangler::visit( FunctionDecl *declaration ) {
     85        void Mangler::visit( FunctionDecl * declaration ) {
    8686                mangleDecl( declaration );
    8787        }
    8888
    89         void Mangler::visit( VoidType *voidType ) {
     89        void Mangler::visit( VoidType * voidType ) {
    9090                printQualifiers( voidType );
    9191                mangleName << "v";
    9292        }
    9393
    94         void Mangler::visit( BasicType *basicType ) {
     94        void Mangler::visit( BasicType * basicType ) {
    9595                static const char *btLetter[] = {
    9696                        "b",    // Bool
     
    121121        }
    122122
    123         void Mangler::visit( PointerType *pointerType ) {
     123        void Mangler::visit( PointerType * pointerType ) {
    124124                printQualifiers( pointerType );
    125125                mangleName << "P";
     
    127127        }
    128128
    129         void Mangler::visit( ArrayType *arrayType ) {
     129        void Mangler::visit( ArrayType * arrayType ) {
    130130                // TODO: encode dimension
    131131                printQualifiers( arrayType );
     
    134134        }
    135135
    136         void Mangler::visit( ReferenceType *refType ) {
     136        void Mangler::visit( ReferenceType * refType ) {
    137137                printQualifiers( refType );
    138138                mangleName << "R";
     
    149149        }
    150150
    151         void Mangler::visit( FunctionType *functionType ) {
     151        void Mangler::visit( FunctionType * functionType ) {
    152152                printQualifiers( functionType );
    153153                mangleName << "F";
     
    160160        }
    161161
    162         void Mangler::mangleRef( ReferenceToType *refType, std::string prefix ) {
     162        void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {
    163163                printQualifiers( refType );
    164164
     
    166166        }
    167167
    168         void Mangler::mangleGenericRef( ReferenceToType *refType, std::string prefix ) {
     168        void Mangler::mangleGenericRef( ReferenceToType * refType, std::string prefix ) {
    169169                printQualifiers( refType );
    170170
     
    189189        }
    190190
    191         void Mangler::visit( StructInstType *aggregateUseType ) {
     191        void Mangler::visit( StructInstType * aggregateUseType ) {
    192192                if ( typeMode ) mangleGenericRef( aggregateUseType, "s" );
    193193                else mangleRef( aggregateUseType, "s" );
    194194        }
    195195
    196         void Mangler::visit( UnionInstType *aggregateUseType ) {
     196        void Mangler::visit( UnionInstType * aggregateUseType ) {
    197197                if ( typeMode ) mangleGenericRef( aggregateUseType, "u" );
    198198                else mangleRef( aggregateUseType, "u" );
    199199        }
    200200
    201         void Mangler::visit( EnumInstType *aggregateUseType ) {
     201        void Mangler::visit( EnumInstType * aggregateUseType ) {
    202202                mangleRef( aggregateUseType, "e" );
    203203        }
    204204
    205         void Mangler::visit( TypeInstType *typeInst ) {
     205        void Mangler::visit( TypeInstType * typeInst ) {
    206206                VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
    207207                if ( varNum == varNums.end() ) {
     
    231231        }
    232232
    233         void Mangler::visit( TupleType *tupleType ) {
     233        void Mangler::visit( TupleType * tupleType ) {
    234234                printQualifiers( tupleType );
    235235                mangleName << "T";
    236                 acceptAll( tupleType->get_types(), *this );
     236                acceptAll( tupleType->types, *this );
    237237                mangleName << "_";
    238238        }
    239239
    240         void Mangler::visit( VarArgsType *varArgsType ) {
     240        void Mangler::visit( VarArgsType * varArgsType ) {
    241241                printQualifiers( varArgsType );
    242242                mangleName << "VARGS";
    243243        }
    244244
    245         void Mangler::visit( __attribute__((unused)) ZeroType *zeroType ) {
     245        void Mangler::visit( ZeroType * ) {
    246246                mangleName << "Z";
    247247        }
    248248
    249         void Mangler::visit( __attribute__((unused)) OneType *oneType ) {
     249        void Mangler::visit( OneType * ) {
    250250                mangleName << "O";
    251251        }
    252252
    253         void Mangler::visit( TypeDecl *decl ) {
     253        void Mangler::visit( TypeDecl * decl ) {
    254254                static const char *typePrefix[] = { "BT", "BD", "BF" };
    255                 mangleName << typePrefix[ decl->get_kind() ] << ( decl->get_name().length() + 1 ) << decl->get_name();
     255                mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name;
    256256        }
    257257
     
    262262        }
    263263
    264         void Mangler::printQualifiers( Type *type ) {
     264        void Mangler::printQualifiers( Type * type ) {
    265265                // skip if not including qualifiers
    266266                if ( typeMode ) return;
     
    270270                        int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
    271271                        mangleName << "A";
    272                         for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     272                        for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
    273273                                switch ( (*i)->get_kind() ) {
    274274                                  case TypeDecl::Any:
     
    287287                                        assert( false );
    288288                                } // switch
    289                                 varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() );
    290                                 for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
     289                                varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
     290                                for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
    291291                                        Mangler sub_mangler( mangleOverridable, typeMode );
    292292                                        sub_mangler.nextVarNum = nextVarNum;
     
    315315//              } // if
    316316                if ( type->get_lvalue() ) {
     317                        // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
    317318                        mangleName << "L";
    318                 } // if
     319                }
    319320                if ( type->get_atomic() ) {
    320321                        mangleName << "A";
  • src/SymTab/Validate.cc

    r4dfa562 ra2d4d1c  
    5656#include "FixFunction.h"               // for FixFunction
    5757#include "Indexer.h"                   // for Indexer
     58#include "InitTweak/GenInit.h"         // for fixReturnStatements
    5859#include "InitTweak/InitTweak.h"       // for isCtorDtorAssign
    5960#include "Parser/LinkageSpec.h"        // for C
     
    150151        /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
    151152        struct ForallPointerDecay final {
    152                 void previsit( ObjectDecl *object );
    153                 void previsit( FunctionDecl *func );
     153                void previsit( ObjectDecl * object );
     154                void previsit( FunctionDecl * func );
    154155        };
    155156
     
    579580
    580581        /// Fix up assertions - flattens assertion lists, removing all trait instances
    581         void forallFixer( Type * func ) {
    582                 for ( TypeDecl * type : func->get_forall() ) {
     582        void forallFixer( std::list< TypeDecl * > & forall, BaseSyntaxNode * node ) {
     583                for ( TypeDecl * type : forall ) {
    583584                        std::list< DeclarationWithType * > asserts;
    584585                        asserts.splice( asserts.end(), type->assertions );
     
    599600                                assertion = assertion->acceptMutator( fixer );
    600601                                if ( fixer.get_isVoid() ) {
    601                                         throw SemanticError( "invalid type void in assertion of function ", func );
     602                                        throw SemanticError( "invalid type void in assertion of function ", node );
    602603                                } // if
    603604                        } // for
     
    607608
    608609        void ForallPointerDecay::previsit( ObjectDecl *object ) {
    609                 forallFixer( object->get_type() );
    610                 if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
    611                         forallFixer( pointer->get_base() );
     610                forallFixer( object->type->forall, object );
     611                if ( PointerType *pointer = dynamic_cast< PointerType * >( object->type ) ) {
     612                        forallFixer( pointer->base->forall, object );
    612613                } // if
    613614                object->fixUniqueId();
     
    615616
    616617        void ForallPointerDecay::previsit( FunctionDecl *func ) {
    617                 forallFixer( func->get_type() );
     618                forallFixer( func->type->forall, func );
    618619                func->fixUniqueId();
    619620        }
  • src/SynTree/Visitor.h

    r4dfa562 ra2d4d1c  
    2525  public:
    2626        // visit: Default implementation of all functions visits the children
    27     // of the given syntax node, but performs no other action.
     27        // of the given syntax node, but performs no other action.
    2828
    2929        virtual void visit( ObjectDecl *objectDecl );
  • src/SynTree/module.mk

    r4dfa562 ra2d4d1c  
    4848       SynTree/Visitor.cc \
    4949       SynTree/Mutator.cc \
    50        SynTree/AddStmtVisitor.cc \
    5150       SynTree/TypeSubstitution.cc \
    5251       SynTree/Attribute.cc \
  • src/Tuples/TupleExpansion.cc

    r4dfa562 ra2d4d1c  
    2121#include "Common/ScopedMap.h"     // for ScopedMap
    2222#include "Common/utility.h"       // for CodeLocation
    23 #include "GenPoly/DeclMutator.h"  // for DeclMutator
    2423#include "InitTweak/InitTweak.h"  // for getFunction
    2524#include "Parser/LinkageSpec.h"   // for Spec, C, Intrinsic
  • src/main.cc

    r4dfa562 ra2d4d1c  
    239239                } // if
    240240
    241                 // OPTPRINT( "Concurrency" )
    242                 // Concurrency::applyKeywords( translationUnit );
    243 
    244241                // add the assignment statement after the initialization of a type parameter
    245242                OPTPRINT( "validate" )
  • src/tests/.expect/64/sched-ext-parse.txt

    r4dfa562 ra2d4d1c  
    10551055static inline struct condition ___operator_assign__F10scondition_R10scondition10scondition_autogen___1(struct condition *___dst__R10scondition_1, struct condition ___src__10scondition_1){
    10561056    struct condition ___ret__10scondition_1;
    1057     struct __condition_blocked_queue_t _tmp_cp56;
     1057    struct __condition_blocked_queue_t _tmp_cp4;
    10581058    struct __condition_blocked_queue_t _tmp_cp_ret29;
    1059     ((void)(((void)(_tmp_cp_ret29=___operator_assign__F28s__condition_blocked_queue_t_R28s__condition_blocked_queue_t28s__condition_blocked_queue_t_autogen___1((&(*___dst__R10scondition_1).__blocked__28s__condition_blocked_queue_t_1), (((void)___constructor__F_R28s__condition_blocked_queue_t28s__condition_blocked_queue_t_autogen___1((&_tmp_cp56), ___src__10scondition_1.__blocked__28s__condition_blocked_queue_t_1)) , _tmp_cp56)))) , _tmp_cp_ret29));
     1059    ((void)(((void)(_tmp_cp_ret29=___operator_assign__F28s__condition_blocked_queue_t_R28s__condition_blocked_queue_t28s__condition_blocked_queue_t_autogen___1((&(*___dst__R10scondition_1).__blocked__28s__condition_blocked_queue_t_1), (((void)___constructor__F_R28s__condition_blocked_queue_t28s__condition_blocked_queue_t_autogen___1((&_tmp_cp4), ___src__10scondition_1.__blocked__28s__condition_blocked_queue_t_1)) , _tmp_cp4)))) , _tmp_cp_ret29));
    10601060    ((void)___destructor__F_R28s__condition_blocked_queue_t_autogen___1((&_tmp_cp_ret29)));
    1061     ((void)___destructor__F_R28s__condition_blocked_queue_t_autogen___1((&_tmp_cp56)));
     1061    ((void)___destructor__F_R28s__condition_blocked_queue_t_autogen___1((&_tmp_cp4)));
    10621062    ((void)((*___dst__R10scondition_1).__monitors__PP13smonitor_desc_1=___src__10scondition_1.__monitors__PP13smonitor_desc_1));
    10631063    ((void)((*___dst__R10scondition_1).__monitor_count__Us_1=___src__10scondition_1.__monitor_count__Us_1));
     
    11551155static inline struct M ___operator_assign__F2sM_R2sM2sM_autogen___1(struct M *___dst__R2sM_1, struct M ___src__2sM_1){
    11561156    struct M ___ret__2sM_1;
    1157     struct monitor_desc _tmp_cp60;
     1157    struct monitor_desc _tmp_cp5;
    11581158    struct monitor_desc _tmp_cp_ret31;
    1159     ((void)(((void)(_tmp_cp_ret31=___operator_assign__F13smonitor_desc_R13smonitor_desc13smonitor_desc_autogen___1((&(*___dst__R2sM_1).____mon__13smonitor_desc_1), (((void)___constructor__F_R13smonitor_desc13smonitor_desc_autogen___1((&_tmp_cp60), ___src__2sM_1.____mon__13smonitor_desc_1)) , _tmp_cp60)))) , _tmp_cp_ret31));
     1159    ((void)(((void)(_tmp_cp_ret31=___operator_assign__F13smonitor_desc_R13smonitor_desc13smonitor_desc_autogen___1((&(*___dst__R2sM_1).____mon__13smonitor_desc_1), (((void)___constructor__F_R13smonitor_desc13smonitor_desc_autogen___1((&_tmp_cp5), ___src__2sM_1.____mon__13smonitor_desc_1)) , _tmp_cp5)))) , _tmp_cp_ret31));
    11601160    ((void)___destructor__F_R13smonitor_desc_autogen___1((&_tmp_cp_ret31)));
    1161     ((void)___destructor__F_R13smonitor_desc_autogen___1((&_tmp_cp60)));
     1161    ((void)___destructor__F_R13smonitor_desc_autogen___1((&_tmp_cp5)));
    11621162    ((void)___constructor__F_R2sM2sM_autogen___1((&___ret__2sM_1), ___src__2sM_1));
    11631163    return ((struct M )___ret__2sM_1);
Note: See TracChangeset for help on using the changeset viewer.