Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    rb16898e rb6fe7e6  
    3333#include "SymTab/Autogen.h"
    3434#include "GenPoly/PolyMutator.h"
     35#include "GenPoly/DeclMutator.h"
    3536#include "SynTree/AddStmtVisitor.h"
    3637#include "CodeGen/GenType.h"  // for warnings
     
    216217                        SymTab::Indexer & indexer;
    217218                };
     219
     220                class FixCtorExprs : public GenPoly::DeclMutator {
     221                  public:
     222                        /// expands ConstructorExpr nodes into comma expressions, using a temporary for the first argument
     223                        static void fix( std::list< Declaration * > & translationUnit );
     224
     225                        virtual Expression * mutate( ConstructorExpr * ctorExpr );
     226                };
    218227        } // namespace
    219228
     
    221230                // fixes ConstructorInit for global variables. should happen before fixInitializers.
    222231                InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
     232
    223233
    224234                InsertImplicitCalls::insert( translationUnit );
     
    231241
    232242                GenStructMemberCalls::generate( translationUnit );
     243                // xxx - ctor expansion currently has to be after FixCopyCtors, because there is currently a
     244                // hack in the way untyped assignments are generated, where the first argument cannot have
     245                // its address taken because of the way codegeneration handles UntypedExpr vs. ApplicationExpr.
     246                // Thus such assignment exprs must never pushed through expression resolution (and thus should
     247                // not go through the FixCopyCtors pass), otherwise they will fail -- guaranteed.
     248                // Also needs to happen after GenStructMemberCalls, since otherwise member constructors exprs
     249                // don't look right, and a member can be constructed more than once.
     250                FixCtorExprs::fix( translationUnit );
    233251        }
    234252
     
    283301                                throw warner.errors;
    284302                        }
     303                }
     304
     305                void FixCtorExprs::fix( std::list< Declaration * > & translationUnit ) {
     306                        FixCtorExprs fixer;
     307                        fixer.mutateDeclarationList( translationUnit );
    285308                }
    286309
     
    480503                                        retExpr = deref;
    481504                                } // if
    482                                 // xxx - might need to set env on retExpr...
    483                                 // retExpr->set_env( env->clone() );
     505                                retExpr->set_env( env->clone() );
    484506                                return retExpr;
    485507                        } else {
     
    914936                        return safe_dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untypedExpr, indexer ) );
    915937                }
     938
     939                Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
     940                        static UniqueName tempNamer( "_tmp_ctor_expr" );
     941                        assert( ctorExpr->get_results().size() == 1 );
     942                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_results().front()->clone(), nullptr );
     943                        addDeclaration( tmp );
     944
     945                        ApplicationExpr * callExpr = safe_dynamic_cast< ApplicationExpr * > ( ctorExpr->get_callExpr() );
     946                        TypeSubstitution * env = ctorExpr->get_env();
     947                        ctorExpr->set_callExpr( nullptr );
     948                        ctorExpr->set_env( nullptr );
     949
     950                        Expression *& firstArg = callExpr->get_args().front();
     951                        UntypedExpr * assign = new UntypedExpr( new NameExpr( "?=?" ) );
     952                        assign->get_args().push_back( new VariableExpr( tmp ) );
     953                        assign->get_args().push_back( firstArg );
     954                        cloneAll( ctorExpr->get_results(), assign->get_results() );
     955                        firstArg = assign;
     956
     957                        CommaExpr * commaExpr = new CommaExpr( callExpr, new VariableExpr( tmp ) );
     958                        commaExpr->set_env( env );
     959                        delete ctorExpr;
     960                        return commaExpr;
     961                }
    916962        } // namespace
    917963} // namespace InitTweak
Note: See TracChangeset for help on using the changeset viewer.