Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    rdbe8f244 rfb7dca0  
    1010// Created On       : Sun May 17 21:50:04 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 12 17:49:21 2016
    13 // Update Count     : 298
     12// Last Modified On : Thu Feb  2 17:47:54 2017
     13// Update Count     : 312
    1414//
    1515
     
    6767namespace SymTab {
    6868        class HoistStruct final : public Visitor {
     69                template< typename Visitor >
     70                friend void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
     71            template< typename Visitor >
     72            friend void addVisitStatementList( std::list< Statement* > &stmts, Visitor &visitor );
    6973          public:
    7074                /// Flattens nested struct types
     
    7377                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    7478
     79                virtual void visit( EnumInstType *enumInstType );
     80                virtual void visit( StructInstType *structInstType );
     81                virtual void visit( UnionInstType *unionInstType );
    7582                virtual void visit( StructDecl *aggregateDecl );
    7683                virtual void visit( UnionDecl *aggregateDecl );
     
    8390                template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
    8491
    85                 std::list< Declaration * > declsToAdd;
     92                std::list< Declaration * > declsToAdd, declsToAddAfter;
    8693                bool inStruct;
    8794        };
     
    115122          private:
    116123                using Parent::visit;
     124                void visit( EnumInstType *enumInst ) final;
    117125                void visit( StructInstType *structInst ) final;
    118126                void visit( UnionInstType *unionInst ) final;
    119127                void visit( TraitInstType *contextInst ) final;
     128                void visit( EnumDecl *enumDecl ) final;
    120129                void visit( StructDecl *structDecl ) final;
    121130                void visit( UnionDecl *unionDecl ) final;
     
    124133                const Indexer *indexer;
    125134
     135                typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType;
    126136                typedef std::map< std::string, std::list< StructInstType * > > ForwardStructsType;
    127137                typedef std::map< std::string, std::list< UnionInstType * > > ForwardUnionsType;
     138                ForwardEnumsType forwardEnums;
    128139                ForwardStructsType forwardStructs;
    129140                ForwardUnionsType forwardUnions;
     
    236247        void HoistStruct::hoistStruct( std::list< Declaration * > &translationUnit ) {
    237248                HoistStruct hoister;
    238                 acceptAndAdd( translationUnit, hoister, true );
     249                acceptAndAdd( translationUnit, hoister );
    239250        }
    240251
     
    260271                return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl );
    261272        }
    262         // xxx - shouldn't this be declsToAddBefore?
     273
    263274        template< typename AggDecl >
    264275        void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) {
     
    276287        }
    277288
     289        void HoistStruct::visit( EnumInstType *structInstType ) {
     290                if ( structInstType->get_baseEnum() ) {
     291                        declsToAdd.push_front( structInstType->get_baseEnum() );
     292                }
     293        }
     294
     295        void HoistStruct::visit( StructInstType *structInstType ) {
     296                if ( structInstType->get_baseStruct() ) {
     297                        declsToAdd.push_front( structInstType->get_baseStruct() );
     298                }
     299        }
     300
     301        void HoistStruct::visit( UnionInstType *structInstType ) {
     302                if ( structInstType->get_baseUnion() ) {
     303                        declsToAdd.push_front( structInstType->get_baseUnion() );
     304                }
     305        }
     306
    278307        void HoistStruct::visit( StructDecl *aggregateDecl ) {
    279308                handleAggregate( aggregateDecl );
     
    297326                        ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i );
    298327                        assert( obj );
    299                         obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false, false, false ), enumDecl->get_name() ) );
     328                        obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false, false ), enumDecl->get_name() ) );
    300329                } // for
    301330                Parent::visit( enumDecl );
     
    349378        }
    350379
     380        void LinkReferenceToTypes::visit( EnumInstType *enumInst ) {
     381                Parent::visit( enumInst );
     382                EnumDecl *st = indexer->lookupEnum( enumInst->get_name() );
     383                // it's not a semantic error if the enum is not found, just an implicit forward declaration
     384                if ( st ) {
     385                        //assert( ! enumInst->get_baseEnum() || enumInst->get_baseEnum()->get_members().empty() || ! st->get_members().empty() );
     386                        enumInst->set_baseEnum( st );
     387                } // if
     388                if ( ! st || st->get_members().empty() ) {
     389                        // use of forward declaration
     390                        forwardEnums[ enumInst->get_name() ].push_back( enumInst );
     391                } // if
     392        }
     393
    351394        void LinkReferenceToTypes::visit( StructInstType *structInst ) {
    352395                Parent::visit( structInst );
     
    419462                        }
    420463                }
     464        }
     465
     466        void LinkReferenceToTypes::visit( EnumDecl *enumDecl ) {
     467                // visit enum members first so that the types of self-referencing members are updated properly
     468                Parent::visit( enumDecl );
     469                if ( ! enumDecl->get_members().empty() ) {
     470                        ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->get_name() );
     471                        if ( fwds != forwardEnums.end() ) {
     472                                for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
     473                                        (*inst )->set_baseEnum( enumDecl );
     474                                } // for
     475                                forwardEnums.erase( fwds );
     476                        } // if
     477                } // if
    421478        }
    422479
     
    572629                } else {
    573630                        TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
    574                         assert( base != typedeclNames.end() );
     631                        assertf( base != typedeclNames.end(), "Can't find name %s", typeInst->get_name().c_str() );
    575632                        typeInst->set_baseType( base->second );
    576633                } // if
Note: See TracChangeset for help on using the changeset viewer.