Changes in / [ada0eb06:7dc09294]


Ignore:
Location:
src
Files:
1 added
16 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rada0eb06 r7dc09294  
    258258
    259259        void CodeGenerator::visit( TraitDecl * traitDecl ) {
    260                 assertf( ! genC, "TraitDecl nodes should not reach code generation." );
     260                assertf( ! genC, "TraitDecls should not reach code generation." );
    261261                extension( traitDecl );
    262262                handleAggregate( traitDecl, "trait " );
     
    271271
    272272        void CodeGenerator::visit( TypeDecl * typeDecl ) {
    273                 if ( genC ) {
    274                         // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
    275                         // still to be done
    276                         extension( typeDecl );
    277                         output << "extern unsigned long " << typeDecl->get_name();
    278                         if ( typeDecl->get_base() ) {
    279                                 output << " = sizeof( " << genType( typeDecl->get_base(), "", pretty, genC ) << " )";
    280                         } // if
    281                 } else {
    282                         output << typeDecl->genTypeString() << " " << typeDecl->get_name();
    283                         if ( typeDecl->get_kind() != TypeDecl::Any && typeDecl->get_sized() ) {
    284                                 output << " | sized(" << typeDecl->get_name() << ")";
    285                         }
    286                         if ( ! typeDecl->get_assertions().empty() ) {
    287                                 output << " | { ";
    288                                 genCommaList( typeDecl->get_assertions().begin(), typeDecl->get_assertions().end() );
    289                                 output << " }";
    290                         }
     273                assertf( ! genC, "TypeDecls should not reach code generation." );
     274                output << typeDecl->genTypeString() << " " << typeDecl->get_name();
     275                if ( typeDecl->get_kind() != TypeDecl::Any && typeDecl->get_sized() ) {
     276                        output << " | sized(" << typeDecl->get_name() << ")";
     277                }
     278                if ( ! typeDecl->get_assertions().empty() ) {
     279                        output << " | { ";
     280                        genCommaList( typeDecl->get_assertions().begin(), typeDecl->get_assertions().end() );
     281                        output << " }";
    291282                }
    292283        }
  • src/Common/PassVisitor.h

    rada0eb06 r7dc09294  
    145145        virtual Declaration* mutate( EnumDecl *aggregateDecl ) override final;
    146146        virtual Declaration* mutate( TraitDecl *aggregateDecl ) override final;
    147         virtual TypeDecl* mutate( TypeDecl *typeDecl ) override final;
     147        virtual Declaration* mutate( TypeDecl *typeDecl ) override final;
    148148        virtual Declaration* mutate( TypedefDecl *typeDecl ) override final;
    149149        virtual AsmDecl* mutate( AsmDecl *asmDecl ) override final;
  • src/Common/PassVisitor.impl.h

    rada0eb06 r7dc09294  
    976976
    977977template< typename pass_type >
    978 TypeDecl * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
    979         MUTATE_BODY( TypeDecl, node );
     978Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
     979        MUTATE_BODY( Declaration, node );
    980980}
    981981
  • src/Common/utility.h

    rada0eb06 r7dc09294  
    370370}
    371371
     372// -----------------------------------------------------------------------------
     373// Helper struct and function to support
     374// for ( val : lazy_map( container1, f ) ) {}
     375// syntax to have a for each that iterates a container, mapping each element by applying f
     376template< typename T, typename Func >
     377struct lambda_iterate_t {
     378        const T & ref;
     379        std::function<Func> f;
     380
     381        struct iterator {
     382                typedef decltype(begin(ref)) Iter;
     383                Iter it;
     384                std::function<Func> f;
     385                iterator( Iter it, std::function<Func> f ) : it(it), f(f) {}
     386                iterator & operator++() {
     387                        ++it; return *this;
     388                }
     389                bool operator!=( const iterator &other ) const { return it != other.it; }
     390                auto operator*() const -> decltype(f(*it)) { return f(*it); }
     391        };
     392
     393        lambda_iterate_t( const T & ref, std::function<Func> f ) : ref(ref), f(f) {}
     394
     395        auto begin() const -> decltype(iterator(std::begin(ref), f)) { return iterator(std::begin(ref), f); }
     396        auto end() const   -> decltype(iterator(std::end(ref), f)) { return iterator(std::end(ref), f); }
     397};
     398
     399template< typename... Args >
     400lambda_iterate_t<Args...> lazy_map( const Args &... args ) {
     401        return lambda_iterate_t<Args...>( args...);
     402}
     403
     404
     405
    372406// Local Variables: //
    373407// tab-width: 4 //
  • src/GenPoly/Box.cc

    rada0eb06 r7dc09294  
    2727
    2828#include "CodeGen/OperatorTable.h"
     29#include "Common/PassVisitor.h"          // for PassVisitor
    2930#include "Common/ScopedMap.h"            // for ScopedMap, ScopedMap<>::iter...
    3031#include "Common/SemanticError.h"        // for SemanticError
     
    157158                /// * Calculates polymorphic offsetof expressions from offset array
    158159                /// * Inserts dynamic calculation of polymorphic type layouts where needed
    159                 class PolyGenericCalculator final : public PolyMutator {
     160                class PolyGenericCalculator final : public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
    160161                public:
    161                         typedef PolyMutator Parent;
    162                         using Parent::mutate;
    163 
    164162                        PolyGenericCalculator();
    165163
    166                         template< typename DeclClass >
    167                         DeclClass *handleDecl( DeclClass *decl, Type *type );
    168                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
    169                         virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override;
    170                         virtual TypedefDecl *mutate( TypedefDecl *objectDecl ) override;
    171                         virtual TypeDecl *mutate( TypeDecl *objectDecl ) override;
    172                         virtual Statement *mutate( DeclStmt *declStmt ) override;
    173                         virtual Type *mutate( PointerType *pointerType ) override;
    174                         virtual Type *mutate( FunctionType *funcType ) override;
    175                         virtual Expression *mutate( MemberExpr *memberExpr ) override;
    176                         virtual Expression *mutate( SizeofExpr *sizeofExpr ) override;
    177                         virtual Expression *mutate( AlignofExpr *alignofExpr ) override;
    178                         virtual Expression *mutate( OffsetofExpr *offsetofExpr ) override;
    179                         virtual Expression *mutate( OffsetPackExpr *offsetPackExpr ) override;
    180 
    181                         virtual void doBeginScope() override;
    182                         virtual void doEndScope() override;
     164                        void premutate( ObjectDecl *objectDecl );
     165                        void premutate( FunctionDecl *functionDecl );
     166                        void premutate( TypedefDecl *objectDecl );
     167                        void premutate( TypeDecl *objectDecl );
     168                        Declaration * postmutate( TypeDecl *TraitDecl );
     169                        void premutate( PointerType *pointerType );
     170                        void premutate( FunctionType *funcType );
     171                        void premutate( DeclStmt *declStmt );
     172                        Expression *postmutate( MemberExpr *memberExpr );
     173                        Expression *postmutate( SizeofExpr *sizeofExpr );
     174                        Expression *postmutate( AlignofExpr *alignofExpr );
     175                        Expression *postmutate( OffsetofExpr *offsetofExpr );
     176                        Expression *postmutate( OffsetPackExpr *offsetPackExpr );
     177
     178                        void beginScope();
     179                        void endScope();
    183180
    184181                private:
     
    194191                        /// Exits the type-variable scope
    195192                        void endTypeScope();
     193                        /// Enters a new scope for knowLayouts and knownOffsets and queues exit calls
     194                        void beginGenericScope();
    196195
    197196                        ScopedSet< std::string > knownLayouts;          ///< Set of generic type layouts known in the current scope, indexed by sizeofName
    198197                        ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
    199198                        UniqueName bufNamer;                           ///< Namer for VLA buffers
     199                        TyVarMap scopeTyVars;
    200200                };
    201201
     
    250250                Pass1 pass1;
    251251                Pass2 pass2;
    252                 PolyGenericCalculator polyCalculator;
     252                PassVisitor<PolyGenericCalculator> polyCalculator;
    253253                Pass3 pass3;
    254254
     
    256256                mutateTranslationUnit/*All*/( translationUnit, pass1 );
    257257                mutateTranslationUnit/*All*/( translationUnit, pass2 );
    258                 mutateTranslationUnit/*All*/( translationUnit, polyCalculator );
     258                mutateAll( translationUnit, polyCalculator );
    259259                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    260260        }
     
    555555                TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
    556556                        addToTyVarMap( typeDecl, scopeTyVars );
    557                         return Mutator::mutate( typeDecl );
     557                        return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
    558558                }
    559559
     
    762762                                } else if ( arg->get_result()->get_lvalue() ) {
    763763                                        // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations.
     764                                        // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) {
     765                                        //      if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){
     766                                        //              // temporary hack - don't box arrays, because &arr is not the same as &arr[0]
     767                                        //              return;
     768                                        //      }
     769                                        // }
    764770                                        arg =  generalizedLvalue( new AddressExpr( arg ) );
    765771                                        if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) {
     
    13531359                                return handleDecl( typeDecl );
    13541360                        } else {
    1355                                 return Parent::mutate( typeDecl );
     1361                                return dynamic_cast<TypeDecl*>( Parent::mutate( typeDecl ) );
    13561362                        }
    13571363                }
     
    14661472
    14671473                PolyGenericCalculator::PolyGenericCalculator()
    1468                         : Parent(), knownLayouts(), knownOffsets(), bufNamer( "_buf" ) {}
     1474                        : knownLayouts(), knownOffsets(), bufNamer( "_buf" ), scopeTyVars( TypeDecl::Data{} ) {}
    14691475
    14701476                void PolyGenericCalculator::beginTypeScope( Type *ty ) {
    1471                         scopeTyVars.beginScope();
     1477                        GuardScope( scopeTyVars );
    14721478                        makeTyVarMap( ty, scopeTyVars );
    14731479                }
    14741480
    1475                 void PolyGenericCalculator::endTypeScope() {
    1476                         scopeTyVars.endScope();
    1477                 }
    1478 
    1479                 template< typename DeclClass >
    1480                 DeclClass * PolyGenericCalculator::handleDecl( DeclClass *decl, Type *type ) {
    1481                         beginTypeScope( type );
    1482                         // knownLayouts.beginScope();
    1483                         // knownOffsets.beginScope();
    1484 
    1485                         DeclClass *ret = static_cast< DeclClass *>( Parent::mutate( decl ) );
    1486 
    1487                         // knownOffsets.endScope();
    1488                         // knownLayouts.endScope();
    1489                         endTypeScope();
    1490                         return ret;
    1491                 }
    1492 
    1493                 ObjectDecl * PolyGenericCalculator::mutate( ObjectDecl *objectDecl ) {
    1494                         return handleDecl( objectDecl, objectDecl->get_type() );
    1495                 }
    1496 
    1497                 DeclarationWithType * PolyGenericCalculator::mutate( FunctionDecl *functionDecl ) {
    1498                         knownLayouts.beginScope();
    1499                         knownOffsets.beginScope();
    1500 
    1501                         DeclarationWithType * decl = handleDecl( functionDecl, functionDecl->get_functionType() );
    1502                         knownOffsets.endScope();
    1503                         knownLayouts.endScope();
    1504                         return decl;
    1505                 }
    1506 
    1507                 TypedefDecl * PolyGenericCalculator::mutate( TypedefDecl *typedefDecl ) {
    1508                         return handleDecl( typedefDecl, typedefDecl->get_base() );
    1509                 }
    1510 
    1511                 TypeDecl * PolyGenericCalculator::mutate( TypeDecl *typeDecl ) {
     1481                void PolyGenericCalculator::beginGenericScope() {
     1482                        GuardScope( *this );
     1483                }
     1484
     1485                void PolyGenericCalculator::premutate( ObjectDecl *objectDecl ) {
     1486                        beginTypeScope( objectDecl->get_type() );
     1487                }
     1488
     1489                void PolyGenericCalculator::premutate( FunctionDecl *functionDecl ) {
     1490                        beginGenericScope();
     1491
     1492                        beginTypeScope( functionDecl->get_functionType() );
     1493                }
     1494
     1495                void PolyGenericCalculator::premutate( TypedefDecl *typedefDecl ) {
     1496                        beginTypeScope( typedefDecl->get_base() );
     1497                }
     1498
     1499                void PolyGenericCalculator::premutate( TypeDecl * typeDecl ) {
    15121500                        addToTyVarMap( typeDecl, scopeTyVars );
    1513                         return Parent::mutate( typeDecl );
    1514                 }
    1515 
    1516                 Type * PolyGenericCalculator::mutate( PointerType *pointerType ) {
     1501                }
     1502
     1503                Declaration * PolyGenericCalculator::postmutate( TypeDecl *typeDecl ) {
     1504                        if ( Type * base = typeDecl->base ) {
     1505                                // add size/align variables for opaque type declarations
     1506                                TypeInstType inst( Type::Qualifiers(), typeDecl->name, typeDecl );
     1507                                std::string typeName = mangleType( &inst );
     1508                                Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     1509
     1510                                ObjectDecl * sizeDecl = ObjectDecl::newObject( sizeofName( typeName ), layoutType, new SingleInit( new SizeofExpr( base->clone() ) ) );
     1511                                ObjectDecl * alignDecl = ObjectDecl::newObject( alignofName( typeName ), layoutType->clone(), new SingleInit( new AlignofExpr( base->clone() ) ) );
     1512
     1513                                // ensure that the initializing sizeof/alignof exprs are properly mutated
     1514                                sizeDecl->acceptMutator( *visitor );
     1515                                alignDecl->acceptMutator( *visitor );
     1516
     1517                                // can't use makeVar, because it inserts into stmtsToAdd and TypeDecls can occur at global scope
     1518                                declsToAddAfter.push_back( alignDecl );
     1519                                // replace with sizeDecl
     1520                                return sizeDecl;
     1521                        }
     1522                        return typeDecl;
     1523                }
     1524
     1525                void PolyGenericCalculator::premutate( PointerType *pointerType ) {
    15171526                        beginTypeScope( pointerType );
    1518 
    1519                         Type *ret = Parent::mutate( pointerType );
    1520 
    1521                         endTypeScope();
    1522                         return ret;
    1523                 }
    1524 
    1525                 Type * PolyGenericCalculator::mutate( FunctionType *funcType ) {
     1527                }
     1528
     1529                void PolyGenericCalculator::premutate( FunctionType *funcType ) {
    15261530                        beginTypeScope( funcType );
    15271531
     
    15341538                                }
    15351539                        }
    1536 
    1537                         Type *ret = Parent::mutate( funcType );
    1538 
    1539                         endTypeScope();
    1540                         return ret;
    1541                 }
    1542 
    1543                 Statement *PolyGenericCalculator::mutate( DeclStmt *declStmt ) {
     1540                }
     1541
     1542                void PolyGenericCalculator::premutate( DeclStmt *declStmt ) {
    15441543                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
    15451544                                if ( findGeneric( objectDecl->get_type() ) ) {
     
    15501549                                                new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Kind::Char), new NameExpr( sizeofName( mangleType(declType) ) ),
    15511550                                                true, false, std::list<Attribute*>{ new Attribute( "aligned", std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ) } ), 0 );
    1552                                         stmtsToAdd.push_back( new DeclStmt( noLabels, newBuf ) );
     1551                                        stmtsToAddBefore.push_back( new DeclStmt( noLabels, newBuf ) );
    15531552
    15541553                                        delete objectDecl->get_init();
     
    15561555                                }
    15571556                        }
    1558                         return Parent::mutate( declStmt );
    15591557                }
    15601558
     
    15831581                }
    15841582
    1585                 Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) {
    1586                         // mutate, exiting early if no longer MemberExpr
    1587                         Expression *expr = Parent::mutate( memberExpr );
    1588                         memberExpr = dynamic_cast< MemberExpr* >( expr );
    1589                         if ( ! memberExpr ) return expr;
    1590 
     1583                Expression *PolyGenericCalculator::postmutate( MemberExpr *memberExpr ) {
    15911584                        // only mutate member expressions for polymorphic types
    15921585                        int tyDepth;
     
    16351628                ObjectDecl *PolyGenericCalculator::makeVar( const std::string &name, Type *type, Initializer *init ) {
    16361629                        ObjectDecl *newObj = new ObjectDecl( name, Type::StorageClasses(), LinkageSpec::C, 0, type, init );
    1637                         stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
     1630                        stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
    16381631                        return newObj;
    16391632                }
     
    17141707                                        addOtypeParamsToLayoutCall( layoutCall, otypeParams );
    17151708
    1716                                         stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) );
     1709                                        stmtsToAddBefore.push_back( new ExprStmt( noLabels, layoutCall ) );
    17171710                                }
    17181711
     
    17401733                                addOtypeParamsToLayoutCall( layoutCall, otypeParams );
    17411734
    1742                                 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) );
     1735                                stmtsToAddBefore.push_back( new ExprStmt( noLabels, layoutCall ) );
    17431736
    17441737                                return true;
     
    17481741                }
    17491742
    1750                 Expression *PolyGenericCalculator::mutate( SizeofExpr *sizeofExpr ) {
     1743                Expression *PolyGenericCalculator::postmutate( SizeofExpr *sizeofExpr ) {
    17511744                        Type *ty = sizeofExpr->get_isType() ? sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result();
    17521745                        if ( findGeneric( ty ) ) {
     
    17581751                }
    17591752
    1760                 Expression *PolyGenericCalculator::mutate( AlignofExpr *alignofExpr ) {
     1753                Expression *PolyGenericCalculator::postmutate( AlignofExpr *alignofExpr ) {
    17611754                        Type *ty = alignofExpr->get_isType() ? alignofExpr->get_type() : alignofExpr->get_expr()->get_result();
    17621755                        if ( findGeneric( ty ) ) {
     
    17681761                }
    17691762
    1770                 Expression *PolyGenericCalculator::mutate( OffsetofExpr *offsetofExpr ) {
    1771                         // mutate, exiting early if no longer OffsetofExpr
    1772                         Expression *expr = Parent::mutate( offsetofExpr );
    1773                         offsetofExpr = dynamic_cast< OffsetofExpr* >( expr );
    1774                         if ( ! offsetofExpr ) return expr;
    1775 
     1763                Expression *PolyGenericCalculator::postmutate( OffsetofExpr *offsetofExpr ) {
    17761764                        // only mutate expressions for polymorphic structs/unions
    17771765                        Type *ty = offsetofExpr->get_type();
     
    17931781                }
    17941782
    1795                 Expression *PolyGenericCalculator::mutate( OffsetPackExpr *offsetPackExpr ) {
     1783                Expression *PolyGenericCalculator::postmutate( OffsetPackExpr *offsetPackExpr ) {
    17961784                        StructInstType *ty = offsetPackExpr->get_type();
    17971785
     
    18321820                }
    18331821
    1834                 void PolyGenericCalculator::doBeginScope() {
     1822                void PolyGenericCalculator::beginScope() {
    18351823                        knownLayouts.beginScope();
    18361824                        knownOffsets.beginScope();
    18371825                }
    18381826
    1839                 void PolyGenericCalculator::doEndScope() {
     1827                void PolyGenericCalculator::endScope() {
    18401828                        knownLayouts.endScope();
    18411829                        knownOffsets.endScope();
     
    18941882
    18951883                        addToTyVarMap( typeDecl, scopeTyVars );
    1896                         return Mutator::mutate( typeDecl );
     1884                        return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) );
    18971885                }
    18981886
  • src/Parser/DeclarationNode.cc

    rada0eb06 r7dc09294  
    333333DeclarationNode * DeclarationNode::newTypeDecl( string * name, DeclarationNode * typeParams ) {
    334334        DeclarationNode * newnode = new DeclarationNode;
     335        newnode->name = name;
    335336        newnode->type = new TypeData( TypeData::Symbolic );
    336337        newnode->type->symbolic.isTypedef = false;
    337338        newnode->type->symbolic.params = typeParams;
    338         newnode->type->symbolic.name = name;
    339339        return newnode;
    340340} // DeclarationNode::newTypeDecl
  • src/ResolvExpr/CastCost.cc

    rada0eb06 r7dc09294  
    4545                                }
    4646                        } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
    47                                 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    4847                                // all typedefs should be gone by this point
    49                                 assert( type );
     48                                TypeDecl *type = safe_dynamic_cast< TypeDecl* >( namedType );
    5049                                if ( type->get_base() ) {
    5150                                        return castCost( src, type->get_base(), indexer, env ) + Cost::safe;
  • src/ResolvExpr/ConversionCost.cc

    rada0eb06 r7dc09294  
    9292
    9393        Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    94                 PRINT( std::cerr << "convert to reference cost..." << std::endl; )
     94                PRINT( std::cerr << "convert to reference cost... diff " << diff << std::endl; )
    9595                if ( diff > 0 ) {
    9696                        // TODO: document this
     
    128128                        ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
    129129                        assert( diff == -1 && destAsRef );
     130                        PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
    130131                        if ( typesCompatibleIgnoreQualifiers( src, destAsRef->get_base(), indexer, env ) ) {
    131132                                PRINT( std::cerr << "converting compatible base type" << std::endl; )
  • src/SymTab/Autogen.cc

    rada0eb06 r7dc09294  
    163163                // Routines at global scope marked "static" to prevent multiple definitions in separate translation units
    164164                // because each unit generates copies of the default routines for each aggregate.
    165 //              DeclarationNode::StorageClass sc = functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static;
    166165                Type::StorageClasses scs = functionNesting > 0 ? Type::StorageClasses() : Type::StorageClasses( Type::Static );
    167166                LinkageSpec::Spec spec = isIntrinsic ? LinkageSpec::Intrinsic : LinkageSpec::AutoGen;
     
    186185        /// using map and t, determines if is constructable, etc.
    187186        bool lookup( const TypeMap & map, Type * t ) {
     187                assertf( t, "Autogenerate lookup was given non-type: %s", toString( t ).c_str() );
    188188                if ( dynamic_cast< PointerType * >( t ) ) {
    189189                        // will need more complicated checking if we want this to work with pointer types, since currently
     
    200200
    201201        /// using map and aggr, examines each member to determine if constructor, etc. should be generated
    202         template<typename AggrDecl>
    203         bool shouldGenerate( const TypeMap & map, AggrDecl * aggr ) {
    204                 for ( Declaration * dcl : aggr->get_members() ) {
    205                         if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( dcl ) ) {
    206                                 if ( ! lookup( map, dwt->get_type() ) ) return false;
    207                         }
     202        template<typename Container>
     203        bool shouldGenerate( const TypeMap & map, const Container & container ) {
     204                for ( Type * t : container ) {
     205                        if ( ! lookup( map, t ) ) return false;
    208206                }
    209207                return true;
     
    211209
    212210        /// data structure for abstracting the generation of special functions
    213         template< typename OutputIterator >
     211        template< typename OutputIterator, typename Container >
    214212        struct FuncGenerator {
    215                 StructDecl *aggregateDecl;
    216                 StructInstType *refType;
     213                const Container & container;
     214                Type *refType;
    217215                unsigned int functionNesting;
    218216                const std::list< TypeDecl* > & typeParams;
    219217                OutputIterator out;
    220                 FuncGenerator( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) : aggregateDecl( aggregateDecl ), refType( refType ), functionNesting( functionNesting ), typeParams( typeParams ), out( out ) {}
     218                FuncGenerator( const Container & container, Type *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) : container( container ), refType( refType ), functionNesting( functionNesting ), typeParams( typeParams ), out( out ) {}
    221219
    222220                /// generates a function (?{}, ?=?, ^?{}) based on the data argument and members. If function is generated, inserts the type into the map.
    223221                void gen( const FuncData & data, bool concurrent_type ) {
    224                         if ( ! shouldGenerate( data.map, aggregateDecl ) ) return;
     222                        if ( ! shouldGenerate( data.map, container ) ) return;
    225223                        FunctionType * ftype = data.genType( refType );
    226224
    227225                        if(concurrent_type && CodeGen::isDestructor( data.fname )) {
    228                                 ftype->get_parameters().front()->get_type()->set_mutex( true );
    229                         }
    230 
    231                         cloneAll( typeParams, ftype->get_forall() );
     226                                ftype->parameters.front()->get_type()->set_mutex( true );
     227                        }
     228
     229                        cloneAll( typeParams, ftype->forall );
    232230                        *out++ = genFunc( data.fname, ftype, functionNesting );
    233231                        data.map.insert( Mangler::mangleType( refType ), true );
     
    235233        };
    236234
    237         template< typename OutputIterator >
    238         FuncGenerator<OutputIterator> makeFuncGenerator( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) {
    239                 return FuncGenerator<OutputIterator>( aggregateDecl, refType, functionNesting, typeParams, out );
     235        template< typename OutputIterator, typename Container >
     236        FuncGenerator<OutputIterator, Container> makeFuncGenerator( const Container & container, Type *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) {
     237                return FuncGenerator<OutputIterator, Container>( container, refType, functionNesting, typeParams, out );
    240238        }
    241239
     
    393391        }
    394392
     393        Type * declToType( Declaration * decl ) {
     394                if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
     395                        return dwt->get_type();
     396                }
     397                return nullptr;
     398        }
     399
    395400        /// generates struct constructors, destructor, and assignment functions
    396401        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
     
    406411                // generate each of the functions based on the supplied FuncData objects
    407412                std::list< FunctionDecl * > newFuncs;
    408                 auto generator = makeFuncGenerator( aggregateDecl, refType, functionNesting, typeParams, back_inserter( newFuncs ) );
     413                // structure that iterates aggregate decl members, returning their types
     414                auto generator = makeFuncGenerator( lazy_map( aggregateDecl->members, declToType ), refType, functionNesting, typeParams, back_inserter( newFuncs ) );
    409415                for ( const FuncData & d : data ) {
    410416                        generator.gen( d, aggregateDecl->is_thread() || aggregateDecl->is_monitor() );
     
    605611        }
    606612
     613        Type * declToTypeDeclBase( Declaration * decl ) {
     614                if ( TypeDecl * td = dynamic_cast< TypeDecl * >( decl ) ) {
     615                        return td->base;
     616                }
     617                return nullptr;
     618        }
     619
     620        // generate ctor/dtors/assign for typedecls, e.g., otype T = int *;
    607621        void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
    608                 TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
    609                 typeInst->set_baseType( typeDecl );
    610                 ObjectDecl *src = new ObjectDecl( "_src", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, typeInst->clone(), nullptr );
    611                 ObjectDecl *dst = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), typeInst->clone() ), nullptr );
    612 
    613                 std::list< Statement * > stmts;
    614                 if ( typeDecl->get_base() ) {
    615                         // xxx - generate ctor/dtors for typedecls, e.g.
    616                         // otype T = int *;
    617                         UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    618                         assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
    619                         assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
    620                         stmts.push_back( new ReturnStmt( std::list< Label >(), assign ) );
    621                 } // if
    622                 FunctionType *type = new FunctionType( Type::Qualifiers(), false );
    623                 type->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, typeInst, 0 ) );
    624                 type->get_parameters().push_back( dst );
    625                 type->get_parameters().push_back( src );
    626                 FunctionDecl *func = genFunc( "?=?", type, functionNesting );
    627                 func->get_statements()->get_kids() = stmts;
    628                 declsToAddAfter.push_back( func );
     622                if ( ! typeDecl->base ) return;
     623
     624                // generate each of the functions based on the supplied FuncData objects
     625                std::list< FunctionDecl * > newFuncs;
     626                std::list< Declaration * > tds { typeDecl };
     627                std::list< TypeDecl * > typeParams;
     628                TypeInstType refType( Type::Qualifiers(), typeDecl->name, typeDecl );
     629                auto generator = makeFuncGenerator( lazy_map( tds, declToTypeDeclBase ), &refType, functionNesting, typeParams, back_inserter( newFuncs ) );
     630                for ( const FuncData & d : data ) {
     631                        generator.gen( d, false );
     632                }
     633
     634                if ( functionNesting == 0 ) {
     635                        // forward declare if top-level struct, so that
     636                        // type is complete as soon as its body ends
     637                        // Note: this is necessary if we want structs which contain
     638                        // generic (otype) structs as members.
     639                        for ( FunctionDecl * dcl : newFuncs ) {
     640                                addForwardDecl( dcl, declsToAddAfter );
     641                        }
     642                }
     643
     644                for ( FunctionDecl * dcl : newFuncs ) {
     645                        FunctionType * ftype = dcl->type;
     646                        assertf( ftype->parameters.size() == 1 || ftype->parameters.size() == 2, "Incorrect number of parameters in autogenerated typedecl function: %zd", ftype->parameters.size() );
     647                        DeclarationWithType * dst = ftype->parameters.front();
     648                        DeclarationWithType * src = ftype->parameters.size() == 2 ? ftype->parameters.back() : nullptr;
     649                        // generate appropriate calls to member ctor, assignment
     650                        // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor
     651                        UntypedExpr * expr = new UntypedExpr( new NameExpr( dcl->name ) );
     652                        expr->args.push_back( new CastExpr( new VariableExpr( dst ), new ReferenceType( Type::Qualifiers(), typeDecl->base->clone() ) ) );
     653                        if ( src ) expr->args.push_back( new CastExpr( new VariableExpr( src ), typeDecl->base->clone() ) );
     654                        dcl->statements->kids.push_back( new ExprStmt( noLabels, expr ) );
     655                        if ( CodeGen::isAssignment( dcl->get_name() ) ) {
     656                                // assignment needs to return a value
     657                                FunctionType * assignType = dcl->type;
     658                                assert( assignType->parameters.size() == 2 );
     659                                ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( assignType->parameters.back() );
     660                                dcl->statements->kids.push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     661                        }
     662                        declsToAddAfter.push_back( dcl );
     663                }
    629664        }
    630665
  • src/SymTab/Validate.cc

    rada0eb06 r7dc09294  
    176176        };
    177177
    178         class EliminateTypedef : public Mutator {
    179           public:
     178        struct EliminateTypedef final : public WithVisitorRef<EliminateTypedef>, public WithGuards {
    180179                EliminateTypedef() : scopeLevel( 0 ) {}
    181180                /// Replaces typedefs by forward declarations
    182181                static void eliminateTypedef( std::list< Declaration * > &translationUnit );
     182
     183                Type * postmutate( TypeInstType * aggregateUseType );
     184                Declaration * postmutate( TypedefDecl * typeDecl );
     185                void premutate( TypeDecl * typeDecl );
     186                void premutate( FunctionDecl * funcDecl );
     187                void premutate( ObjectDecl * objDecl );
     188                DeclarationWithType * postmutate( ObjectDecl * objDecl );
     189
     190                void premutate( CastExpr * castExpr );
     191
     192                void premutate( CompoundStmt * compoundStmt );
     193                CompoundStmt * postmutate( CompoundStmt * compoundStmt );
     194
     195                void premutate( StructDecl * structDecl );
     196                Declaration * postmutate( StructDecl * structDecl );
     197                void premutate( UnionDecl * unionDecl );
     198                Declaration * postmutate( UnionDecl * unionDecl );
     199                void premutate( EnumDecl * enumDecl );
     200                Declaration * postmutate( EnumDecl * enumDecl );
     201                Declaration * postmutate( TraitDecl * contextDecl );
     202
    183203          private:
    184                 virtual Declaration *mutate( TypedefDecl *typeDecl );
    185                 virtual TypeDecl *mutate( TypeDecl *typeDecl );
    186                 virtual DeclarationWithType *mutate( FunctionDecl *funcDecl );
    187                 virtual DeclarationWithType *mutate( ObjectDecl *objDecl );
    188                 virtual CompoundStmt *mutate( CompoundStmt *compoundStmt );
    189                 virtual Type *mutate( TypeInstType *aggregateUseType );
    190                 virtual Expression *mutate( CastExpr *castExpr );
    191 
    192                 virtual Declaration *mutate( StructDecl * structDecl );
    193                 virtual Declaration *mutate( UnionDecl * unionDecl );
    194                 virtual Declaration *mutate( EnumDecl * enumDecl );
    195                 virtual Declaration *mutate( TraitDecl * contextDecl );
    196 
    197204                template<typename AggDecl>
    198205                AggDecl *handleAggregate( AggDecl * aggDecl );
     
    667674
    668675        void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) {
    669                 EliminateTypedef eliminator;
     676                PassVisitor<EliminateTypedef> eliminator;
    670677                mutateAll( translationUnit, eliminator );
    671                 if ( eliminator.typedefNames.count( "size_t" ) ) {
     678                if ( eliminator.pass.typedefNames.count( "size_t" ) ) {
    672679                        // grab and remember declaration of size_t
    673                         SizeType = eliminator.typedefNames["size_t"].first->get_base()->clone();
     680                        SizeType = eliminator.pass.typedefNames["size_t"].first->get_base()->clone();
    674681                } else {
    675682                        // xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong
     
    681688        }
    682689
    683         Type *EliminateTypedef::mutate( TypeInstType * typeInst ) {
     690        Type * EliminateTypedef::postmutate( TypeInstType * typeInst ) {
    684691                // instances of typedef types will come here. If it is an instance
    685692                // of a typdef type, link the instance to its actual type.
     
    696703                                rtt->get_parameters().clear();
    697704                                cloneAll( typeInst->get_parameters(), rtt->get_parameters() );
    698                                 mutateAll( rtt->get_parameters(), *this );  // recursively fix typedefs on parameters
     705                                mutateAll( rtt->get_parameters(), *visitor );  // recursively fix typedefs on parameters
    699706                        } // if
    700707                        delete typeInst;
     
    708715        }
    709716
    710         Declaration *EliminateTypedef::mutate( TypedefDecl * tyDecl ) {
    711                 Declaration *ret = Mutator::mutate( tyDecl );
    712 
     717        Declaration *EliminateTypedef::postmutate( TypedefDecl * tyDecl ) {
    713718                if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
    714719                        // typedef to the same name from the same scope
     
    741746                        return new EnumDecl( enumDecl->get_name(), noAttributes, tyDecl->get_linkage() );
    742747                } else {
    743                         return ret->clone();
    744                 } // if
    745         }
    746 
    747         TypeDecl *EliminateTypedef::mutate( TypeDecl * typeDecl ) {
     748                        return tyDecl->clone();
     749                } // if
     750        }
     751
     752        void EliminateTypedef::premutate( TypeDecl * typeDecl ) {
    748753                TypedefMap::iterator i = typedefNames.find( typeDecl->get_name() );
    749754                if ( i != typedefNames.end() ) {
     
    752757
    753758                typedeclNames[ typeDecl->get_name() ] = typeDecl;
    754                 return Mutator::mutate( typeDecl );
    755         }
    756 
    757         DeclarationWithType *EliminateTypedef::mutate( FunctionDecl * funcDecl ) {
    758                 typedefNames.beginScope();
    759                 DeclarationWithType *ret = Mutator::mutate( funcDecl );
    760                 typedefNames.endScope();
    761                 return ret;
    762         }
    763 
    764         DeclarationWithType *EliminateTypedef::mutate( ObjectDecl * objDecl ) {
    765                 typedefNames.beginScope();
    766                 DeclarationWithType *ret = Mutator::mutate( objDecl );
    767                 typedefNames.endScope();
    768 
    769                 if ( FunctionType *funtype = dynamic_cast<FunctionType *>( ret->get_type() ) ) { // function type?
     759        }
     760
     761        void EliminateTypedef::premutate( FunctionDecl * ) {
     762                GuardScope( typedefNames );
     763        }
     764
     765        void EliminateTypedef::premutate( ObjectDecl * ) {
     766                GuardScope( typedefNames );
     767        }
     768
     769        DeclarationWithType *EliminateTypedef::postmutate( ObjectDecl * objDecl ) {
     770                if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->get_type() ) ) { // function type?
    770771                        // replace the current object declaration with a function declaration
    771                         FunctionDecl * newDecl = new FunctionDecl( ret->get_name(), ret->get_storageClasses(), ret->get_linkage(), funtype, 0, objDecl->get_attributes(), ret->get_funcSpec() );
     772                        FunctionDecl * newDecl = new FunctionDecl( objDecl->get_name(), objDecl->get_storageClasses(), objDecl->get_linkage(), funtype, 0, objDecl->get_attributes(), objDecl->get_funcSpec() );
    772773                        objDecl->get_attributes().clear();
    773774                        objDecl->set_type( nullptr );
     
    775776                        return newDecl;
    776777                } // if
    777                 return ret;
    778         }
    779 
    780         Expression *EliminateTypedef::mutate( CastExpr * castExpr ) {
    781                 typedefNames.beginScope();
    782                 Expression *ret = Mutator::mutate( castExpr );
    783                 typedefNames.endScope();
    784                 return ret;
    785         }
    786 
    787         CompoundStmt *EliminateTypedef::mutate( CompoundStmt * compoundStmt ) {
    788                 typedefNames.beginScope();
     778                return objDecl;
     779        }
     780
     781        void EliminateTypedef::premutate( CastExpr * ) {
     782                GuardScope( typedefNames );
     783        }
     784
     785        void EliminateTypedef::premutate( CompoundStmt * ) {
     786                GuardScope( typedefNames );
    789787                scopeLevel += 1;
    790                 CompoundStmt *ret = Mutator::mutate( compoundStmt );
    791                 scopeLevel -= 1;
     788                GuardAction( [this](){ scopeLevel -= 1; } );
     789        }
     790
     791        CompoundStmt *EliminateTypedef::postmutate( CompoundStmt * compoundStmt ) {
    792792                // remove and delete decl stmts
    793793                filter( compoundStmt->kids, [](Statement * stmt) {
     
    799799                        return false;
    800800                }, true);
    801                 typedefNames.endScope();
    802                 return ret;
     801                return compoundStmt;
    803802        }
    804803
     
    827826        }
    828827
    829         Declaration *EliminateTypedef::mutate( StructDecl * structDecl ) {
     828        void EliminateTypedef::premutate( StructDecl * structDecl ) {
    830829                addImplicitTypedef( structDecl );
    831                 Mutator::mutate( structDecl );
     830        }
     831
     832
     833        Declaration *EliminateTypedef::postmutate( StructDecl * structDecl ) {
    832834                return handleAggregate( structDecl );
    833835        }
    834836
    835         Declaration *EliminateTypedef::mutate( UnionDecl * unionDecl ) {
     837        void EliminateTypedef::premutate( UnionDecl * unionDecl ) {
    836838                addImplicitTypedef( unionDecl );
    837                 Mutator::mutate( unionDecl );
     839        }
     840
     841        Declaration *EliminateTypedef::postmutate( UnionDecl * unionDecl ) {
    838842                return handleAggregate( unionDecl );
    839843        }
    840844
    841         Declaration *EliminateTypedef::mutate( EnumDecl * enumDecl ) {
     845        void EliminateTypedef::premutate( EnumDecl * enumDecl ) {
    842846                addImplicitTypedef( enumDecl );
    843                 Mutator::mutate( enumDecl );
     847        }
     848
     849        Declaration *EliminateTypedef::postmutate( EnumDecl * enumDecl ) {
    844850                return handleAggregate( enumDecl );
    845851        }
    846852
    847         Declaration *EliminateTypedef::mutate( TraitDecl * contextDecl ) {
    848                 Mutator::mutate( contextDecl );
    849                 return handleAggregate( contextDecl );
     853        Declaration *EliminateTypedef::postmutate( TraitDecl * traitDecl ) {
     854                return handleAggregate( traitDecl );
    850855        }
    851856
  • src/SynTree/Declaration.h

    rada0eb06 r7dc09294  
    136136        Expression *get_bitfieldWidth() const { return bitfieldWidth; }
    137137        void set_bitfieldWidth( Expression *newValue ) { bitfieldWidth = newValue; }
     138
     139        static ObjectDecl * newObject( const std::string & name, Type * type, Initializer * init );
    138140
    139141        virtual ObjectDecl *clone() const { return new ObjectDecl( *this ); }
     
    230232        virtual TypeDecl *clone() const { return new TypeDecl( *this ); }
    231233        virtual void accept( Visitor &v ) { v.visit( this ); }
    232         virtual TypeDecl *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     234        virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    233235        virtual void print( std::ostream &os, int indent = 0 ) const;
    234236
  • src/SynTree/Mutator.cc

    rada0eb06 r7dc09294  
    7878}
    7979
    80 TypeDecl * Mutator::mutate( TypeDecl *typeDecl ) {
     80Declaration * Mutator::mutate( TypeDecl *typeDecl ) {
    8181        handleNamedTypeDecl( typeDecl );
    8282        typeDecl->set_init( maybeMutate( typeDecl->get_init(), *this ) );
  • src/SynTree/Mutator.h

    rada0eb06 r7dc09294  
    3131        virtual Declaration* mutate( EnumDecl *aggregateDecl );
    3232        virtual Declaration* mutate( TraitDecl *aggregateDecl );
    33         virtual TypeDecl* mutate( TypeDecl *typeDecl );
     33        virtual Declaration* mutate( TypeDecl *typeDecl );
    3434        virtual Declaration* mutate( TypedefDecl *typeDecl );
    3535        virtual AsmDecl* mutate( AsmDecl *asmDecl );
  • src/SynTree/ObjectDecl.cc

    rada0eb06 r7dc09294  
    3838        delete init;
    3939        delete bitfieldWidth;
     40}
     41
     42ObjectDecl * ObjectDecl::newObject( const std::string & name, Type * type, Initializer * init ) {
     43        return new ObjectDecl( name, Type::StorageClasses(), LinkageSpec::C, 0, type, init );
    4044}
    4145
  • src/SynTree/Statement.cc

    rada0eb06 r7dc09294  
    472472}
    473473
    474 NullStmt::NullStmt( std::list<Label> labels ) : CompoundStmt( labels ) {}
    475 NullStmt::NullStmt() : CompoundStmt( std::list<Label>() ) {}
     474NullStmt::NullStmt( std::list<Label> labels ) : Statement( labels ) {}
     475NullStmt::NullStmt() : Statement( std::list<Label>() ) {}
    476476
    477477void NullStmt::print( std::ostream &os, __attribute__((unused)) int indent ) const {
  • src/SynTree/Statement.h

    rada0eb06 r7dc09294  
    6767};
    6868
    69 class NullStmt : public CompoundStmt {
     69class NullStmt : public Statement {
    7070  public:
    7171        NullStmt();
Note: See TracChangeset for help on using the changeset viewer.