Ignore:
Timestamp:
Dec 14, 2016, 3:21:54 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
9facf3b
Parents:
a64644c
Message:

autogenerate functions for seen tuple types

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    ra64644c r1486116  
    2424#include "MakeLibCfa.h"
    2525#include "Autogen.h"
     26#include "GenPoly/ScopedSet.h"
     27#include "SymTab/Mangler.h"
     28#include "GenPoly/DeclMutator.h"
    2629
    2730namespace SymTab {
     
    2932
    3033        class AutogenerateRoutines : public Visitor {
    31                 public:
     34          public:
    3235                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    3336
     
    4851                virtual void visit( SwitchStmt *switchStmt );
    4952
    50                 AutogenerateRoutines() : functionNesting( 0 ) {}
    51                 private:
     53          private:
    5254                template< typename StmtClass > void visitStatement( StmtClass *stmt );
    5355
    5456                std::list< Declaration * > declsToAdd;
    5557                std::set< std::string > structsDone;
    56                 unsigned int functionNesting;     // current level of nested functions
     58                unsigned int functionNesting = 0;     // current level of nested functions
    5759        };
    5860
     61        /// generates routines for tuple types.
     62        /// Doesn't really need to be a mutator, but it's easier to reuse DeclMutator than it is to use AddVisit
     63        /// or anything we currently have that supports adding new declarations for visitors
     64        class AutogenTupleRoutines : public GenPoly::DeclMutator {
     65          public:
     66                typedef GenPoly::DeclMutator Parent;
     67                using Parent::mutate;
     68
     69                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
     70
     71                virtual Type * mutate( TupleType *tupleType );
     72
     73                virtual CompoundStmt * mutate( CompoundStmt *compoundStmt );
     74
     75          private:
     76                unsigned int functionNesting = 0;     // current level of nested functions
     77                GenPoly::ScopedSet< std::string > seenTuples;
     78        };
     79
    5980        void autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    60                 AutogenerateRoutines visitor;
    61                 acceptAndAdd( translationUnit, visitor, false );
     81                AutogenerateRoutines generator;
     82                acceptAndAdd( translationUnit, generator, false );
     83
     84                // needs to be done separately because AutogenerateRoutines skips types that appear as function arguments, etc.
     85                // AutogenTupleRoutines tupleGenerator;
     86                // tupleGenerator.mutateDeclarationList( translationUnit );
    6287        }
    6388
     
    93118
    94119        /// given type T, generate type of assignment, i.e. function type T (*) (T *, T)
    95         FunctionType * genAssignType( Type * paramType, const std::list< Expression* > & params = std::list< Expression* >() ) {
     120        FunctionType * genAssignType( Type * paramType ) {
    96121                FunctionType *ftype = genCopyType( paramType );
    97122                ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr );
     
    173198                copyCtorDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, genEnumAssign( copyCtorType, assignDecl ) ) );
    174199
    175                 declsToAdd.push_back( assignDecl );
    176200                declsToAdd.push_back( ctorDecl );
    177201                declsToAdd.push_back( copyCtorDecl );
    178202                declsToAdd.push_back( dtorDecl );
     203                declsToAdd.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return
    179204        }
    180205
     
    311336                        // forward declare if top-level struct, so that
    312337                        // type is complete as soon as its body ends
     338                        // Note: this is necessary if we want structs which contain
     339                        // generic (otype) structs as members.
    313340                        addForwardDecl( assignDecl, declsToAdd );
    314341                        addForwardDecl( ctorDecl, declsToAdd );
     
    352379                makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dtorDecl, isDynamicLayout, false );
    353380
    354                 if ( ! isDynamicLayout ) {
    355                         assert( assignType->get_parameters().size() == 2 );
    356                         ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( assignType->get_parameters().back() );
    357                         assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    358                 }
    359 
    360                 declsToAdd.push_back( assignDecl );
     381                assert( assignType->get_parameters().size() == 2 );
     382                ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( assignType->get_parameters().back() );
     383                assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     384
    361385                declsToAdd.push_back( ctorDecl );
    362386                declsToAdd.push_back( copyCtorDecl );
    363387                declsToAdd.push_back( dtorDecl );
     388                declsToAdd.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return
    364389                declsToAdd.splice( declsToAdd.end(), memCtors );
    365390        }
     
    402427                // void ?{}(T *); void ^?{}(T *);
    403428                FunctionType *ctorType = genDefaultType( refType );
    404                 cloneAll( typeParams, ctorType->get_forall() );
    405429                FunctionType *dtorType = genDefaultType( refType );
    406                 cloneAll( typeParams, dtorType->get_forall() );
    407430
    408431                // copy ctor needs both parameters
    409432                // void ?{}(T *, T);
    410433                FunctionType *copyCtorType = genCopyType( refType );
    411                 cloneAll( typeParams, copyCtorType->get_forall() );
    412434
    413435                // assignment needs both and return value
    414436                // T ?=?(T *, T);
    415437                FunctionType *assignType = genAssignType( refType );
     438
     439                cloneAll( typeParams, ctorType->get_forall() );
     440                cloneAll( typeParams, dtorType->get_forall() );
     441                cloneAll( typeParams, copyCtorType->get_forall() );
    416442                cloneAll( typeParams, assignType->get_forall() );
    417443
     
    448474                }
    449475
    450                 declsToAdd.push_back( assignDecl );
    451476                declsToAdd.push_back( ctorDecl );
    452477                declsToAdd.push_back( copyCtorDecl );
    453478                declsToAdd.push_back( dtorDecl );
     479                declsToAdd.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return
    454480                declsToAdd.splice( declsToAdd.end(), memCtors );
    455481        }
     
    552578                visitStatement( switchStmt );
    553579        }
     580
     581        void makeTupleFunctionBody( FunctionDecl * function ) {
     582                FunctionType * ftype = function->get_functionType();
     583                assertf( ftype->get_parameters().size() == 1 || ftype->get_parameters().size() == 2, "too many parameters in generated tuple function" );
     584
     585                UntypedExpr * untyped = new UntypedExpr( new NameExpr( function->get_name() ) );
     586
     587                /// xxx - &* is used to make this easier for later passes to handle
     588                untyped->get_args().push_back( new AddressExpr( UntypedExpr::createDeref( new VariableExpr( ftype->get_parameters().front() ) ) ) );
     589                if ( ftype->get_parameters().size() == 2 ) {
     590                        untyped->get_args().push_back( new VariableExpr( ftype->get_parameters().back() ) );
     591                }
     592                function->get_statements()->get_kids().push_back( new ExprStmt( noLabels, untyped ) );
     593                function->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, UntypedExpr::createDeref( new VariableExpr( ftype->get_parameters().front() ) ) ) );
     594        }
     595
     596        Type * AutogenTupleRoutines::mutate( TupleType * tupleType ) {
     597                tupleType = safe_dynamic_cast< TupleType * >( Parent::mutate( tupleType ) );
     598                std::string mangleName = SymTab::Mangler::mangleType( tupleType );
     599                if ( seenTuples.find( mangleName ) != seenTuples.end() ) return tupleType;
     600                seenTuples.insert( mangleName );
     601
     602                // T ?=?(T *, T);
     603                FunctionType *assignType = genAssignType( tupleType );
     604
     605                // void ?{}(T *); void ^?{}(T *);
     606                FunctionType *ctorType = genDefaultType( tupleType );
     607                FunctionType *dtorType = genDefaultType( tupleType );
     608
     609                // void ?{}(T *, T);
     610                FunctionType *copyCtorType = genCopyType( tupleType );
     611
     612                std::set< TypeDecl* > done;
     613                std::list< TypeDecl * > typeParams;
     614                for ( Type * t : *tupleType ) {
     615                        if ( TypeInstType * ty = dynamic_cast< TypeInstType * >( t ) ) {
     616                                if ( ! done.count( ty->get_baseType() ) ) {
     617                                        TypeDecl * newDecl = new TypeDecl( ty->get_baseType()->get_name(), DeclarationNode::NoStorageClass, nullptr, TypeDecl::Any );
     618                                        TypeInstType * inst = new TypeInstType( Type::Qualifiers(), newDecl->get_name(), newDecl );
     619                                        newDecl->get_assertions().push_back( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, genAssignType( inst ), nullptr, true, false ) );
     620                                        newDecl->get_assertions().push_back( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, genDefaultType( inst ), nullptr, true, false ) );
     621                                        newDecl->get_assertions().push_back( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, genCopyType( inst ), nullptr, true, false ) );
     622                                        newDecl->get_assertions().push_back( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, genDefaultType( inst ), nullptr, true, false ) );
     623                                        typeParams.push_back( newDecl );
     624                                        done.insert( ty->get_baseType() );
     625                                }
     626                        }
     627                }
     628                cloneAll( typeParams, ctorType->get_forall() );
     629                cloneAll( typeParams, dtorType->get_forall() );
     630                cloneAll( typeParams, copyCtorType->get_forall() );
     631                cloneAll( typeParams, assignType->get_forall() );
     632
     633                FunctionDecl *assignDecl = genFunc( "?=?", assignType, functionNesting );
     634                FunctionDecl *ctorDecl = genFunc( "?{}", ctorType, functionNesting );
     635                FunctionDecl *copyCtorDecl = genFunc( "?{}", copyCtorType, functionNesting );
     636                FunctionDecl *dtorDecl = genFunc( "^?{}", dtorType, functionNesting );
     637
     638                makeTupleFunctionBody( assignDecl );
     639                makeTupleFunctionBody( ctorDecl );
     640                makeTupleFunctionBody( copyCtorDecl );
     641                makeTupleFunctionBody( dtorDecl );
     642
     643                addDeclaration( ctorDecl );
     644                addDeclaration( copyCtorDecl );
     645                addDeclaration( dtorDecl );
     646                addDeclaration( assignDecl ); // assignment should come last since it uses copy constructor in return
     647
     648                return tupleType;
     649        }
     650
     651        DeclarationWithType * AutogenTupleRoutines::mutate( FunctionDecl *functionDecl ) {
     652                functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
     653                mutateAll( functionDecl->get_oldDecls(), *this );
     654                functionNesting += 1;
     655                functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     656                functionNesting -= 1;
     657                return functionDecl;
     658        }
     659
     660        CompoundStmt * AutogenTupleRoutines::mutate( CompoundStmt *compoundStmt ) {
     661                seenTuples.beginScope();
     662                compoundStmt = safe_dynamic_cast< CompoundStmt * >( Parent::mutate( compoundStmt ) );
     663                seenTuples.endScope();
     664                return compoundStmt;
     665        }
    554666} // SymTab
Note: See TracChangeset for help on using the changeset viewer.