Inferno  0.2
misc.cpp
Go to the documentation of this file.
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