Ignore:
Timestamp:
Sep 26, 2017, 11:27:38 PM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
5dc26f5
Parents:
201aeb9
Message:

merge

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r201aeb9 rd67cdb7  
    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+
    31 #include "GenPoly/DeclMutator.h"   // for DeclMutator
    3231#include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::iterator
     32#include "InitTweak/GenInit.h"     // for fixReturnStatements
     33#include "ResolvExpr/Resolver.h"   // for resolveDecl
    3334#include "SymTab/Mangler.h"        // for Mangler
    3435#include "SynTree/Attribute.h"     // For Attribute
     
    5354        };
    5455
    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 
     56        struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting {
    6657                AutogenerateRoutines();
    6758
    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 );
     59                void previsit( EnumDecl * enumDecl );
     60                void previsit( StructDecl * structDecl );
     61                void previsit( UnionDecl * structDecl );
     62                void previsit( TypeDecl * typeDecl );
     63                void previsit( TraitDecl * traitDecl );
     64                void previsit( FunctionDecl * functionDecl );
     65
     66                void previsit( FunctionType * ftype );
     67                void previsit( PointerType * ptype );
     68
     69                void previsit( CompoundStmt * compoundStmt );
    8070
    8171          private:
    82                 template< typename StmtClass > void visitStatement( StmtClass *stmt );
    83 
    84                 std::list< Declaration * > declsToAdd, declsToAddAfter;
    85                 std::set< std::string > structsDone;
     72                GenPoly::ScopedSet< std::string > structsDone;
    8673                unsigned int functionNesting = 0;     // current level of nested functions
    8774                /// Note: the following maps could be ScopedSets, but it should be easier to work
     
    9380
    9481        /// generates routines for tuple types.
    95         /// Doesn't really need to be a mutator, but it's easier to reuse DeclMutator than it is to use AddVisit
    96         /// or anything we currently have that supports adding new declarations for visitors
    97         class AutogenTupleRoutines : public GenPoly::DeclMutator {
    98           public:
    99                 typedef GenPoly::DeclMutator Parent;
    100                 using Parent::mutate;
    101 
    102                 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
    103 
    104                 virtual Type * mutate( TupleType *tupleType );
    105 
    106                 virtual CompoundStmt * mutate( CompoundStmt *compoundStmt );
     82        struct AutogenTupleRoutines : public WithDeclsToAdd, public WithVisitorRef<AutogenTupleRoutines>, public WithGuards, public WithShortCircuiting {
     83                void previsit( FunctionDecl *functionDecl );
     84
     85                void postvisit( TupleType *tupleType );
     86
     87                void previsit( CompoundStmt *compoundStmt );
    10788
    10889          private:
     
    11293
    11394        void autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    114                 AutogenerateRoutines generator;
    115                 acceptAndAdd( translationUnit, generator );
     95                PassVisitor<AutogenerateRoutines> generator;
     96                acceptAll( translationUnit, generator );
    11697
    11798                // needs to be done separately because AutogenerateRoutines skips types that appear as function arguments, etc.
    11899                // AutogenTupleRoutines tupleGenerator;
    119                 // tupleGenerator.mutateDeclarationList( translationUnit );
     100                // acceptAll( translationUnit, tupleGenerator );
    120101        }
    121102
    122103        bool isUnnamedBitfield( ObjectDecl * obj ) {
    123                 return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL;
     104                return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr;
    124105        }
    125106
     
    128109                FunctionDecl * decl = functionDecl->clone();
    129110                delete decl->get_statements();
    130                 decl->set_statements( NULL );
     111                decl->set_statements( nullptr );
    131112                declsToAdd.push_back( decl );
    132113                decl->fixUniqueId();
     
    339320                                assert( ! func->get_functionType()->get_parameters().empty() );
    340321                                ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() );
    341                                 ObjectDecl * srcParam = NULL;
     322                                ObjectDecl * srcParam = nullptr;
    342323                                if ( func->get_functionType()->get_parameters().size() == 2 ) {
    343324                                        srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
     
    346327                                assert( dstParam );
    347328
    348                                 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
     329                                Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr;
    349330                                makeStructMemberOp( dstParam, srcselect, field, func, forward );
    350331                        } // if
     
    385366                                } else {
    386367                                        // no matching parameter, initialize field with default ctor
    387                                         makeStructMemberOp( dstParam, NULL, field, func );
     368                                        makeStructMemberOp( dstParam, nullptr, field, func );
    388369                                }
    389370                        }
     
    401382        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
    402383                // Builtins do not use autogeneration.
    403                 if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA ||
    404                          aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) {
     384                if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) {
    405385                        return;
    406386                }
    407387
    408388                // 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
     389                const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    410390
    411391                // generate each of the functions based on the supplied FuncData objects
     
    572552                // the order here determines the order that these functions are generated.
    573553                // 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 ) {
     554                data.emplace_back( "?{}", genDefaultType, constructable );
     555                data.emplace_back( "?{}", genCopyType, copyable );
     556                data.emplace_back( "^?{}", genDefaultType, destructable );
     557                data.emplace_back( "?=?", genAssignType, assignable );
     558        }
     559
     560        void AutogenerateRoutines::previsit( EnumDecl * enumDecl ) {
     561                visit_children = false;
    581562                if ( ! enumDecl->get_members().empty() ) {
    582563                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
     
    586567        }
    587568
    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() ) {
     569        void AutogenerateRoutines::previsit( StructDecl * structDecl ) {
     570                visit_children = false;
     571                if ( structDecl->has_body() && structsDone.find( structDecl->name ) == structsDone.end() ) {
     572                        StructInstType structInst( Type::Qualifiers(), structDecl->name );
     573                        for ( TypeDecl * typeDecl : structDecl->parameters ) {
    592574                                // 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 ) ) );
     575                                acceptAll( typeDecl->assertions, *visitor );
     576                                structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );
    595577                        }
    596578                        structInst.set_baseStruct( structDecl );
    597579                        makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data );
    598                         structsDone.insert( structDecl->get_name() );
     580                        structsDone.insert( structDecl->name );
    599581                } // if
    600582        }
    601583
    602         void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
     584        void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) {
     585                visit_children = false;
    603586                if ( ! unionDecl->get_members().empty() ) {
    604587                        UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
     
    619602
    620603        // generate ctor/dtors/assign for typedecls, e.g., otype T = int *;
    621         void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
     604        void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) {
     605                visit_children = false;
    622606                if ( ! typeDecl->base ) return;
    623607
     
    664648        }
    665649
    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 *) {
     650        void AutogenerateRoutines::previsit( FunctionType *) {
    674651                // ensure that we don't add assignment ops for types defined as part of the function
    675         }
    676 
    677         void AutogenerateRoutines::visit( PointerType *) {
     652                visit_children = false;
     653        }
     654
     655        void AutogenerateRoutines::previsit( PointerType *) {
    678656                // ensure that we don't add assignment ops for types defined as part of the pointer
    679         }
    680 
    681         void AutogenerateRoutines::visit( TraitDecl *) {
     657                visit_children = false;
     658        }
     659
     660        void AutogenerateRoutines::previsit( TraitDecl * ) {
    682661                // 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 ) {
     662                visit_children = false;
     663        }
     664
     665        void AutogenerateRoutines::previsit( FunctionDecl * functionDecl ) {
     666                visit_children = false;
    693667                // record the existence of this function as appropriate
    694668                insert( functionDecl, constructable, InitTweak::isDefaultConstructor );
     
    697671                insert( functionDecl, destructable, InitTweak::isDestructor );
    698672
    699                 maybeAccept( functionDecl->get_functionType(), *this );
     673                maybeAccept( functionDecl->type, *visitor );
    700674                functionNesting += 1;
    701                 maybeAccept( functionDecl->get_statements(), *this );
     675                maybeAccept( functionDecl->statements, *visitor );
    702676                functionNesting -= 1;
    703677        }
    704678
    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 );
     679        void AutogenerateRoutines::previsit( CompoundStmt * ) {
     680                GuardScope( constructable );
     681                GuardScope( assignable );
     682                GuardScope( copyable );
     683                GuardScope( destructable );
     684                GuardScope( structsDone );
    719685        }
    720686
     
    734700        }
    735701
    736         Type * AutogenTupleRoutines::mutate( TupleType * tupleType ) {
    737                 tupleType = strict_dynamic_cast< TupleType * >( Parent::mutate( tupleType ) );
     702        void AutogenTupleRoutines::postvisit( TupleType * tupleType ) {
    738703                std::string mangleName = SymTab::Mangler::mangleType( tupleType );
    739                 if ( seenTuples.find( mangleName ) != seenTuples.end() ) return tupleType;
     704                if ( seenTuples.find( mangleName ) != seenTuples.end() ) return;
    740705                seenTuples.insert( mangleName );
    741706
     
    785750                makeTupleFunctionBody( dtorDecl );
    786751
    787                 addDeclaration( ctorDecl );
    788                 addDeclaration( copyCtorDecl );
    789                 addDeclaration( dtorDecl );
    790                 addDeclaration( assignDecl ); // assignment should come last since it uses copy constructor in return
    791 
    792                 return tupleType;
    793         }
    794 
    795         DeclarationWithType * AutogenTupleRoutines::mutate( FunctionDecl *functionDecl ) {
    796                 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
     752                declsToAddBefore.push_back( ctorDecl );
     753                declsToAddBefore.push_back( copyCtorDecl );
     754                declsToAddBefore.push_back( dtorDecl );
     755                declsToAddBefore.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return
     756        }
     757
     758        void AutogenTupleRoutines::previsit( FunctionDecl *functionDecl ) {
     759                visit_children = false;
     760                maybeAccept( functionDecl->type, *visitor );
    797761                functionNesting += 1;
    798                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     762                maybeAccept( functionDecl->statements, *visitor );
    799763                functionNesting -= 1;
    800                 return functionDecl;
    801         }
    802 
    803         CompoundStmt * AutogenTupleRoutines::mutate( CompoundStmt *compoundStmt ) {
    804                 seenTuples.beginScope();
    805                 compoundStmt = strict_dynamic_cast< CompoundStmt * >( Parent::mutate( compoundStmt ) );
    806                 seenTuples.endScope();
    807                 return compoundStmt;
     764        }
     765
     766        void AutogenTupleRoutines::previsit( CompoundStmt * ) {
     767                GuardScope( seenTuples );
    808768        }
    809769} // SymTab
Note: See TracChangeset for help on using the changeset viewer.