Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r8b11840 r4e8949f  
    1616#include "Autogen.h"
    1717
     18#include <cstddef>                 // for NULL
    1819#include <algorithm>               // for count_if
    1920#include <cassert>                 // for strict_dynamic_cast, assert, assertf
     
    2627#include "AddVisit.h"              // for addVisit
    2728#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+
    3131#include "GenPoly/DeclMutator.h"   // for DeclMutator
    3232#include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::iterator
    33 #include "InitTweak/GenInit.h"     // for fixReturnStatements
    34 #include "ResolvExpr/Resolver.h"   // for resolveDecl
    3533#include "SymTab/Mangler.h"        // for Mangler
    3634#include "SynTree/Attribute.h"     // For Attribute
     
    5553        };
    5654
    57         struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting {
     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
    5866                AutogenerateRoutines();
    5967
    60                 void previsit( EnumDecl * enumDecl );
    61                 void previsit( StructDecl * structDecl );
    62                 void previsit( UnionDecl * structDecl );
    63                 void previsit( TypeDecl * typeDecl );
    64                 void previsit( TraitDecl * traitDecl );
    65                 void previsit( FunctionDecl * functionDecl );
    66 
    67                 void previsit( FunctionType * ftype );
    68                 void previsit( PointerType * ptype );
    69 
    70                 void previsit( CompoundStmt * compoundStmt );
     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 );
    7180
    7281          private:
    73                 GenPoly::ScopedSet< std::string > structsDone;
     82                template< typename StmtClass > void visitStatement( StmtClass *stmt );
     83
     84                std::list< Declaration * > declsToAdd, declsToAddAfter;
     85                std::set< std::string > structsDone;
    7486                unsigned int functionNesting = 0;     // current level of nested functions
    7587                /// Note: the following maps could be ScopedSets, but it should be easier to work
     
    100112
    101113        void autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    102                 PassVisitor<AutogenerateRoutines> generator;
    103                 acceptAll( translationUnit, generator );
     114                AutogenerateRoutines generator;
     115                acceptAndAdd( translationUnit, generator );
    104116
    105117                // needs to be done separately because AutogenerateRoutines skips types that appear as function arguments, etc.
     
    109121
    110122        bool isUnnamedBitfield( ObjectDecl * obj ) {
    111                 return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr;
     123                return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL;
    112124        }
    113125
     
    116128                FunctionDecl * decl = functionDecl->clone();
    117129                delete decl->get_statements();
    118                 decl->set_statements( nullptr );
     130                decl->set_statements( NULL );
    119131                declsToAdd.push_back( decl );
    120132                decl->fixUniqueId();
     
    327339                                assert( ! func->get_functionType()->get_parameters().empty() );
    328340                                ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() );
    329                                 ObjectDecl * srcParam = nullptr;
     341                                ObjectDecl * srcParam = NULL;
    330342                                if ( func->get_functionType()->get_parameters().size() == 2 ) {
    331343                                        srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
     
    334346                                assert( dstParam );
    335347
    336                                 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr;
     348                                Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
    337349                                makeStructMemberOp( dstParam, srcselect, field, func, forward );
    338350                        } // if
     
    373385                                } else {
    374386                                        // no matching parameter, initialize field with default ctor
    375                                         makeStructMemberOp( dstParam, nullptr, field, func );
     387                                        makeStructMemberOp( dstParam, NULL, field, func );
    376388                                }
    377389                        }
     
    389401        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
    390402                // Builtins do not use autogeneration.
    391                 if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) {
     403                if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA ||
     404                         aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) {
    392405                        return;
    393406                }
    394407
    395408                // Make function polymorphic in same parameters as generic struct, if applicable
    396                 const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
     409                const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    397410
    398411                // generate each of the functions based on the supplied FuncData objects
     
    559572                // the order here determines the order that these functions are generated.
    560573                // assignment should come last since it uses copy constructor in return.
    561                 data.emplace_back( "?{}", genDefaultType, constructable );
    562                 data.emplace_back( "?{}", genCopyType, copyable );
    563                 data.emplace_back( "^?{}", genDefaultType, destructable );
    564                 data.emplace_back( "?=?", genAssignType, assignable );
    565         }
    566 
    567         void AutogenerateRoutines::previsit( EnumDecl * enumDecl ) {
    568                 visit_children = false;
     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 ) {
    569581                if ( ! enumDecl->get_members().empty() ) {
    570582                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
     
    574586        }
    575587
    576         void AutogenerateRoutines::previsit( StructDecl * structDecl ) {
    577                 visit_children = false;
    578                 if ( structDecl->has_body() && structsDone.find( structDecl->name ) == structsDone.end() ) {
    579                         StructInstType structInst( Type::Qualifiers(), structDecl->name );
    580                         for ( TypeDecl * typeDecl : structDecl->parameters ) {
     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() ) {
    581592                                // need to visit assertions so that they are added to the appropriate maps
    582                                 acceptAll( typeDecl->assertions, *visitor );
    583                                 structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );
     593                                acceptAll( typeDecl->get_assertions(), *this );
     594                                structInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) );
    584595                        }
    585596                        structInst.set_baseStruct( structDecl );
    586597                        makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data );
    587                         structsDone.insert( structDecl->name );
     598                        structsDone.insert( structDecl->get_name() );
    588599                } // if
    589600        }
    590601
    591         void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) {
    592                 visit_children = false;
     602        void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
    593603                if ( ! unionDecl->get_members().empty() ) {
    594604                        UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
     
    609619
    610620        // generate ctor/dtors/assign for typedecls, e.g., otype T = int *;
    611         void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) {
    612                 visit_children = false;
     621        void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
    613622                if ( ! typeDecl->base ) return;
    614623
     
    655664        }
    656665
    657         void AutogenerateRoutines::previsit( FunctionType *) {
     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 *) {
    658674                // ensure that we don't add assignment ops for types defined as part of the function
    659                 visit_children = false;
    660         }
    661 
    662         void AutogenerateRoutines::previsit( PointerType *) {
     675        }
     676
     677        void AutogenerateRoutines::visit( PointerType *) {
    663678                // ensure that we don't add assignment ops for types defined as part of the pointer
    664                 visit_children = false;
    665         }
    666 
    667         void AutogenerateRoutines::previsit( TraitDecl * ) {
     679        }
     680
     681        void AutogenerateRoutines::visit( TraitDecl *) {
    668682                // ensure that we don't add assignment ops for types defined as part of the trait
    669                 visit_children = false;
    670         }
    671 
    672         void AutogenerateRoutines::previsit( FunctionDecl * functionDecl ) {
    673                 visit_children = false;
     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 ) {
    674693                // record the existence of this function as appropriate
    675694                insert( functionDecl, constructable, InitTweak::isDefaultConstructor );
     
    678697                insert( functionDecl, destructable, InitTweak::isDestructor );
    679698
    680                 maybeAccept( functionDecl->type, *visitor );
     699                maybeAccept( functionDecl->get_functionType(), *this );
    681700                functionNesting += 1;
    682                 maybeAccept( functionDecl->statements, *visitor );
     701                maybeAccept( functionDecl->get_statements(), *this );
    683702                functionNesting -= 1;
    684703        }
    685704
    686         void AutogenerateRoutines::previsit( CompoundStmt * ) {
    687                 GuardScope( constructable );
    688                 GuardScope( assignable );
    689                 GuardScope( copyable );
    690                 GuardScope( destructable );
    691                 GuardScope( structsDone );
     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 );
    692719        }
    693720
Note: See TracChangeset for help on using the changeset viewer.