Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.cc

    r33a25f9 re3e16bc  
    3737#include "SynTree/Type.h"          // for Type, StructInstType, UnionInstType
    3838
    39 #define debugPrint(x) if ( doDebug ) { std::cerr << x; }
     39#define debugPrint(x) if ( doDebug ) { std::cout << 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();
    232577        }
    233578
     
    417762
    418763        void Indexer::addId( DeclarationWithType *decl ) {
    419                 debugPrint( "Adding Id " << decl->name << std::endl );
    420764                makeWritable();
    421765
     
    467811
    468812        void Indexer::addType( NamedTypeDecl *decl ) {
    469                 debugPrint( "Adding type " << decl->name << std::endl );
    470813                makeWritable();
    471814
     
    495838
    496839        void Indexer::addStruct( const std::string &id ) {
    497                 debugPrint( "Adding fwd decl for struct " << id << std::endl );
    498840                addStruct( new StructDecl( id ) );
    499841        }
    500842
    501843        void Indexer::addStruct( StructDecl *decl ) {
    502                 debugPrint( "Adding struct " << decl->name << std::endl );
    503844                makeWritable();
    504845
     
    519860
    520861        void Indexer::addEnum( EnumDecl *decl ) {
    521                 debugPrint( "Adding enum " << decl->name << std::endl );
    522862                makeWritable();
    523863
     
    538878
    539879        void Indexer::addUnion( const std::string &id ) {
    540                 debugPrint( "Adding fwd decl for union " << id << std::endl );
    541880                addUnion( new UnionDecl( id ) );
    542881        }
    543882
    544883        void Indexer::addUnion( UnionDecl *decl ) {
    545                 debugPrint( "Adding union " << decl->name << std::endl );
    546884                makeWritable();
    547885
     
    562900
    563901        void Indexer::addTrait( TraitDecl *decl ) {
    564                 debugPrint( "Adding trait " << decl->name << std::endl );
    565902                makeWritable();
    566903
Note: See TracChangeset for help on using the changeset viewer.