Inferno
0.2
|
00001 #include "cpptree.hpp" 00002 #include "helpers/walk.hpp" 00003 #include "misc.hpp" 00004 00005 using namespace CPPTree; 00006 00007 TreePtr<Identifier> GetIdentifier( TreePtr<Declaration> d ) 00008 { 00009 if( TreePtr<Instance> i = dynamic_pointer_cast<Instance>( d ) ) 00010 return i->identifier; 00011 else if( TreePtr<UserType> t = dynamic_pointer_cast<UserType>( d ) ) 00012 return t->identifier; 00013 else if( TreePtr<Label> l = dynamic_pointer_cast<Label>( d ) ) 00014 return l->identifier; 00015 else 00016 return TreePtr<Identifier>(); // was a declaration without an identifier, ie a base class 00017 } 00018 00019 TreePtr<Node> GetDeclaration::operator()( TreePtr<Node> context, TreePtr<Node> root ) 00020 { 00021 if( TreePtr<TypeIdentifier> tid = dynamic_pointer_cast<TypeIdentifier>( root ) ) 00022 return Get( context, tid ); 00023 else if( TreePtr<InstanceIdentifier> iid = dynamic_pointer_cast<InstanceIdentifier>( root ) ) 00024 return Get( context, iid ); 00025 else 00026 return TreePtr<Node>(); 00027 } 00028 00029 TreePtr<UserType> GetDeclaration::Get( TreePtr<Node> context, TreePtr<TypeIdentifier> id ) 00030 { 00031 Walk w(context); 00032 FOREACH( TreePtr<Node> n, w ) 00033 { 00034 if( TreePtr<UserType> d = dynamic_pointer_cast<UserType>(n) ) 00035 if( id == GetIdentifier( d ) ) 00036 return d; 00037 } 00038 ASSERTFAIL(); 00039 } 00040 00041 TreePtr<Instance> GetDeclaration::Get( TreePtr<Node> context, TreePtr<InstanceIdentifier> id ) 00042 { 00043 Walk w( context ); 00044 FOREACH( TreePtr<Node> n, w ) 00045 { 00046 if( TreePtr<Instance> d = dynamic_pointer_cast<Instance>(n) ) 00047 if( id == GetIdentifier( d ) ) 00048 return d; 00049 } 00050 00051 ASSERT(0)("did not find instance declaration for identifier ")(*id)("\n"); 00052 ASSERTFAIL(""); 00053 } 00054 00055 GetDeclaration GetDeclaration::instance; // TODO Use this instead of constructing a temp (could contain lookup tables etc in the future) 00056 00057 // Look for a record, skipping over typedefs. Returns NULL if not a record. 00058 TreePtr<Record> GetRecordDeclaration( TreePtr<Node> context, TreePtr<TypeIdentifier> id ) 00059 { 00060 TreePtr<Node> ut = GetDeclaration()( context, id ); 00061 while( TreePtr<Typedef> td = dynamic_pointer_cast<Typedef>(ut) ) 00062 { 00063 TreePtr<TypeIdentifier> ti = dynamic_pointer_cast<TypeIdentifier>(td->type); 00064 if(ti) 00065 ut = GetDeclaration()( context, ti); 00066 else 00067 return TreePtr<Record>(); // not a record 00068 } 00069 TreePtr<Record> r = dynamic_pointer_cast<Record>(ut); 00070 return r; 00071 } 00072 00073 00074 // Hunt through a record and its bases to find the named member 00075 TreePtr<Instance> FindMemberByName( TreePtr<Program> program, TreePtr<Record> r, string name ) 00076 { 00077 TRACE("Record has %d members\n", r->members.size() ); 00078 00079 // Try the instance members (objects and functions) for a name match 00080 FOREACH( TreePtr<Declaration> d, r->members ) 00081 if( TreePtr<Instance> i = dynamic_pointer_cast<Instance>(d) ) 00082 if( TreePtr<SpecificInstanceIdentifier> sss = dynamic_pointer_cast<SpecificInstanceIdentifier>(i->identifier) ) 00083 if( sss->GetName() == name ) 00084 return i; 00085 00086 // Try recursing through the base classes, if there are any 00087 if( TreePtr<InheritanceRecord> ir = dynamic_pointer_cast<InheritanceRecord>( r ) ) 00088 FOREACH( TreePtr<Base> b, ir->bases ) 00089 { 00090 TreePtr<Node> ut = GetDeclaration()( program, b->record ); 00091 TreePtr<InheritanceRecord> ir = dynamic_pointer_cast<InheritanceRecord>(ut); 00092 ASSERT(ir); 00093 if( TreePtr<Instance> i = FindMemberByName( program, ir, name ) ) 00094 return i; 00095 } 00096 00097 // We failed. Hang our head in shame. 00098 return TreePtr<Instance>(); 00099 } 00100 00101 00102 TreePtr<Identifier> GetIdentifierOfDeclaration( TreePtr<Declaration> d ) 00103 { 00104 if( TreePtr<Instance> di = dynamic_pointer_cast<Instance>(d) ) 00105 return di->identifier; 00106 else if( TreePtr<UserType> dut = dynamic_pointer_cast<UserType>(d) ) 00107 return dut->identifier; 00108 else if( TreePtr<Label> dl = dynamic_pointer_cast<Label>(d) ) 00109 return dl->identifier; 00110 else 00111 return TreePtr<Identifier>(); // no identifier, maybe because d is a Base node 00112 } 00113