Changes in / [5f782f7:3e3d923]
- Location:
- src
- Files:
-
- 10 edited
-
Common/PassVisitor.impl.h (modified) (10 diffs)
-
GenPoly/Box.cc (modified) (2 diffs)
-
InitTweak/FixInit.cc (modified) (23 diffs)
-
ResolvExpr/AlternativeFinder.cc (modified) (1 diff)
-
ResolvExpr/AlternativePrinter.cc (modified) (1 diff)
-
ResolvExpr/AlternativePrinter.h (modified) (1 diff)
-
ResolvExpr/Resolver.cc (modified) (24 diffs)
-
SymTab/Indexer.cc (modified) (7 diffs)
-
SymTab/Indexer.h (modified) (2 diffs)
-
main.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Common/PassVisitor.impl.h
r5f782f7 r3e3d923 183 183 184 184 } catch ( SemanticError &e ) { 185 e.set_location( (*i)->location );186 185 errors.append( e ); 187 186 } … … 293 292 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 294 293 295 // A NOTE ON THE ORDER OF TRAVERSAL296 //297 // Types and typedefs have their base types visited before they are added to the type table. This is ok, since there is298 // no such thing as a recursive type or typedef.299 //300 // typedef struct { T *x; } T; // never allowed301 //302 // for structs/unions, it is possible to have recursion, so the decl should be added as if it's incomplete to begin, the303 // members are traversed, and then the complete type should be added (assuming the type is completed by this particular304 // declaration).305 //306 // struct T { struct T *x; }; // allowed307 //308 // It is important to add the complete type to the symbol table *after* the members/base has been traversed, since that309 // traversal may modify the definition of the type and these modifications should be visible when the symbol table is310 // queried later in this pass.311 //312 // TODO: figure out whether recursive contexts are sensible/possible/reasonable.313 294 314 295 //-------------------------------------------------------------------------- … … 468 449 indexerAddEnum( node ); 469 450 470 // unlike structs, traits, and unions, enums inject their members into the global scope451 // unlike structs, contexts, and unions, enums inject their members into the global scope 471 452 maybeAccept( node->parameters, *this ); 472 453 maybeAccept( node->members , *this ); … … 532 513 } 533 514 534 // see A NOTE ON THE ORDER OF TRAVERSAL, above535 // note that assertions come after the type is added to the symtab, since they are not part of the type proper536 // and may depend on the type itself537 515 indexerAddType( node ); 538 516 … … 554 532 } 555 533 556 // see A NOTE ON THE ORDER OF TRAVERSAL, above557 // note that assertions come after the type is added to the symtab, since they are not part of the type proper558 // and may depend on the type itself559 534 indexerAddType( node ); 560 535 … … 683 658 void PassVisitor< pass_type >::visit( IfStmt * node ) { 684 659 VISIT_START( node ); 685 { 686 // if statements introduce a level of scope (for the initialization) 660 661 visitExpression( node->condition ); 662 node->thenPart = visitStatement( node->thenPart ); 663 node->elsePart = visitStatement( node->elsePart ); 664 665 VISIT_END( node ); 666 } 667 668 template< typename pass_type > 669 Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) { 670 MUTATE_START( node ); 671 { 687 672 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 688 acceptAll( node->get_initialization(), *this );689 visitExpression( node->condition );690 node->thenPart = visitStatement( node->thenPart );691 node->elsePart = visitStatement( node->elsePart );692 }693 VISIT_END( node );694 }695 696 template< typename pass_type >697 Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {698 MUTATE_START( node );699 {700 // if statements introduce a level of scope (for the initialization)701 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );702 maybeMutateRef( node->get_initialization(), *this );703 673 node->condition = mutateExpression( node->condition ); 704 674 node->thenPart = mutateStatement ( node->thenPart ); … … 736 706 VISIT_START( node ); 737 707 { 738 // for statements introduce a level of scope (for the initialization)739 708 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 740 709 maybeAccept( node->initialization, *this ); … … 750 719 MUTATE_START( node ); 751 720 { 752 // for statements introduce a level of scope (for the initialization)753 721 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 754 722 maybeMutateRef( node->initialization, *this ); … … 879 847 VISIT_START( node ); 880 848 { 881 // catch statements introduce a level of scope (for the caught exception)882 849 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 883 850 maybeAccept( node->decl, *this ); … … 892 859 MUTATE_START( node ); 893 860 { 894 // catch statements introduce a level of scope (for the caught exception)895 861 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 896 862 maybeMutateRef( node->decl, *this ); -
src/GenPoly/Box.cc
r5f782f7 r3e3d923 628 628 } else { 629 629 // xxx - should this be an assertion? 630 throw SemanticError( toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ), appExpr ); 630 std::string x = env ? toString( *env ) : "missing env"; 631 throw SemanticError( x + "\n" + "unbound type variable: " + tyParm->first + " in application ", appExpr ); 631 632 } // if 632 633 } // if … … 705 706 if ( concrete == 0 ) { 706 707 return typeInst; 708 // xxx - should this be an assertion? 709 // std::string x = env ? toString( *env ) : "missing env"; 710 // throw SemanticError( x + "\n" + "Unbound type variable " + typeInst->get_name() + " in ", appExpr ); 707 711 } // if 708 712 return concrete; -
src/InitTweak/FixInit.cc
r5f782f7 r3e3d923 70 70 namespace InitTweak { 71 71 namespace { 72 typedef std::unordered_map< Expression *, TypeSubstitution * > EnvMap; 72 73 typedef std::unordered_map< int, int > UnqCount; 73 74 74 struct InsertImplicitCalls : public WithTypeSubstitution { 75 class InsertImplicitCalls : public WithTypeSubstitution { 76 public: 75 77 /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which 76 78 /// function calls need their parameters to be copy constructed 77 static void insert( std::list< Declaration * > & translationUnit ); 79 static void insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ); 80 81 InsertImplicitCalls( EnvMap & envMap ) : envMap( envMap ) {} 78 82 79 83 Expression * postmutate( ApplicationExpr * appExpr ); 84 void premutate( StmtExpr * stmtExpr ); 85 86 // collects environments for relevant nodes 87 EnvMap & envMap; 80 88 }; 81 89 82 struct ResolveCopyCtors final : public WithIndexer, public WithShortCircuiting, public WithTypeSubstitution { 90 class ResolveCopyCtors final : public SymTab::Indexer { 91 public: 83 92 /// generate temporary ObjectDecls for each argument and return value of each ImplicitCopyCtorExpr, 84 93 /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both 85 94 /// arguments and return value temporaries 86 static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, UnqCount & unqCount ); 87 88 ResolveCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ) {} 89 90 void postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ); 91 void postvisit( StmtExpr * stmtExpr ); 92 void previsit( UniqueExpr * unqExpr ); 93 void postvisit( UniqueExpr * unqExpr ); 95 static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap, UnqCount & unqCount ); 96 97 typedef SymTab::Indexer Parent; 98 using Parent::visit; 99 100 ResolveCopyCtors( const EnvMap & envMap, UnqCount & unqCount ) : envMap( envMap ), unqCount( unqCount ) {} 101 102 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override; 103 virtual void visit( UniqueExpr * unqExpr ) override; 104 virtual void visit( StmtExpr * stmtExpr ) override; 94 105 95 106 /// create and resolve ctor/dtor expression: fname(var, [cpArg]) … … 100 111 void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 101 112 113 TypeSubstitution * env; 114 const EnvMap & envMap; 102 115 UnqCount & unqCount; // count the number of times each unique expr ID appears 103 std::unordered_set< int > vars;104 116 }; 105 117 … … 226 238 }; 227 239 228 struct GenStructMemberCalls final : public WithGuards, public WithShortCircuiting, public WithIndexer { 240 class GenStructMemberCalls final : public SymTab::Indexer { 241 public: 242 typedef Indexer Parent; 229 243 /// generate default/copy ctor and dtor calls for user-defined struct ctor/dtors 230 244 /// for any member that is missing a corresponding ctor/dtor call. … … 232 246 static void generate( std::list< Declaration * > & translationUnit ); 233 247 234 void previsit( FunctionDecl * funcDecl ); 235 void postvisit( FunctionDecl * funcDecl ); 236 237 void previsit( MemberExpr * memberExpr ); 238 void previsit( ApplicationExpr * appExpr ); 248 using Parent::visit; 249 250 virtual void visit( FunctionDecl * funcDecl ) override; 251 252 virtual void visit( MemberExpr * memberExpr ) override; 253 virtual void visit( ApplicationExpr * appExpr ) override; 239 254 240 255 SemanticError errors; … … 280 295 InitTweak::fixGlobalInit( translationUnit, filename, inLibrary ); 281 296 297 EnvMap envMap; 282 298 UnqCount unqCount; 283 299 284 InsertImplicitCalls::insert( translationUnit );285 ResolveCopyCtors::resolveImplicitCalls( translationUnit, unqCount );300 InsertImplicitCalls::insert( translationUnit, envMap ); 301 ResolveCopyCtors::resolveImplicitCalls( translationUnit, envMap, unqCount ); 286 302 InsertDtors::insert( translationUnit ); 287 303 FixInit::fixInitializers( translationUnit ); … … 302 318 303 319 namespace { 304 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit ) {305 PassVisitor<InsertImplicitCalls> inserter ;320 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ) { 321 PassVisitor<InsertImplicitCalls> inserter( envMap ); 306 322 mutateAll( translationUnit, inserter ); 307 323 } 308 324 309 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {310 PassVisitor<ResolveCopyCtors> resolver(unqCount );325 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap, UnqCount & unqCount ) { 326 ResolveCopyCtors resolver( envMap, unqCount ); 311 327 acceptAll( translationUnit, resolver ); 312 328 } … … 344 360 345 361 void GenStructMemberCalls::generate( std::list< Declaration * > & translationUnit ) { 346 PassVisitor<GenStructMemberCalls>warner;362 GenStructMemberCalls warner; 347 363 acceptAll( translationUnit, warner ); 348 364 } … … 382 398 // wrap each function call so that it is easy to identify nodes that have to be copy constructed 383 399 ImplicitCopyCtorExpr * expr = new ImplicitCopyCtorExpr( appExpr ); 384 // Move the type substitution to the new top-level, if it is attached to the appExpr.400 // save the type substitution into the envMap so that it is easy to find. 385 401 // Ensure it is not deleted with the ImplicitCopyCtorExpr by removing it before deletion. 386 402 // The substitution is needed to obtain the type of temporary variables so that copy constructor 387 // calls can be resolved. 403 // calls can be resolved. Normally this is what PolyMutator is for, but the pass that resolves 404 // copy constructor calls must be an Indexer. We could alternatively make a PolyIndexer which 405 // saves the environment, or compute the types of temporaries here, but it's much simpler to 406 // save the environment here, and more cohesive to compute temporary variables and resolve copy 407 // constructor calls together. 388 408 assert( env ); 389 std::swap( expr->env, appExpr->env );409 envMap[expr] = env; 390 410 return expr; 411 } 412 413 void InsertImplicitCalls::premutate( StmtExpr * stmtExpr ) { 414 assert( env ); 415 envMap[stmtExpr] = env; 391 416 } 392 417 … … 406 431 // (VariableExpr and already resolved expression) 407 432 CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; ) 408 Expression * resolved = ResolvExpr::findVoidExpression( untyped, indexer);433 Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this ); 409 434 assert( resolved ); 410 435 if ( resolved->get_env() ) { … … 455 480 } 456 481 457 void ResolveCopyCtors:: postvisit( ImplicitCopyCtorExpr *impCpCtorExpr ) {482 void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) { 458 483 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 484 Parent::visit( impCpCtorExpr ); 485 env = envMap.at(impCpCtorExpr); 486 assert( env ); 459 487 460 488 ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr(); … … 485 513 } 486 514 487 void ResolveCopyCtors::postvisit( StmtExpr * stmtExpr ) { 488 assert( env ); 515 void ResolveCopyCtors::visit( StmtExpr * stmtExpr ) { 516 Parent::visit( stmtExpr ); 517 env = envMap.at(stmtExpr); 489 518 assert( stmtExpr->get_result() ); 490 519 Type * result = stmtExpr->get_result(); … … 508 537 stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) ); 509 538 } // if 510 } 511 512 void ResolveCopyCtors::previsit( UniqueExpr * unqExpr ) { 539 540 } 541 542 void ResolveCopyCtors::visit( UniqueExpr * unqExpr ) { 543 static std::unordered_set< int > vars; 513 544 unqCount[ unqExpr->get_id() ]++; // count the number of unique expressions for each ID 514 545 if ( vars.count( unqExpr->get_id() ) ) { 515 546 // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated 516 visit_children = false;517 }518 }519 520 void ResolveCopyCtors::postvisit( UniqueExpr * unqExpr ) {521 if ( vars.count( unqExpr->get_id() ) ) {522 // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated523 547 return; 524 548 } 525 549 550 Parent::visit( unqExpr ); 526 551 // it should never be necessary to wrap a void-returning expression in a UniqueExpr - if this assumption changes, this needs to be rethought 527 552 assert( unqExpr->get_result() ); … … 560 585 561 586 // xxx - update to work with multiple return values 562 ObjectDecl * returnDecl = returnDecls.empty() ? nullptr: returnDecls.front();587 ObjectDecl * returnDecl = returnDecls.empty() ? NULL : returnDecls.front(); 563 588 Expression * callExpr = impCpCtorExpr->get_callExpr(); 564 589 … … 569 594 tempDecls.clear(); 570 595 returnDecls.clear(); 571 impCpCtorExpr->set_callExpr( nullptr ); 572 std::swap( impCpCtorExpr->env, callExpr->env ); 573 assert( impCpCtorExpr->env == nullptr ); 596 impCpCtorExpr->set_callExpr( NULL ); 597 impCpCtorExpr->set_env( NULL ); 574 598 delete impCpCtorExpr; 575 599 … … 954 978 } 955 979 956 void GenStructMemberCalls:: previsit( FunctionDecl * funcDecl ) {957 GuardValue( funcDecl );958 GuardValue( unhandled );959 GuardValue( usedUninit );960 GuardValue( thisParam );961 GuardValue( isCtor );962 GuardValue( structDecl );980 void GenStructMemberCalls::visit( FunctionDecl * funcDecl ) { 981 ValueGuard< FunctionDecl * > oldFunction( funcDecl ); 982 ValueGuard< std::set< DeclarationWithType * > > oldUnhandled( unhandled ); 983 ValueGuard< std::map< DeclarationWithType *, CodeLocation > > oldUsedUninit( usedUninit ); 984 ValueGuard< ObjectDecl * > oldThisParam( thisParam ); 985 ValueGuard< bool > oldIsCtor( isCtor ); 986 ValueGuard< StructDecl * > oldStructDecl( structDecl ); 963 987 errors = SemanticError(); // clear previous errors 964 988 … … 986 1010 } 987 1011 } 988 } 989 990 void addIds( SymTab::Indexer & indexer, const std::list< DeclarationWithType * > & decls ) { 991 for ( auto d : decls ) { 992 indexer.addId( d ); 993 } 994 } 995 996 void addTypes( SymTab::Indexer & indexer, const std::list< TypeDecl * > & tds ) { 997 for ( auto td : tds ) { 998 indexer.addType( td ); 999 addIds( indexer, td->assertions ); 1000 } 1001 } 1002 1003 void GenStructMemberCalls::postvisit( FunctionDecl * funcDecl ) { 1012 Parent::visit( function ); 1013 1004 1014 // remove the unhandled objects from usedUninit, because a call is inserted 1005 1015 // to handle them - only objects that are later constructed are used uninitialized. … … 1022 1032 if ( ! unhandled.empty() ) { 1023 1033 // need to explicitly re-add function parameters to the indexer in order to resolve copy constructors 1024 auto guard = makeFuncGuard( [this]() { indexer.enterScope(); }, [this]() { indexer.leaveScope(); } ); 1025 addTypes( indexer, function->type->forall ); 1026 addIds( indexer, function->type->returnVals ); 1027 addIds( indexer, function->type->parameters ); 1034 enterScope(); 1035 maybeAccept( function->get_functionType(), *this ); 1028 1036 1029 1037 // need to iterate through members in reverse in order for … … 1055 1063 Statement * callStmt = stmt.front(); 1056 1064 1057 MutatingResolver resolver( indexer);1065 MutatingResolver resolver( *this ); 1058 1066 try { 1059 1067 callStmt->acceptMutator( resolver ); … … 1069 1077 } 1070 1078 } 1079 leaveScope(); 1071 1080 } 1072 1081 if (! errors.isEmpty()) { … … 1098 1107 } 1099 1108 1100 void GenStructMemberCalls::previsit( ApplicationExpr * appExpr ) { 1101 if ( ! checkWarnings( function ) ) { 1102 visit_children = false; 1103 return; 1104 } 1109 void GenStructMemberCalls::visit( ApplicationExpr * appExpr ) { 1110 if ( ! checkWarnings( function ) ) return; 1105 1111 1106 1112 std::string fname = getFunctionName( appExpr ); … … 1121 1127 } 1122 1128 } 1123 } 1124 1125 void GenStructMemberCalls::previsit( MemberExpr * memberExpr ) { 1126 if ( ! checkWarnings( function ) || ! isCtor ) { 1127 visit_children = false; 1128 return; 1129 } 1129 Parent::visit( appExpr ); 1130 } 1131 1132 void GenStructMemberCalls::visit( MemberExpr * memberExpr ) { 1133 if ( ! checkWarnings( function ) ) return; 1134 if ( ! isCtor ) return; 1130 1135 1131 1136 if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) { … … 1135 1140 } 1136 1141 } 1142 Parent::visit( memberExpr ); 1137 1143 } 1138 1144 … … 1155 1161 // in generated code. If this changes, add mutate methods for entities with 1156 1162 // scope and call {enter,leave}Scope explicitly. 1157 indexer.addId( objectDecl);1163 objectDecl->accept( indexer ); 1158 1164 return objectDecl; 1159 1165 } -
src/ResolvExpr/AlternativeFinder.cc
r5f782f7 r3e3d923 523 523 for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) { 524 524 if ( i->second.isUsed ) { 525 i ndexer.addId( i->first);525 i->first->accept( indexer ); 526 526 } 527 527 } -
src/ResolvExpr/AlternativePrinter.cc
r5f782f7 r3e3d923 26 26 27 27 namespace ResolvExpr { 28 AlternativePrinter::AlternativePrinter( std::ostream &os ) : os( os ) {}28 AlternativePrinter::AlternativePrinter( std::ostream &os ) : SymTab::Indexer( false ), os( os ) {} 29 29 30 void AlternativePrinter:: postvisit( ExprStmt *exprStmt ) {30 void AlternativePrinter::visit( ExprStmt *exprStmt ) { 31 31 TypeEnvironment env; 32 AlternativeFinder finder( indexer, env );32 AlternativeFinder finder( *this, env ); 33 33 finder.findWithAdjustment( exprStmt->get_expr() ); 34 34 int count = 1; -
src/ResolvExpr/AlternativePrinter.h
r5f782f7 r3e3d923 18 18 #include <iostream> // for ostream 19 19 20 #include " Common/PassVisitor.h"20 #include "SymTab/Indexer.h" // for Indexer 21 21 22 22 class ExprStmt; 23 23 24 24 namespace ResolvExpr { 25 class AlternativePrinter final : public WithIndexer {25 class AlternativePrinter final : public SymTab::Indexer { 26 26 public: 27 27 AlternativePrinter( std::ostream &os ); 28 28 29 void postvisit( ExprStmt *exprStmt ); 29 using SymTab::Indexer::visit; 30 virtual void visit( ExprStmt *exprStmt ) override; 30 31 private: 31 32 std::ostream &os; -
src/ResolvExpr/Resolver.cc
r5f782f7 r3e3d923 21 21 #include "Alternative.h" // for Alternative, AltList 22 22 #include "AlternativeFinder.h" // for AlternativeFinder, resolveIn... 23 #include "Common/PassVisitor.h" // for PassVisitor24 23 #include "Common/SemanticError.h" // for SemanticError 25 24 #include "Common/utility.h" // for ValueGuard, group_iterate … … 44 43 45 44 namespace ResolvExpr { 46 struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting { 47 Resolver() {} 48 Resolver( const SymTab::Indexer & other ) { 49 indexer = other; 50 } 51 52 void previsit( FunctionDecl *functionDecl ); 53 void postvisit( FunctionDecl *functionDecl ); 54 void previsit( ObjectDecl *functionDecl ); 55 void previsit( TypeDecl *typeDecl ); 56 void previsit( EnumDecl * enumDecl ); 57 58 void previsit( ArrayType * at ); 59 void previsit( PointerType * at ); 60 61 void previsit( ExprStmt *exprStmt ); 62 void previsit( AsmExpr *asmExpr ); 63 void previsit( AsmStmt *asmStmt ); 64 void previsit( IfStmt *ifStmt ); 65 void previsit( WhileStmt *whileStmt ); 66 void previsit( ForStmt *forStmt ); 67 void previsit( SwitchStmt *switchStmt ); 68 void previsit( CaseStmt *caseStmt ); 69 void previsit( BranchStmt *branchStmt ); 70 void previsit( ReturnStmt *returnStmt ); 71 void previsit( ThrowStmt *throwStmt ); 72 void previsit( CatchStmt *catchStmt ); 73 74 void previsit( SingleInit *singleInit ); 75 void previsit( ListInit *listInit ); 76 void previsit( ConstructorInit *ctorInit ); 45 class Resolver final : public SymTab::Indexer { 46 public: 47 Resolver() : SymTab::Indexer( false ) {} 48 Resolver( const SymTab:: Indexer & other ) : SymTab::Indexer( other ) { 49 if ( const Resolver * res = dynamic_cast< const Resolver * >( &other ) ) { 50 functionReturn = res->functionReturn; 51 currentObject = res->currentObject; 52 inEnumDecl = res->inEnumDecl; 53 } 54 } 55 56 typedef SymTab::Indexer Parent; 57 using Parent::visit; 58 virtual void visit( FunctionDecl *functionDecl ) override; 59 virtual void visit( ObjectDecl *functionDecl ) override; 60 virtual void visit( TypeDecl *typeDecl ) override; 61 virtual void visit( EnumDecl * enumDecl ) override; 62 63 virtual void visit( ArrayType * at ) override; 64 virtual void visit( PointerType * at ) override; 65 66 virtual void visit( ExprStmt *exprStmt ) override; 67 virtual void visit( AsmExpr *asmExpr ) override; 68 virtual void visit( AsmStmt *asmStmt ) override; 69 virtual void visit( IfStmt *ifStmt ) override; 70 virtual void visit( WhileStmt *whileStmt ) override; 71 virtual void visit( ForStmt *forStmt ) override; 72 virtual void visit( SwitchStmt *switchStmt ) override; 73 virtual void visit( CaseStmt *caseStmt ) override; 74 virtual void visit( BranchStmt *branchStmt ) override; 75 virtual void visit( ReturnStmt *returnStmt ) override; 76 virtual void visit( ThrowStmt *throwStmt ) override; 77 virtual void visit( CatchStmt *catchStmt ) override; 78 79 virtual void visit( SingleInit *singleInit ) override; 80 virtual void visit( ListInit *listInit ) override; 81 virtual void visit( ConstructorInit *ctorInit ) override; 77 82 private: 78 83 typedef std::list< Initializer * >::iterator InitIterator; … … 91 96 92 97 void resolve( std::list< Declaration * > translationUnit ) { 93 PassVisitor<Resolver>resolver;98 Resolver resolver; 94 99 acceptAll( translationUnit, resolver ); 95 100 } 96 101 97 // used in resolveTypeof98 102 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) { 99 103 TypeEnvironment env; 100 104 return resolveInVoidContext( expr, indexer, env ); 101 105 } 106 102 107 103 108 namespace { … … 185 190 } 186 191 187 void Resolver:: previsit( ObjectDecl *objectDecl ) {188 Type *new_type = resolveTypeof( objectDecl->get_type(), indexer);192 void Resolver::visit( ObjectDecl *objectDecl ) { 193 Type *new_type = resolveTypeof( objectDecl->get_type(), *this ); 189 194 objectDecl->set_type( new_type ); 190 195 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable … … 193 198 // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting 194 199 // the RHS. 195 GuardValue( currentObject );200 ValueGuard<CurrentObject> temp( currentObject ); 196 201 currentObject = CurrentObject( objectDecl->get_type() ); 197 202 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) { … … 200 205 currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ); 201 206 } 207 Parent::visit( objectDecl ); 208 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) { 209 // delete newly created signed int type 210 // delete currentObject.getType(); 211 } 202 212 } 203 213 … … 206 216 if ( type->get_dimension() ) { 207 217 CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() ); 208 Expression *newExpr = findSingleExpression( castExpr, indexer);218 Expression *newExpr = findSingleExpression( castExpr, *this ); 209 219 delete type->get_dimension(); 210 220 type->set_dimension( newExpr ); … … 212 222 } 213 223 214 void Resolver:: previsit( ArrayType * at ) {224 void Resolver::visit( ArrayType * at ) { 215 225 handlePtrType( at ); 216 } 217 218 void Resolver::previsit( PointerType * pt ) { 226 Parent::visit( at ); 227 } 228 229 void Resolver::visit( PointerType * pt ) { 219 230 handlePtrType( pt ); 220 } 221 222 void Resolver::previsit( TypeDecl *typeDecl ) { 231 Parent::visit( pt ); 232 } 233 234 void Resolver::visit( TypeDecl *typeDecl ) { 223 235 if ( typeDecl->get_base() ) { 224 Type *new_type = resolveTypeof( typeDecl->get_base(), indexer);236 Type *new_type = resolveTypeof( typeDecl->get_base(), *this ); 225 237 typeDecl->set_base( new_type ); 226 238 } // if 227 } 228 229 void Resolver::previsit( FunctionDecl *functionDecl ) { 239 Parent::visit( typeDecl ); 240 } 241 242 void Resolver::visit( FunctionDecl *functionDecl ) { 230 243 #if 0 231 std::c err<< "resolver visiting functiondecl ";232 functionDecl->print( std::c err);233 std::c err<< std::endl;244 std::cout << "resolver visiting functiondecl "; 245 functionDecl->print( std::cout ); 246 std::cout << std::endl; 234 247 #endif 235 Type *new_type = resolveTypeof( functionDecl->get_type(), indexer);248 Type *new_type = resolveTypeof( functionDecl->get_type(), *this ); 236 249 functionDecl->set_type( new_type ); 237 GuardValue( functionReturn );250 ValueGuard< Type * > oldFunctionReturn( functionReturn ); 238 251 functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() ); 239 } 240 241 242 void Resolver::postvisit( FunctionDecl *functionDecl ) { 252 Parent::visit( functionDecl ); 253 243 254 // default value expressions have an environment which shouldn't be there and trips up later passes. 244 255 // xxx - it might be necessary to somehow keep the information from this environment, but I can't currently … … 254 265 } 255 266 256 void Resolver:: previsit( EnumDecl *) {267 void Resolver::visit( EnumDecl * enumDecl ) { 257 268 // in case we decide to allow nested enums 258 GuardValue( inEnumDecl );269 ValueGuard< bool > oldInEnumDecl( inEnumDecl ); 259 270 inEnumDecl = true; 260 }261 262 void Resolver::previsit( ExprStmt *exprStmt ) { 263 visit_children = false;271 Parent::visit( enumDecl ); 272 } 273 274 void Resolver::visit( ExprStmt *exprStmt ) { 264 275 assertf( exprStmt->get_expr(), "ExprStmt has null Expression in resolver" ); 265 Expression *newExpr = findVoidExpression( exprStmt->get_expr(), indexer);276 Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this ); 266 277 delete exprStmt->get_expr(); 267 278 exprStmt->set_expr( newExpr ); 268 279 } 269 280 270 void Resolver::previsit( AsmExpr *asmExpr ) { 271 visit_children = false; 272 Expression *newExpr = findVoidExpression( asmExpr->get_operand(), indexer ); 281 void Resolver::visit( AsmExpr *asmExpr ) { 282 Expression *newExpr = findVoidExpression( asmExpr->get_operand(), *this ); 273 283 delete asmExpr->get_operand(); 274 284 asmExpr->set_operand( newExpr ); 275 285 if ( asmExpr->get_inout() ) { 276 newExpr = findVoidExpression( asmExpr->get_inout(), indexer);286 newExpr = findVoidExpression( asmExpr->get_inout(), *this ); 277 287 delete asmExpr->get_inout(); 278 288 asmExpr->set_inout( newExpr ); … … 280 290 } 281 291 282 void Resolver::previsit( AsmStmt *asmStmt ) { 283 visit_children = false; 284 acceptAll( asmStmt->get_input(), *visitor ); 285 acceptAll( asmStmt->get_output(), *visitor ); 286 } 287 288 void Resolver::previsit( IfStmt *ifStmt ) { 289 Expression *newExpr = findSingleExpression( ifStmt->get_condition(), indexer ); 292 void Resolver::visit( AsmStmt *asmStmt ) { 293 acceptAll( asmStmt->get_input(), *this); 294 acceptAll( asmStmt->get_output(), *this); 295 } 296 297 void Resolver::visit( IfStmt *ifStmt ) { 298 Expression *newExpr = findSingleExpression( ifStmt->get_condition(), *this ); 290 299 delete ifStmt->get_condition(); 291 300 ifStmt->set_condition( newExpr ); 292 } 293 294 void Resolver::previsit( WhileStmt *whileStmt ) { 295 Expression *newExpr = findSingleExpression( whileStmt->get_condition(), indexer ); 301 Parent::visit( ifStmt ); 302 } 303 304 void Resolver::visit( WhileStmt *whileStmt ) { 305 Expression *newExpr = findSingleExpression( whileStmt->get_condition(), *this ); 296 306 delete whileStmt->get_condition(); 297 307 whileStmt->set_condition( newExpr ); 298 } 299 300 void Resolver::previsit( ForStmt *forStmt ) { 308 Parent::visit( whileStmt ); 309 } 310 311 void Resolver::visit( ForStmt *forStmt ) { 312 Parent::visit( forStmt ); 313 301 314 if ( forStmt->get_condition() ) { 302 Expression * newExpr = findSingleExpression( forStmt->get_condition(), indexer);315 Expression * newExpr = findSingleExpression( forStmt->get_condition(), *this ); 303 316 delete forStmt->get_condition(); 304 317 forStmt->set_condition( newExpr ); … … 306 319 307 320 if ( forStmt->get_increment() ) { 308 Expression * newExpr = findVoidExpression( forStmt->get_increment(), indexer);321 Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this ); 309 322 delete forStmt->get_increment(); 310 323 forStmt->set_increment( newExpr ); … … 312 325 } 313 326 314 void Resolver:: previsit( SwitchStmt *switchStmt ) {315 GuardValue( currentObject );327 void Resolver::visit( SwitchStmt *switchStmt ) { 328 ValueGuard< CurrentObject > oldCurrentObject( currentObject ); 316 329 Expression *newExpr; 317 newExpr = findIntegralExpression( switchStmt->get_condition(), indexer);330 newExpr = findIntegralExpression( switchStmt->get_condition(), *this ); 318 331 delete switchStmt->get_condition(); 319 332 switchStmt->set_condition( newExpr ); 320 333 321 334 currentObject = CurrentObject( newExpr->get_result() ); 322 } 323 324 void Resolver::previsit( CaseStmt *caseStmt ) { 335 Parent::visit( switchStmt ); 336 } 337 338 void Resolver::visit( CaseStmt *caseStmt ) { 325 339 if ( caseStmt->get_condition() ) { 326 340 std::list< InitAlternative > initAlts = currentObject.getOptions(); 327 341 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." ); 328 342 CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() ); 329 Expression * newExpr = findSingleExpression( castExpr, indexer);343 Expression * newExpr = findSingleExpression( castExpr, *this ); 330 344 castExpr = strict_dynamic_cast< CastExpr * >( newExpr ); 331 345 caseStmt->set_condition( castExpr->get_arg() ); … … 333 347 delete castExpr; 334 348 } 335 }336 337 void Resolver::previsit( BranchStmt *branchStmt ) { 338 visit_children = false;349 Parent::visit( caseStmt ); 350 } 351 352 void Resolver::visit( BranchStmt *branchStmt ) { 339 353 // must resolve the argument for a computed goto 340 354 if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement … … 343 357 PointerType pt( Type::Qualifiers(), v.clone() ); 344 358 CastExpr * castExpr = new CastExpr( arg, pt.clone() ); 345 Expression * newExpr = findSingleExpression( castExpr, indexer); // find best expression359 Expression * newExpr = findSingleExpression( castExpr, *this ); // find best expression 346 360 branchStmt->set_target( newExpr ); 347 361 } // if … … 349 363 } 350 364 351 void Resolver::previsit( ReturnStmt *returnStmt ) { 352 visit_children = false; 365 void Resolver::visit( ReturnStmt *returnStmt ) { 353 366 if ( returnStmt->get_expr() ) { 354 367 CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() ); 355 Expression *newExpr = findSingleExpression( castExpr, indexer);368 Expression *newExpr = findSingleExpression( castExpr, *this ); 356 369 delete castExpr; 357 370 returnStmt->set_expr( newExpr ); … … 359 372 } 360 373 361 void Resolver::previsit( ThrowStmt *throwStmt ) { 362 visit_children = false; 374 void Resolver::visit( ThrowStmt *throwStmt ) { 363 375 // TODO: Replace *exception type with &exception type. 364 376 if ( throwStmt->get_expr() ) { 365 377 StructDecl * exception_decl = 366 indexer.lookupStruct( "__cfaehm__base_exception_t" );378 lookupStruct( "__cfaehm__base_exception_t" ); 367 379 assert( exception_decl ); 368 380 Expression * wrapped = new CastExpr( … … 376 388 ) 377 389 ); 378 Expression * newExpr = findSingleExpression( wrapped, indexer);390 Expression * newExpr = findSingleExpression( wrapped, *this ); 379 391 throwStmt->set_expr( newExpr ); 380 392 } 381 393 } 382 394 383 void Resolver::previsit( CatchStmt *catchStmt ) { 395 void Resolver::visit( CatchStmt *catchStmt ) { 396 // inline Indexer::visit so that the exception variable is still in-scope for 397 // findSingleExpression() below 398 Parent::enterScope(); 399 Visitor::visit( catchStmt ); 400 384 401 if ( catchStmt->get_cond() ) { 385 402 Expression * wrapped = new CastExpr( … … 387 404 new BasicType( noQualifiers, BasicType::Bool ) 388 405 ); 389 catchStmt->set_cond( findSingleExpression( wrapped, indexer ) ); 390 } 406 catchStmt->set_cond( findSingleExpression( wrapped, *this ) ); 407 } 408 409 Parent::leaveScope(); 391 410 } 392 411 … … 400 419 } 401 420 402 void Resolver::previsit( SingleInit *singleInit ) { 403 visit_children = false; 421 void Resolver::visit( SingleInit *singleInit ) { 404 422 // resolve initialization using the possibilities as determined by the currentObject cursor 405 423 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() ); 406 Expression * newExpr = findSingleExpression( untyped, indexer);424 Expression * newExpr = findSingleExpression( untyped, *this ); 407 425 InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr ); 408 426 … … 443 461 } 444 462 445 void Resolver::previsit( ListInit * listInit ) { 446 visit_children = false; 463 void Resolver::visit( ListInit * listInit ) { 447 464 // move cursor into brace-enclosed initializer-list 448 465 currentObject.enterListInit(); … … 455 472 Initializer * init = std::get<1>(p); 456 473 newDesignations.push_back( currentObject.findNext( des ) ); 457 init->accept( * visitor);474 init->accept( *this ); 458 475 } 459 476 // set the set of 'resolved' designations and leave the brace-enclosed initializer-list … … 484 501 delete ctorInit->get_dtor(); 485 502 ctorInit->set_dtor( NULL ); 486 maybeAccept( ctorInit->get_init(), * visitor);503 maybeAccept( ctorInit->get_init(), *this ); 487 504 } 488 505 … … 490 507 void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ) { 491 508 assert( ctorInit ); 492 PassVisitor<Resolver>resolver( indexer );509 Resolver resolver( indexer ); 493 510 ctorInit->accept( resolver ); 494 511 } … … 496 513 void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ) { 497 514 assert( stmtExpr ); 498 PassVisitor<Resolver>resolver( indexer );515 Resolver resolver( indexer ); 499 516 stmtExpr->accept( resolver ); 500 517 } 501 518 502 void Resolver::previsit( ConstructorInit *ctorInit ) { 503 visit_children = false; 519 void Resolver::visit( ConstructorInit *ctorInit ) { 504 520 // xxx - fallback init has been removed => remove fallbackInit function and remove complexity from FixInit and remove C-init from ConstructorInit 505 maybeAccept( ctorInit->get_ctor(), * visitor);506 maybeAccept( ctorInit->get_dtor(), * visitor);521 maybeAccept( ctorInit->get_ctor(), *this ); 522 maybeAccept( ctorInit->get_dtor(), *this ); 507 523 508 524 // found a constructor - can get rid of C-style initializer -
src/SymTab/Indexer.cc
r5f782f7 r3e3d923 230 230 231 231 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(); 232 577 } 233 578 … … 417 762 418 763 void Indexer::addId( DeclarationWithType *decl ) { 419 debugPrint( "Adding Id " << decl->name << std::endl );420 764 makeWritable(); 421 765 … … 467 811 468 812 void Indexer::addType( NamedTypeDecl *decl ) { 469 debugPrint( "Adding type " << decl->name << std::endl );470 813 makeWritable(); 471 814 … … 495 838 496 839 void Indexer::addStruct( const std::string &id ) { 497 debugPrint( "Adding fwd decl for struct " << id << std::endl );498 840 addStruct( new StructDecl( id ) ); 499 841 } 500 842 501 843 void Indexer::addStruct( StructDecl *decl ) { 502 debugPrint( "Adding struct " << decl->name << std::endl );503 844 makeWritable(); 504 845 … … 519 860 520 861 void Indexer::addEnum( EnumDecl *decl ) { 521 debugPrint( "Adding enum " << decl->name << std::endl );522 862 makeWritable(); 523 863 … … 538 878 539 879 void Indexer::addUnion( const std::string &id ) { 540 debugPrint( "Adding fwd decl for union " << id << std::endl );541 880 addUnion( new UnionDecl( id ) ); 542 881 } 543 882 544 883 void Indexer::addUnion( UnionDecl *decl ) { 545 debugPrint( "Adding union " << decl->name << std::endl );546 884 makeWritable(); 547 885 … … 562 900 563 901 void Indexer::addTrait( TraitDecl *decl ) { 564 debugPrint( "Adding trait " << decl->name << std::endl );565 902 makeWritable(); 566 903 -
src/SymTab/Indexer.h
r5f782f7 r3e3d923 24 24 25 25 namespace SymTab { 26 class Indexer {26 class Indexer : public Visitor { 27 27 public: 28 28 explicit Indexer( bool useDebug = false ); … … 33 33 Indexer& operator= ( const Indexer &that ); 34 34 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 ); 35 86 36 87 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to tell the indexer -
src/main.cc
r5f782f7 r3e3d923 35 35 #include "CodeTools/DeclStats.h" // for printDeclStats 36 36 #include "CodeTools/TrackLoc.h" // for fillLocations 37 #include "Common/PassVisitor.h"38 37 #include "Common/CompilerError.h" // for CompilerError 39 38 #include "Common/SemanticError.h" // for SemanticError … … 251 250 252 251 if ( expraltp ) { 253 PassVisitor<ResolvExpr::AlternativePrinter>printer( cout );252 ResolvExpr::AlternativePrinter printer( cout ); 254 253 acceptAll( translationUnit, printer ); 255 254 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.