Changeset 8024bc8 for src/SymTab


Ignore:
Timestamp:
Sep 18, 2017, 11:02:23 AM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
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:
6994d8c
Parents:
ed235b6 (diff), 5f782f7 (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' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/SymTab
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.cc

    red235b6 r8024bc8  
    3737#include "SynTree/Type.h"          // for Type, StructInstType, UnionInstType
    3838
    39 #define debugPrint(x) if ( doDebug ) { std::cout << x; }
     39#define debugPrint(x) if ( doDebug ) { std::cerr << x; }
    4040
    4141namespace SymTab {
     
    230230
    231231                return *this;
    232         }
    233 
    234         void Indexer::visit( ObjectDecl *objectDecl ) {
    235                 enterScope();
    236                 maybeAccept( objectDecl->get_type(), *this );
    237                 leaveScope();
    238                 maybeAccept( objectDecl->get_init(), *this );
    239                 maybeAccept( objectDecl->get_bitfieldWidth(), *this );
    240                 if ( objectDecl->get_name() != "" ) {
    241                         debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
    242                         addId( objectDecl );
    243                 } // if
    244         }
    245 
    246         void Indexer::visit( FunctionDecl *functionDecl ) {
    247                 if ( functionDecl->get_name() == "" ) return;
    248                 debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
    249                 addId( functionDecl );
    250                 enterScope();
    251                 maybeAccept( functionDecl->get_functionType(), *this );
    252                 maybeAccept( functionDecl->get_statements(), *this );
    253                 leaveScope();
    254         }
    255 
    256 
    257 // A NOTE ON THE ORDER OF TRAVERSAL
    258 //
    259 // Types and typedefs have their base types visited before they are added to the type table.  This is ok, since there is
    260 // no such thing as a recursive type or typedef.
    261 //
    262 //             typedef struct { T *x; } T; // never allowed
    263 //
    264 // for structs/unions, it is possible to have recursion, so the decl should be added as if it's incomplete to begin, the
    265 // members are traversed, and then the complete type should be added (assuming the type is completed by this particular
    266 // declaration).
    267 //
    268 //             struct T { struct T *x; }; // allowed
    269 //
    270 // It is important to add the complete type to the symbol table *after* the members/base has been traversed, since that
    271 // traversal may modify the definition of the type and these modifications should be visible when the symbol table is
    272 // queried later in this pass.
    273 //
    274 // TODO: figure out whether recursive contexts are sensible/possible/reasonable.
    275 
    276 
    277         void Indexer::visit( TypeDecl *typeDecl ) {
    278                 // see A NOTE ON THE ORDER OF TRAVERSAL, above
    279                 // note that assertions come after the type is added to the symtab, since they are not part of the type proper
    280                 // and may depend on the type itself
    281                 enterScope();
    282                 acceptAll( typeDecl->get_parameters(), *this );
    283                 maybeAccept( typeDecl->get_base(), *this );
    284                 leaveScope();
    285                 debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
    286                 addType( typeDecl );
    287                 acceptAll( typeDecl->get_assertions(), *this );
    288                 acceptNewScope( typeDecl->get_init(), *this );
    289         }
    290 
    291         void Indexer::visit( TypedefDecl *typeDecl ) {
    292                 enterScope();
    293                 acceptAll( typeDecl->get_parameters(), *this );
    294                 maybeAccept( typeDecl->get_base(), *this );
    295                 leaveScope();
    296                 debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
    297                 addType( typeDecl );
    298         }
    299 
    300         void Indexer::visit( StructDecl *aggregateDecl ) {
    301                 // make up a forward declaration and add it before processing the members
    302                 // needs to be on the heap because addStruct saves the pointer
    303                 StructDecl &fwdDecl = *new StructDecl( aggregateDecl->get_name() );
    304                 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
    305                 debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
    306                 addStruct( &fwdDecl );
    307 
    308                 enterScope();
    309                 acceptAll( aggregateDecl->get_parameters(), *this );
    310                 acceptAll( aggregateDecl->get_members(), *this );
    311                 leaveScope();
    312 
    313                 debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
    314                 // this addition replaces the forward declaration
    315                 addStruct( aggregateDecl );
    316         }
    317 
    318         void Indexer::visit( UnionDecl *aggregateDecl ) {
    319                 // make up a forward declaration and add it before processing the members
    320                 UnionDecl fwdDecl( aggregateDecl->get_name() );
    321                 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
    322                 debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
    323                 addUnion( &fwdDecl );
    324 
    325                 enterScope();
    326                 acceptAll( aggregateDecl->get_parameters(), *this );
    327                 acceptAll( aggregateDecl->get_members(), *this );
    328                 leaveScope();
    329 
    330                 debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
    331                 addUnion( aggregateDecl );
    332         }
    333 
    334         void Indexer::visit( EnumDecl *aggregateDecl ) {
    335                 debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
    336                 addEnum( aggregateDecl );
    337                 // unlike structs, contexts, and unions, enums inject their members into the global scope
    338                 acceptAll( aggregateDecl->get_members(), *this );
    339         }
    340 
    341         void Indexer::visit( TraitDecl *aggregateDecl ) {
    342                 enterScope();
    343                 acceptAll( aggregateDecl->get_parameters(), *this );
    344                 acceptAll( aggregateDecl->get_members(), *this );
    345                 leaveScope();
    346 
    347                 debugPrint( "Adding trait " << aggregateDecl->get_name() << std::endl );
    348                 addTrait( aggregateDecl );
    349         }
    350 
    351         void Indexer::visit( CompoundStmt *compoundStmt ) {
    352                 enterScope();
    353                 acceptAll( compoundStmt->get_kids(), *this );
    354                 leaveScope();
    355         }
    356 
    357         void Indexer::visit( IfStmt *ifStmt ) {
    358             // for statements introduce a level of scope
    359             enterScope();
    360             Visitor::visit( ifStmt );
    361             leaveScope();
    362         }
    363 
    364         void Indexer::visit( ForStmt *forStmt ) {
    365             // for statements introduce a level of scope
    366             enterScope();
    367             Visitor::visit( forStmt );
    368             leaveScope();
    369         }
    370 
    371         void Indexer::visit( CatchStmt *catchStmt ) {
    372                 // catch statements introduce a level of scope (for the caught exception)
    373                 enterScope();
    374                 Visitor::visit( catchStmt );
    375                 leaveScope();
    376         }
    377 
    378         void Indexer::visit( ApplicationExpr *applicationExpr ) {
    379                 acceptNewScope( applicationExpr->get_result(), *this );
    380                 maybeAccept( applicationExpr->get_function(), *this );
    381                 acceptAll( applicationExpr->get_args(), *this );
    382         }
    383 
    384         void Indexer::visit( UntypedExpr *untypedExpr ) {
    385                 acceptNewScope( untypedExpr->get_result(), *this );
    386                 acceptAll( untypedExpr->get_args(), *this );
    387         }
    388 
    389         void Indexer::visit( NameExpr *nameExpr ) {
    390                 acceptNewScope( nameExpr->get_result(), *this );
    391         }
    392 
    393         void Indexer::visit( AddressExpr *addressExpr ) {
    394                 acceptNewScope( addressExpr->get_result(), *this );
    395                 maybeAccept( addressExpr->get_arg(), *this );
    396         }
    397 
    398         void Indexer::visit( LabelAddressExpr *labAddressExpr ) {
    399                 acceptNewScope( labAddressExpr->get_result(), *this );
    400         }
    401 
    402         void Indexer::visit( CastExpr *castExpr ) {
    403                 acceptNewScope( castExpr->get_result(), *this );
    404                 maybeAccept( castExpr->get_arg(), *this );
    405         }
    406 
    407         void Indexer::visit( UntypedMemberExpr *memberExpr ) {
    408                 acceptNewScope( memberExpr->get_result(), *this );
    409                 maybeAccept( memberExpr->get_aggregate(), *this );
    410         }
    411 
    412         void Indexer::visit( MemberExpr *memberExpr ) {
    413                 acceptNewScope( memberExpr->get_result(), *this );
    414                 maybeAccept( memberExpr->get_aggregate(), *this );
    415         }
    416 
    417         void Indexer::visit( VariableExpr *variableExpr ) {
    418                 acceptNewScope( variableExpr->get_result(), *this );
    419         }
    420 
    421         void Indexer::visit( ConstantExpr *constantExpr ) {
    422                 acceptNewScope( constantExpr->get_result(), *this );
    423                 maybeAccept( constantExpr->get_constant(), *this );
    424         }
    425 
    426         void Indexer::visit( SizeofExpr *sizeofExpr ) {
    427                 acceptNewScope( sizeofExpr->get_result(), *this );
    428                 if ( sizeofExpr->get_isType() ) {
    429                         maybeAccept( sizeofExpr->get_type(), *this );
    430                 } else {
    431                         maybeAccept( sizeofExpr->get_expr(), *this );
    432                 }
    433         }
    434 
    435         void Indexer::visit( AlignofExpr *alignofExpr ) {
    436                 acceptNewScope( alignofExpr->get_result(), *this );
    437                 if ( alignofExpr->get_isType() ) {
    438                         maybeAccept( alignofExpr->get_type(), *this );
    439                 } else {
    440                         maybeAccept( alignofExpr->get_expr(), *this );
    441                 }
    442         }
    443 
    444         void Indexer::visit( UntypedOffsetofExpr *offsetofExpr ) {
    445                 acceptNewScope( offsetofExpr->get_result(), *this );
    446                 maybeAccept( offsetofExpr->get_type(), *this );
    447         }
    448 
    449         void Indexer::visit( OffsetofExpr *offsetofExpr ) {
    450                 acceptNewScope( offsetofExpr->get_result(), *this );
    451                 maybeAccept( offsetofExpr->get_type(), *this );
    452                 maybeAccept( offsetofExpr->get_member(), *this );
    453         }
    454 
    455         void Indexer::visit( OffsetPackExpr *offsetPackExpr ) {
    456                 acceptNewScope( offsetPackExpr->get_result(), *this );
    457                 maybeAccept( offsetPackExpr->get_type(), *this );
    458         }
    459 
    460         void Indexer::visit( AttrExpr *attrExpr ) {
    461                 acceptNewScope( attrExpr->get_result(), *this );
    462                 if ( attrExpr->get_isType() ) {
    463                         maybeAccept( attrExpr->get_type(), *this );
    464                 } else {
    465                         maybeAccept( attrExpr->get_expr(), *this );
    466                 }
    467         }
    468 
    469         void Indexer::visit( LogicalExpr *logicalExpr ) {
    470                 acceptNewScope( logicalExpr->get_result(), *this );
    471                 maybeAccept( logicalExpr->get_arg1(), *this );
    472                 maybeAccept( logicalExpr->get_arg2(), *this );
    473         }
    474 
    475         void Indexer::visit( ConditionalExpr *conditionalExpr ) {
    476                 acceptNewScope( conditionalExpr->get_result(), *this );
    477                 maybeAccept( conditionalExpr->get_arg1(), *this );
    478                 maybeAccept( conditionalExpr->get_arg2(), *this );
    479                 maybeAccept( conditionalExpr->get_arg3(), *this );
    480         }
    481 
    482         void Indexer::visit( CommaExpr *commaExpr ) {
    483                 acceptNewScope( commaExpr->get_result(), *this );
    484                 maybeAccept( commaExpr->get_arg1(), *this );
    485                 maybeAccept( commaExpr->get_arg2(), *this );
    486         }
    487 
    488         void Indexer::visit( TypeExpr *typeExpr ) {
    489                 acceptNewScope( typeExpr->get_result(), *this );
    490                 maybeAccept( typeExpr->get_type(), *this );
    491         }
    492 
    493         void Indexer::visit( AsmExpr *asmExpr ) {
    494                 maybeAccept( asmExpr->get_inout(), *this );
    495                 maybeAccept( asmExpr->get_constraint(), *this );
    496                 maybeAccept( asmExpr->get_operand(), *this );
    497         }
    498 
    499         void Indexer::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
    500                 acceptNewScope( impCpCtorExpr->get_result(), *this );
    501                 maybeAccept( impCpCtorExpr->get_callExpr(), *this );
    502                 acceptAll( impCpCtorExpr->get_tempDecls(), *this );
    503                 acceptAll( impCpCtorExpr->get_returnDecls(), *this );
    504                 acceptAll( impCpCtorExpr->get_dtors(), *this );
    505         }
    506 
    507         void Indexer::visit( ConstructorExpr * ctorExpr ) {
    508                 acceptNewScope( ctorExpr->get_result(), *this );
    509                 maybeAccept( ctorExpr->get_callExpr(), *this );
    510         }
    511 
    512         void Indexer::visit( CompoundLiteralExpr *compLitExpr ) {
    513                 acceptNewScope( compLitExpr->get_result(), *this );
    514                 maybeAccept( compLitExpr->get_initializer(), *this );
    515         }
    516 
    517         void Indexer::visit( RangeExpr *rangeExpr ) {
    518                 maybeAccept( rangeExpr->get_low(), *this );
    519                 maybeAccept( rangeExpr->get_high(), *this );
    520         }
    521 
    522         void Indexer::visit( UntypedTupleExpr *tupleExpr ) {
    523                 acceptNewScope( tupleExpr->get_result(), *this );
    524                 acceptAll( tupleExpr->get_exprs(), *this );
    525         }
    526 
    527         void Indexer::visit( TupleExpr *tupleExpr ) {
    528                 acceptNewScope( tupleExpr->get_result(), *this );
    529                 acceptAll( tupleExpr->get_exprs(), *this );
    530         }
    531 
    532         void Indexer::visit( TupleIndexExpr *tupleExpr ) {
    533                 acceptNewScope( tupleExpr->get_result(), *this );
    534                 maybeAccept( tupleExpr->get_tuple(), *this );
    535         }
    536 
    537         void Indexer::visit( TupleAssignExpr *tupleExpr ) {
    538                 acceptNewScope( tupleExpr->get_result(), *this );
    539                 maybeAccept( tupleExpr->get_stmtExpr(), *this );
    540         }
    541 
    542         void Indexer::visit( StmtExpr *stmtExpr ) {
    543                 acceptNewScope( stmtExpr->get_result(), *this );
    544                 maybeAccept( stmtExpr->get_statements(), *this );
    545                 acceptAll( stmtExpr->get_returnDecls(), *this );
    546                 acceptAll( stmtExpr->get_dtors(), *this );
    547         }
    548 
    549         void Indexer::visit( UniqueExpr *uniqueExpr ) {
    550                 acceptNewScope( uniqueExpr->get_result(), *this );
    551                 maybeAccept( uniqueExpr->get_expr(), *this );
    552         }
    553 
    554 
    555         void Indexer::visit( TraitInstType *traitInst ) {
    556                 acceptAll( traitInst->get_parameters(), *this );
    557         }
    558 
    559         void Indexer::visit( StructInstType *structInst ) {
    560                 if ( ! lookupStruct( structInst->get_name() ) ) {
    561                         debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
    562                         addStruct( structInst->get_name() );
    563                 }
    564                 enterScope();
    565                 acceptAll( structInst->get_parameters(), *this );
    566                 leaveScope();
    567         }
    568 
    569         void Indexer::visit( UnionInstType *unionInst ) {
    570                 if ( ! lookupUnion( unionInst->get_name() ) ) {
    571                         debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
    572                         addUnion( unionInst->get_name() );
    573                 }
    574                 enterScope();
    575                 acceptAll( unionInst->get_parameters(), *this );
    576                 leaveScope();
    577232        }
    578233
     
    762417
    763418        void Indexer::addId( DeclarationWithType *decl ) {
     419                debugPrint( "Adding Id " << decl->name << std::endl );
    764420                makeWritable();
    765421
     
    811467
    812468        void Indexer::addType( NamedTypeDecl *decl ) {
     469                debugPrint( "Adding type " << decl->name << std::endl );
    813470                makeWritable();
    814471
     
    838495
    839496        void Indexer::addStruct( const std::string &id ) {
     497                debugPrint( "Adding fwd decl for struct " << id << std::endl );
    840498                addStruct( new StructDecl( id ) );
    841499        }
    842500
    843501        void Indexer::addStruct( StructDecl *decl ) {
     502                debugPrint( "Adding struct " << decl->name << std::endl );
    844503                makeWritable();
    845504
     
    860519
    861520        void Indexer::addEnum( EnumDecl *decl ) {
     521                debugPrint( "Adding enum " << decl->name << std::endl );
    862522                makeWritable();
    863523
     
    878538
    879539        void Indexer::addUnion( const std::string &id ) {
     540                debugPrint( "Adding fwd decl for union " << id << std::endl );
    880541                addUnion( new UnionDecl( id ) );
    881542        }
    882543
    883544        void Indexer::addUnion( UnionDecl *decl ) {
     545                debugPrint( "Adding union " << decl->name << std::endl );
    884546                makeWritable();
    885547
     
    900562
    901563        void Indexer::addTrait( TraitDecl *decl ) {
     564                debugPrint( "Adding trait " << decl->name << std::endl );
    902565                makeWritable();
    903566
  • src/SymTab/Indexer.h

    red235b6 r8024bc8  
    2424
    2525namespace SymTab {
    26         class Indexer : public Visitor {
     26        class Indexer {
    2727          public:
    2828                explicit Indexer( bool useDebug = false );
     
    3333                Indexer& operator= ( const Indexer &that );
    3434                Indexer& operator= ( Indexer &&that );
    35 
    36                 using Visitor::visit;
    37                 virtual void visit( ObjectDecl *objectDecl );
    38                 virtual void visit( FunctionDecl *functionDecl );
    39                 virtual void visit( TypeDecl *typeDecl );
    40                 virtual void visit( TypedefDecl *typeDecl );
    41                 virtual void visit( StructDecl *aggregateDecl );
    42                 virtual void visit( UnionDecl *aggregateDecl );
    43                 virtual void visit( EnumDecl *aggregateDecl );
    44                 virtual void visit( TraitDecl *aggregateDecl );
    45 
    46                 virtual void visit( CompoundStmt *compoundStmt );
    47                 virtual void visit( IfStmt *ifStmt );
    48                 virtual void visit( ForStmt *forStmt );
    49                 virtual void visit( CatchStmt *catchStmt );
    50 
    51                 virtual void visit( ApplicationExpr *applicationExpr );
    52                 virtual void visit( UntypedExpr *untypedExpr );
    53                 virtual void visit( NameExpr *nameExpr );
    54                 virtual void visit( CastExpr *castExpr );
    55                 virtual void visit( AddressExpr *addressExpr );
    56                 virtual void visit( LabelAddressExpr *labAddressExpr );
    57                 virtual void visit( UntypedMemberExpr *memberExpr );
    58                 virtual void visit( MemberExpr *memberExpr );
    59                 virtual void visit( VariableExpr *variableExpr );
    60                 virtual void visit( ConstantExpr *constantExpr );
    61                 virtual void visit( SizeofExpr *sizeofExpr );
    62                 virtual void visit( AlignofExpr *alignofExpr );
    63                 virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    64                 virtual void visit( OffsetofExpr *offsetofExpr );
    65                 virtual void visit( OffsetPackExpr *offsetPackExpr );
    66                 virtual void visit( AttrExpr *attrExpr );
    67                 virtual void visit( LogicalExpr *logicalExpr );
    68                 virtual void visit( ConditionalExpr *conditionalExpr );
    69                 virtual void visit( CommaExpr *commaExpr );
    70                 virtual void visit( TypeExpr *typeExpr );
    71                 virtual void visit( AsmExpr *asmExpr );
    72                 virtual void visit( ImplicitCopyCtorExpr *impCpCtorExpr );
    73                 virtual void visit( ConstructorExpr * ctorExpr );
    74                 virtual void visit( CompoundLiteralExpr *compLitExpr );
    75                 virtual void visit( RangeExpr *rangeExpr );
    76                 virtual void visit( UntypedTupleExpr *tupleExpr );
    77                 virtual void visit( TupleExpr *tupleExpr );
    78                 virtual void visit( TupleIndexExpr *tupleExpr );
    79                 virtual void visit( TupleAssignExpr *tupleExpr );
    80                 virtual void visit( StmtExpr * stmtExpr );
    81                 virtual void visit( UniqueExpr * uniqueExpr );
    82 
    83                 virtual void visit( TraitInstType *contextInst );
    84                 virtual void visit( StructInstType *contextInst );
    85                 virtual void visit( UnionInstType *contextInst );
    8635
    8736                // when using an indexer manually (e.g., within a mutator traversal), it is necessary to tell the indexer
     
    10453
    10554                void print( std::ostream &os, int indent = 0 ) const;
    106           private:
     55
    10756                /// looks up a specific mangled ID at the given scope
    10857                DeclarationWithType *lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
     
    12776                void addTrait( TraitDecl *decl );
    12877
     78          private:
    12979                struct Impl;
    13080
  • src/SymTab/Validate.cc

    red235b6 r8024bc8  
    123123
    124124        /// Associates forward declarations of aggregates with their definitions
    125         class LinkReferenceToTypes final : public Indexer {
    126                 typedef Indexer Parent;
    127           public:
    128                 LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
    129                 using Parent::visit;
    130                 void visit( TypeInstType *typeInst ) final;
    131 
    132                 void visit( EnumInstType *enumInst ) final;
    133                 void visit( StructInstType *structInst ) final;
    134                 void visit( UnionInstType *unionInst ) final;
    135                 void visit( TraitInstType *traitInst ) final;
    136 
    137                 void visit( EnumDecl *enumDecl ) final;
    138                 void visit( StructDecl *structDecl ) final;
    139                 void visit( UnionDecl *unionDecl ) final;
    140                 void visit( TraitDecl * traitDecl ) final;
     125        struct LinkReferenceToTypes final : public WithIndexer {
     126                LinkReferenceToTypes( const Indexer *indexer );
     127                void postvisit( TypeInstType *typeInst );
     128
     129                void postvisit( EnumInstType *enumInst );
     130                void postvisit( StructInstType *structInst );
     131                void postvisit( UnionInstType *unionInst );
     132                void postvisit( TraitInstType *traitInst );
     133
     134                void postvisit( EnumDecl *enumDecl );
     135                void postvisit( StructDecl *structDecl );
     136                void postvisit( UnionDecl *unionDecl );
     137                void postvisit( TraitDecl * traitDecl );
    141138
    142139          private:
    143                 const Indexer *indexer;
     140                const Indexer *local_indexer;
    144141
    145142                typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType;
     
    152149
    153150        /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
    154         class ForallPointerDecay final : public Indexer {
    155                 typedef Indexer Parent;
    156           public:
    157                 using Parent::visit;
    158                 ForallPointerDecay( const Indexer *indexer );
    159 
    160                 virtual void visit( ObjectDecl *object ) override;
    161                 virtual void visit( FunctionDecl *func ) override;
    162 
    163                 const Indexer *indexer;
     151        struct ForallPointerDecay final {
     152                void previsit( ObjectDecl *object );
     153                void previsit( FunctionDecl *func );
    164154        };
    165155
     
    263253        };
    264254
    265         void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
     255        void validate( std::list< Declaration * > &translationUnit, __attribute__((unused)) bool doDebug ) {
    266256                PassVisitor<EnumAndPointerDecay> epc;
    267                 LinkReferenceToTypes lrt( doDebug, 0 );
    268                 ForallPointerDecay fpd( 0 );
     257                PassVisitor<LinkReferenceToTypes> lrt( nullptr );
     258                PassVisitor<ForallPointerDecay> fpd;
    269259                PassVisitor<CompoundLiteral> compoundliteral;
    270260                PassVisitor<ValidateGenericParameters> genericParams;
     
    293283        void validateType( Type *type, const Indexer *indexer ) {
    294284                PassVisitor<EnumAndPointerDecay> epc;
    295                 LinkReferenceToTypes lrt( false, indexer );
    296                 ForallPointerDecay fpd( indexer );
     285                PassVisitor<LinkReferenceToTypes> lrt( indexer );
     286                PassVisitor<ForallPointerDecay> fpd;
    297287                type->accept( epc );
    298288                type->accept( lrt );
     
    408398        }
    409399
    410         LinkReferenceToTypes::LinkReferenceToTypes( bool doDebug, const Indexer *other_indexer ) : Indexer( doDebug ) {
     400        LinkReferenceToTypes::LinkReferenceToTypes( const Indexer *other_indexer ) {
    411401                if ( other_indexer ) {
    412                         indexer = other_indexer;
     402                        local_indexer = other_indexer;
    413403                } else {
    414                         indexer = this;
    415                 } // if
    416         }
    417 
    418         void LinkReferenceToTypes::visit( EnumInstType *enumInst ) {
    419                 Parent::visit( enumInst );
    420                 EnumDecl *st = indexer->lookupEnum( enumInst->get_name() );
     404                        local_indexer = &indexer;
     405                } // if
     406        }
     407
     408        void LinkReferenceToTypes::postvisit( EnumInstType *enumInst ) {
     409                EnumDecl *st = local_indexer->lookupEnum( enumInst->get_name() );
    421410                // it's not a semantic error if the enum is not found, just an implicit forward declaration
    422411                if ( st ) {
     
    430419        }
    431420
    432         void LinkReferenceToTypes::visit( StructInstType *structInst ) {
    433                 Parent::visit( structInst );
    434                 StructDecl *st = indexer->lookupStruct( structInst->get_name() );
     421        void LinkReferenceToTypes::postvisit( StructInstType *structInst ) {
     422                StructDecl *st = local_indexer->lookupStruct( structInst->get_name() );
    435423                // it's not a semantic error if the struct is not found, just an implicit forward declaration
    436424                if ( st ) {
     
    444432        }
    445433
    446         void LinkReferenceToTypes::visit( UnionInstType *unionInst ) {
    447                 Parent::visit( unionInst );
    448                 UnionDecl *un = indexer->lookupUnion( unionInst->get_name() );
     434        void LinkReferenceToTypes::postvisit( UnionInstType *unionInst ) {
     435                UnionDecl *un = local_indexer->lookupUnion( unionInst->get_name() );
    449436                // it's not a semantic error if the union is not found, just an implicit forward declaration
    450437                if ( un ) {
     
    499486        }
    500487
    501         void LinkReferenceToTypes::visit( TraitDecl * traitDecl ) {
    502                 Parent::visit( traitDecl );
    503 
     488        void LinkReferenceToTypes::postvisit( TraitDecl * traitDecl ) {
    504489                if ( traitDecl->name == "sized" ) {
    505490                        // "sized" is a special trait - flick the sized status on for the type variable
     
    523508        }
    524509
    525         void LinkReferenceToTypes::visit( TraitInstType * traitInst ) {
    526                 Parent::visit( traitInst );
     510        void LinkReferenceToTypes::postvisit( TraitInstType * traitInst ) {
    527511                // handle other traits
    528                 TraitDecl *traitDecl = indexer->lookupTrait( traitInst->name );
     512                TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );
    529513                if ( ! traitDecl ) {
    530514                        throw SemanticError( "use of undeclared trait " + traitInst->name );
     
    547531        }
    548532
    549         void LinkReferenceToTypes::visit( EnumDecl *enumDecl ) {
     533        void LinkReferenceToTypes::postvisit( EnumDecl *enumDecl ) {
    550534                // visit enum members first so that the types of self-referencing members are updated properly
    551                 Parent::visit( enumDecl );
    552535                if ( ! enumDecl->get_members().empty() ) {
    553536                        ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->get_name() );
     
    561544        }
    562545
    563         void LinkReferenceToTypes::visit( StructDecl *structDecl ) {
     546        void LinkReferenceToTypes::postvisit( StructDecl *structDecl ) {
    564547                // visit struct members first so that the types of self-referencing members are updated properly
    565                 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and and their defaults)
    566                 Parent::visit( structDecl );
     548                // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults)
    567549                if ( ! structDecl->get_members().empty() ) {
    568550                        ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
     
    576558        }
    577559
    578         void LinkReferenceToTypes::visit( UnionDecl *unionDecl ) {
    579                 Parent::visit( unionDecl );
     560        void LinkReferenceToTypes::postvisit( UnionDecl *unionDecl ) {
    580561                if ( ! unionDecl->get_members().empty() ) {
    581562                        ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
     
    589570        }
    590571
    591         void LinkReferenceToTypes::visit( TypeInstType *typeInst ) {
    592                 if ( NamedTypeDecl *namedTypeDecl = lookupType( typeInst->get_name() ) ) {
     572        void LinkReferenceToTypes::postvisit( TypeInstType *typeInst ) {
     573                if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->get_name() ) ) {
    593574                        if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
    594575                                typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
    595576                        } // if
    596                 } // if
    597         }
    598 
    599         ForallPointerDecay::ForallPointerDecay( const Indexer *other_indexer ) :  Indexer( false ) {
    600                 if ( other_indexer ) {
    601                         indexer = other_indexer;
    602                 } else {
    603                         indexer = this;
    604577                } // if
    605578        }
     
    633606        }
    634607
    635         void ForallPointerDecay::visit( ObjectDecl *object ) {
     608        void ForallPointerDecay::previsit( ObjectDecl *object ) {
    636609                forallFixer( object->get_type() );
    637610                if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
    638611                        forallFixer( pointer->get_base() );
    639612                } // if
    640                 Parent::visit( object );
    641613                object->fixUniqueId();
    642614        }
    643615
    644         void ForallPointerDecay::visit( FunctionDecl *func ) {
     616        void ForallPointerDecay::previsit( FunctionDecl *func ) {
    645617                forallFixer( func->get_type() );
    646                 Parent::visit( func );
    647618                func->fixUniqueId();
    648619        }
Note: See TracChangeset for help on using the changeset viewer.