Ignore:
Timestamp:
Nov 25, 2017, 3:22:18 PM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
c6e2c18
Parents:
9d06142 (diff), 3de176d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into cleanup-dtors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    r9d06142 rc0d00b6  
    124124
    125125        /// Associates forward declarations of aggregates with their definitions
    126         struct LinkReferenceToTypes final : public WithIndexer {
     126        struct LinkReferenceToTypes final : public WithIndexer, public WithGuards {
    127127                LinkReferenceToTypes( const Indexer *indexer );
    128128                void postvisit( TypeInstType *typeInst );
     
    137137                void postvisit( UnionDecl *unionDecl );
    138138                void postvisit( TraitDecl * traitDecl );
     139
     140                void previsit( StructDecl *structDecl );
     141                void previsit( UnionDecl *unionDecl );
     142
     143                void renameGenericParams( std::list< TypeDecl * > & params );
    139144
    140145          private:
     
    147152                ForwardStructsType forwardStructs;
    148153                ForwardUnionsType forwardUnions;
     154                /// true if currently in a generic type body, so that type parameter instances can be renamed appropriately
     155                bool inGeneric = false;
    149156        };
    150157
     
    423430        }
    424431
     432        void checkGenericParameters( ReferenceToType * inst ) {
     433                for ( Expression * param : inst->parameters ) {
     434                        if ( ! dynamic_cast< TypeExpr * >( param ) ) {
     435                                throw SemanticError( "Expression parameters for generic types are currently unsupported: ", inst );
     436                        }
     437                }
     438        }
     439
    425440        void LinkReferenceToTypes::postvisit( StructInstType *structInst ) {
    426441                StructDecl *st = local_indexer->lookupStruct( structInst->get_name() );
     
    434449                        forwardStructs[ structInst->get_name() ].push_back( structInst );
    435450                } // if
     451                checkGenericParameters( structInst );
    436452        }
    437453
     
    446462                        forwardUnions[ unionInst->get_name() ].push_back( unionInst );
    447463                } // if
     464                checkGenericParameters( unionInst );
    448465        }
    449466
     
    525542                // need to carry over the 'sized' status of each decl in the instance
    526543                for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) {
    527                         TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( std::get<1>(p) );
     544                        TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) );
     545                        if ( ! expr ) {
     546                                throw SemanticError( "Expression parameters for trait instances are currently unsupported: ", std::get<1>(p) );
     547                        }
    528548                        if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
    529549                                TypeDecl * formalDecl = std::get<0>(p);
     
    546566                        } // if
    547567                } // if
     568        }
     569
     570        void LinkReferenceToTypes::renameGenericParams( std::list< TypeDecl * > & params ) {
     571                // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g.
     572                //   forall(otype T)
     573                //   struct Box {
     574                //     T x;
     575                //   };
     576                //   forall(otype T)
     577                //   void f(Box(T) b) {
     578                //     ...
     579                //   }
     580                // The T in Box and the T in f are different, so internally the naming must reflect that.
     581                GuardValue( inGeneric );
     582                inGeneric = ! params.empty();
     583                for ( TypeDecl * td : params ) {
     584                        td->name = "__" + td->name + "_generic_";
     585                }
     586        }
     587
     588        void LinkReferenceToTypes::previsit( StructDecl * structDecl ) {
     589                renameGenericParams( structDecl->parameters );
     590        }
     591
     592        void LinkReferenceToTypes::previsit( UnionDecl * unionDecl ) {
     593                renameGenericParams( unionDecl->parameters );
    548594        }
    549595
     
    575621
    576622        void LinkReferenceToTypes::postvisit( TypeInstType *typeInst ) {
     623                // ensure generic parameter instances are renamed like the base type
     624                if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name;
    577625                if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->get_name() ) ) {
    578626                        if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
Note: See TracChangeset for help on using the changeset viewer.