00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "nspcinfo.h"
00018 #include <lib/lex/strtreedump.h>
00019 #include <lib/lex/fastval2str.h>
00020
00021
00022 namespace VM
00023 {
00024
00025 const char *NamespaceInfo::NSType2String(NSType t)
00026 {
00027 switch(t)
00028 {
00029 case NSNamespace: return("namespace");
00030 case NSClass: return("class");
00031 }
00032 return("???");
00033 }
00034
00035
00036 const char *NamespaceInfo::SymbolEntryE::ExtID2String(ExtID e)
00037 {
00038 switch(e)
00039 {
00040 case ExtUnknown: return("[unknown]");
00041 case ExtFunction: return("function");
00042 case ExtVariable: return("variable");
00043 }
00044 return("???");
00045 }
00046
00047
00048 TLString NamespaceInfo::SymbolEntryB::CompleteName() const
00049 {
00050 TLString tmp;
00051
00052 const SymbolEntryE *see=ep();
00053 if(see)
00054 {
00055 Assert(symref>=0);
00056
00057 if(see->nspc)
00058 {
00059 tmp=see->nspc->CompleteName();
00060 if(see->nspc->parent)
00061 { tmp+="::"; }
00062 }
00063 else
00064 { tmp="???::"; }
00065
00066 tmp+=see->name;
00067 }
00068 else
00069 {
00070 Assert(symref<0);
00071
00072 char ntmp[sizeof(SymRef)*2+1+1],*e=ntmp;
00073 *e++='@';
00074 e=FastInt2String(e,-symref,0);
00075 *e='\0';
00076 tmp+=ntmp;
00077 }
00078
00079 return(tmp);
00080 }
00081
00082
00083 bool NamespaceInfo::SymbolEntryB::CompareTo(const SymbolEntryB &e) const
00084 {
00085 const SymbolEntryE *seA=ep(),*seB=e.ep();
00086 if(seA && seB)
00087 {
00088 if(seA->extid!=seB->extid) return(0);
00089
00090
00091 switch(seA->extid)
00092 {
00093 case SymbolEntryE::ExtUnknown:
00094 break;
00095 case SymbolEntryE::ExtFunction:
00096 if(seA->ftype!=seB->ftype) return(0);
00097 break;
00098 case SymbolEntryE::ExtVariable:
00099 if(seA->vtype!=seB->vtype) return(0);
00100 break;
00101 default: Assert(0);
00102 }
00103
00104
00105 Assert(seA->name);
00106 Assert(seB->name);
00107 return(seA->name==seB->name);
00108 }
00109
00110 if(!seA && !seB)
00111 {
00112
00113 return(symref==e.symref);
00114 }
00115
00116
00117 return(0);
00118 }
00119
00120
00121 NamespaceInfo::SymbolEntryE &NamespaceInfo::SymbolEntryE::operator=(
00122 const SymbolEntryE &se)
00123 {
00124 symref=se.symref;
00125
00126 extid=se.extid;
00127 ftype=se.ftype;
00128 vtype=se.vtype;
00129 name=se.name;
00130 nspc=se.nspc;
00131 linked=se.linked;
00132
00133 return(*this);
00134 }
00135
00136
00137 NamespaceInfo::SymbolEntryE::SymbolEntryE(const SymbolEntryE &se) :
00138 SymbolEntryB(se),
00139 extid(se.extid),
00140 ftype(se.ftype),
00141 vtype(se.vtype),
00142 name(se.name),
00143 nspc(se.nspc),
00144 linked(se.linked)
00145 {
00146
00147 }
00148
00149 NamespaceInfo::SymbolEntryE::SymbolEntryE(NamespaceInfo *_nspc) :
00150 SymbolEntryB(),
00151 extid(ExtUnknown),
00152 ftype(),
00153 vtype(),
00154 name(),
00155 nspc(_nspc),
00156 linked(NULL)
00157 {
00158
00159 }
00160
00161
00162
00163 void NamespaceInfo::SortNamespaceTree()
00164 {
00165
00166 if(down.IsEmpty()) return;
00167
00168 if(down.first()==down.last())
00169 {
00170
00171 down.first()->SortNamespaceTree();
00172 return;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 down.MergeSort(_Operators());
00184
00185
00186 for(NamespaceInfo *i=down.first(); i; i=i->next)
00187 { i->SortNamespaceTree(); }
00188 }
00189
00190
00191 TLString NamespaceInfo::CompleteName() const
00192 {
00193 if(!parent)
00194 { return TLString("::"); }
00195
00196 TLString res(name);
00197 for(const NamespaceInfo *i=parent; i; i=i->parent)
00198 {
00199 if(!i->name) continue;
00200 res.prepend(i->name+"::");
00201 }
00202
00203 return(res);
00204 }
00205
00206
00207 void NamespaceInfo::DumpTree(StringTreeDump &dump,bool IDs_resolved,
00208 bool recurse) const
00209 {
00210 TLString tmp;
00211 tmp.sprintf(
00212 "%s %s\n"
00213 " link_info_set=%s, linked=%s, children: %d\n"
00214 ,parent ? NSType2String(nstype) : "NAMESPACE",
00215 parent ? name.str() : "ROOT",
00216 link_info_set ? "yes" : "no",linked ? "yes" : "no",(int)down.count());
00217 dump+=tmp;
00218 uint32 scnt=0;
00219 for(SymbolList::Iterator i(symbol); i; i++,scnt++)
00220 {
00221 const SymbolEntryE *se=*i;
00222 tmp.sprintf(
00223 " symbol[%u]={ extid=%s, ftype=%s, vtype=%s, name=%s, "
00224 "symref=%d }\n",
00225 (uint)scnt,
00226 SymbolEntryE::ExtID2String(se->extid),
00227 se->ftype.TypeString().str(),
00228 se->vtype.TypeString().str(),
00229 se->name.str(),
00230 (int)se->symref);
00231 dump+=tmp;
00232
00233 Assert(se->symref>=0 && se->nspc==this);
00234 }
00235 tmp.deref();
00236
00237
00238 if(recurse && !down.IsEmpty())
00239 {
00240 dump.AddIndent();
00241 for(NamespaceInfo *i=down.first(); i; i=i->next)
00242 { i->DumpTree(dump,IDs_resolved,recurse); }
00243 dump.SubIndent();
00244 }
00245 }
00246
00247
00248 void NamespaceInfo::_AddChild(NamespaceInfo *child)
00249 {
00250 Assert(!(child->next || down.last()==child));
00251
00252
00253 down.append(child);
00254
00255
00256
00257 Assert(child->name);
00258
00259
00260 int _unused_ rv=map_name2child.store(child,0);
00261 Assert(rv==0);
00262 }
00263
00264 void NamespaceInfo::_DelChild(NamespaceInfo *child)
00265 {
00266
00267 if(child->next || down.last()==child)
00268 { down.dequeue(child); }
00269
00270
00271 Assert(child->name);
00272
00273 int _unused_ rv=map_name2child.remove(child);
00274 Assert(rv==0);
00275 }
00276
00277
00278 void NamespaceInfo::AddChild(NamespaceInfo *child)
00279 {
00280 if(!child) return;
00281
00282 Assert(!child->parent);
00283 child->parent=this;
00284
00285 _AddChild(child);
00286 }
00287
00288
00289 NamespaceInfo::NamespaceInfo(const TLString &_name,NamespaceInfo *_parent,
00290 NSType _nstype) :
00291 LinkedListBase<NamespaceInfo>(),
00292 parent(_parent),
00293 down(),
00294 name(_name),
00295 nstype(_nstype),
00296 asm_loc(),
00297 linked(NULL),
00298 symbol(16,1),
00299 map_name2child(_nstype==NSNamespace ? 16 : 6)
00300 {
00301 link_info_set=0;
00302 recursion_flag=0;
00303
00304
00305 if(parent)
00306 { parent->_AddChild(this); }
00307 }
00308
00309 NamespaceInfo::~NamespaceInfo()
00310 {
00311
00312 while(!down.IsEmpty())
00313 { delete down.PopFirst(); }
00314
00315 linked=NULL;
00316
00317
00318
00319 if(parent)
00320 { parent->_DelChild(this); }
00321 }
00322
00323 }