Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r4e8949f r8b11840  
    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+
    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
    3335#include "SymTab/Mangler.h"        // for Mangler
    3436#include "SynTree/Attribute.h"     // For Attribute
     
    5355        };
    5456
    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 
     57        struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting {
    6658                AutogenerateRoutines();
    6759
    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 );
     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 );
    8071
    8172          private:
    82                 template< typename StmtClass > void visitStatement( StmtClass *stmt );
    83 
    84                 std::list< Declaration * > declsToAdd, declsToAddAfter;
    85                 std::set< std::string > structsDone;
     73                GenPoly::ScopedSet< std::string > structsDone;
    8674                unsigned int functionNesting = 0;     // current level of nested functions
    8775                /// Note: the following maps could be ScopedSets, but it should be easier to work
     
    112100
    113101        void autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    114                 AutogenerateRoutines generator;
    115                 acceptAndAdd( translationUnit, generator );
     102                PassVisitor<AutogenerateRoutines> generator;
     103                acceptAll( translationUnit, generator );
    116104
    117105                // needs to be done separately because AutogenerateRoutines skips types that appear as function arguments, etc.
     
    121109
    122110        bool isUnnamedBitfield( ObjectDecl * obj ) {
    123                 return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL;
     111                return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr;
    124112        }
    125113
     
    128116                FunctionDecl * decl = functionDecl->clone();
    129117                delete decl->get_statements();
    130                 decl->set_statements( NULL );
     118                decl->set_statements( nullptr );
    131119                declsToAdd.push_back( decl );
    132120                decl->fixUniqueId();
     
    339327                                assert( ! func->get_functionType()->get_parameters().empty() );
    340328                                ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() );
    341                                 ObjectDecl * srcParam = NULL;
     329                                ObjectDecl * srcParam = nullptr;
    342330                                if ( func->get_functionType()->get_parameters().size() == 2 ) {
    343331                                        srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
     
    346334                                assert( dstParam );
    347335
    348                                 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
     336                                Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr;
    349337                                makeStructMemberOp( dstParam, srcselect, field, func, forward );
    350338                        } // if
     
    385373                                } else {
    386374                                        // no matching parameter, initialize field with default ctor
    387                                         makeStructMemberOp( dstParam, NULL, field, func );
     375                                        makeStructMemberOp( dstParam, nullptr, field, func );
    388376                                }
    389377                        }
     
    401389        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
    402390                // Builtins do not use autogeneration.
    403                 if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA ||
    404                          aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) {
     391                if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) {
    405392                        return;
    406393                }
    407394
    408395                // 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
     396                const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    410397
    411398                // generate each of the functions based on the supplied FuncData objects
     
    572559                // the order here determines the order that these functions are generated.
    573560                // 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 ) {
     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;
    581569                if ( ! enumDecl->get_members().empty() ) {
    582570                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
     
    586574        }
    587575
    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() ) {
     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 ) {
    592581                                // 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 ) ) );
     582                                acceptAll( typeDecl->assertions, *visitor );
     583                                structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );
    595584                        }
    596585                        structInst.set_baseStruct( structDecl );
    597586                        makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data );
    598                         structsDone.insert( structDecl->get_name() );
     587                        structsDone.insert( structDecl->name );
    599588                } // if
    600589        }
    601590
    602         void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
     591        void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) {
     592                visit_children = false;
    603593                if ( ! unionDecl->get_members().empty() ) {
    604594                        UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
     
    619609
    620610        // generate ctor/dtors/assign for typedecls, e.g., otype T = int *;
    621         void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
     611        void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) {
     612                visit_children = false;
    622613                if ( ! typeDecl->base ) return;
    623614
     
    664655        }
    665656
    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 *) {
     657        void AutogenerateRoutines::previsit( FunctionType *) {
    674658                // ensure that we don't add assignment ops for types defined as part of the function
    675         }
    676 
    677         void AutogenerateRoutines::visit( PointerType *) {
     659                visit_children = false;
     660        }
     661
     662        void AutogenerateRoutines::previsit( PointerType *) {
    678663                // ensure that we don't add assignment ops for types defined as part of the pointer
    679         }
    680 
    681         void AutogenerateRoutines::visit( TraitDecl *) {
     664                visit_children = false;
     665        }
     666
     667        void AutogenerateRoutines::previsit( TraitDecl * ) {
    682668                // 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 ) {
     669                visit_children = false;
     670        }
     671
     672        void AutogenerateRoutines::previsit( FunctionDecl * functionDecl ) {
     673                visit_children = false;
    693674                // record the existence of this function as appropriate
    694675                insert( functionDecl, constructable, InitTweak::isDefaultConstructor );
     
    697678                insert( functionDecl, destructable, InitTweak::isDestructor );
    698679
    699                 maybeAccept( functionDecl->get_functionType(), *this );
     680                maybeAccept( functionDecl->type, *visitor );
    700681                functionNesting += 1;
    701                 maybeAccept( functionDecl->get_statements(), *this );
     682                maybeAccept( functionDecl->statements, *visitor );
    702683                functionNesting -= 1;
    703684        }
    704685
    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 );
     686        void AutogenerateRoutines::previsit( CompoundStmt * ) {
     687                GuardScope( constructable );
     688                GuardScope( assignable );
     689                GuardScope( copyable );
     690                GuardScope( destructable );
     691                GuardScope( structsDone );
    719692        }
    720693
Note: See TracChangeset for help on using the changeset viewer.