Inferno
0.2
|
00001 #include "scope.hpp" 00002 #include "helpers/walk.hpp" 00003 #include "misc.hpp" 00004 00005 using namespace CPPTree; 00006 00007 // 00008 // Handy helper to get the node that is the "scope" of the supplied node - ie basically the 00009 // parent in the tree. We have to do searches for this, since the tree does not contain 00010 // back-pointers. 00011 // 00012 // TODO take id as SpecificIdentifier, not Identifier, so do not need to ASSERT check this 00013 TreePtr<Scope> GetScope( TreePtr<Program> program, TreePtr<Identifier> id ) 00014 { 00015 TRACE("Trying program (global)\n" ); 00016 00017 // Look through the members of all scopes (Program, Records, CallableParams, Compounds) 00018 Walk walkr(program); 00019 FOREACH( const TreePtr<Node> n, walkr ) 00020 { 00021 if( TreePtr<Scope> s = dynamic_pointer_cast<Scope>(n) ) 00022 FOREACH( TreePtr<Declaration> d, s->members ) 00023 { 00024 if( id == GetIdentifier( d ) ) 00025 return s; 00026 } 00027 } 00028 00029 // Special additional processing for Compounds - look for statements that are really Instance Declarations 00030 Walk walkc(program); 00031 FOREACH( const TreePtr<Node> n, walkc ) 00032 { 00033 if( TreePtr<Compound> c = dynamic_pointer_cast<Compound>(n) ) 00034 FOREACH( TreePtr<Statement> s, c->statements ) 00035 { 00036 if( TreePtr<Instance> d = dynamic_pointer_cast<Instance>(s) ) 00037 if( id == GetIdentifier( d ) ) 00038 return c; 00039 } 00040 } 00041 00042 if( TreePtr<SpecificIdentifier> sid = dynamic_pointer_cast<SpecificIdentifier>( id ) ) 00043 ASSERT(0)("cannot get scope of ")( *sid ); 00044 else 00045 ASSERT(0)("non-specific type ")(*id)(" - should not be doing GetScope() on these" ); 00046 // every identifier should have a scope - if this fails, we've missed out a kind of scope 00047 // Note: if FlattenNodeer is not automated yet, then it may have missed something 00048 return TreePtr<Scope>(); 00049 }