Changeset cce9429 for src/SymTab


Ignore:
Timestamp:
Dec 13, 2016, 6:42:39 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
1aa4b71
Parents:
31f379c
Message:

fix function return type in Validate and add single return decl, construct the return decl, fix polymorphic functions to use the return decl

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    r31f379c rcce9429  
    8686        };
    8787
     88        /// Fix return types so that every function returns exactly one value
     89        class ReturnTypeFixer : public Visitor {
     90          public:
     91                static void fix( std::list< Declaration * > &translationUnit );
     92
     93                virtual void visit( FunctionType * ftype );
     94        };
     95
    8896        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    8997        class EnumAndPointerDecayPass : public Visitor {
     
    94102
    95103        /// Associates forward declarations of aggregates with their definitions
    96         class Pass2 final : public Indexer {
     104        class LinkReferenceToTypes final : public Indexer {
    97105                typedef Indexer Parent;
    98106          public:
    99                 Pass2( bool doDebug, const Indexer *indexer );
     107                LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
    100108          private:
    101109                using Indexer::visit;
     
    193201        void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
    194202                EnumAndPointerDecayPass epc;
    195                 Pass2 pass2( doDebug, 0 );
     203                LinkReferenceToTypes lrt( doDebug, 0 );
    196204                Pass3 pass3( 0 );
    197205                CompoundLiteral compoundliteral;
     
    199207                EliminateTypedef::eliminateTypedef( translationUnit );
    200208                HoistStruct::hoistStruct( translationUnit );
     209                ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
    201210                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecayPass
    202211                acceptAll( translationUnit, epc );
    203                 acceptAll( translationUnit, pass2 );
     212                acceptAll( translationUnit, lrt );
    204213                ReturnChecker::checkFunctionReturns( translationUnit );
    205214                compoundliteral.mutateDeclarationList( translationUnit );
     
    210219        void validateType( Type *type, const Indexer *indexer ) {
    211220                EnumAndPointerDecayPass epc;
    212                 Pass2 pass2( false, indexer );
     221                LinkReferenceToTypes lrt( false, indexer );
    213222                Pass3 pass3( indexer );
    214223                type->accept( epc );
    215                 type->accept( pass2 );
     224                type->accept( lrt );
    216225                type->accept( pass3 );
    217226        }
     
    324333        }
    325334
    326         Pass2::Pass2( bool doDebug, const Indexer *other_indexer ) : Indexer( doDebug ) {
     335        LinkReferenceToTypes::LinkReferenceToTypes( bool doDebug, const Indexer *other_indexer ) : Indexer( doDebug ) {
    327336                if ( other_indexer ) {
    328337                        indexer = other_indexer;
     
    332341        }
    333342
    334         void Pass2::visit( StructInstType *structInst ) {
     343        void LinkReferenceToTypes::visit( StructInstType *structInst ) {
    335344                Parent::visit( structInst );
    336345                StructDecl *st = indexer->lookupStruct( structInst->get_name() );
     
    346355        }
    347356
    348         void Pass2::visit( UnionInstType *unionInst ) {
     357        void LinkReferenceToTypes::visit( UnionInstType *unionInst ) {
    349358                Parent::visit( unionInst );
    350359                UnionDecl *un = indexer->lookupUnion( unionInst->get_name() );
     
    359368        }
    360369
    361         void Pass2::visit( TraitInstType *contextInst ) {
     370        void LinkReferenceToTypes::visit( TraitInstType *contextInst ) {
    362371                Parent::visit( contextInst );
    363372                if ( contextInst->get_name() == "sized" ) {
     
    398407        }
    399408
    400         void Pass2::visit( StructDecl *structDecl ) {
     409        void LinkReferenceToTypes::visit( StructDecl *structDecl ) {
    401410                // visit struct members first so that the types of self-referencing members are updated properly
    402411                Parent::visit( structDecl );
     
    412421        }
    413422
    414         void Pass2::visit( UnionDecl *unionDecl ) {
     423        void LinkReferenceToTypes::visit( UnionDecl *unionDecl ) {
    415424                Parent::visit( unionDecl );
    416425                if ( ! unionDecl->get_members().empty() ) {
     
    425434        }
    426435
    427         void Pass2::visit( TypeInstType *typeInst ) {
     436        void LinkReferenceToTypes::visit( TypeInstType *typeInst ) {
    428437                if ( NamedTypeDecl *namedTypeDecl = lookupType( typeInst->get_name() ) ) {
    429438                        if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
     
    747756                return new VariableExpr( newtempvar );
    748757        }
     758
     759        void ReturnTypeFixer::fix( std::list< Declaration * > &translationUnit ) {
     760                ReturnTypeFixer fixer;
     761                acceptAll( translationUnit, fixer );
     762        }
     763
     764        void ReturnTypeFixer::visit( FunctionType * ftype ) {
     765                static UniqueName tempNamer( "_retval" );
     766
     767                // xxx - need to handle named return values - this information needs to be saved somehow
     768                // so that resolution has access to the names.
     769                // Note that this pass needs to happen early so that other passes which look for tuple types
     770                // find them in all of the right places, including function return types.
     771                std::list< DeclarationWithType * > & retVals = ftype->get_returnVals();
     772                if ( retVals.size() > 1 ) {
     773                        // generate a single return parameter which is the tuple of all of the return values
     774                        TupleType * tupleType = safe_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) );
     775                        // ensure return value is not destructed by explicitly creating an empty ListInit node wherein maybeConstruct is false.
     776                        ObjectDecl * newRet = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) );
     777                        deleteAll( retVals );
     778                        retVals.clear();
     779                        retVals.push_back( newRet );
     780                } else if ( retVals.size() == 1 ) {
     781                        // ensure other return values have a name
     782                        DeclarationWithType * ret = retVals.front();
     783                        if ( ret->get_name() == "" ) {
     784                                ret->set_name( tempNamer.newName() );
     785                        }
     786                }
     787        }
    749788} // namespace SymTab
    750789
Note: See TracChangeset for help on using the changeset viewer.