Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

member.cc

Go to the documentation of this file.
00001 /*
00002   Copyright (C) 1997-2001 Shigeru Chiba, Tokyo Institute of Technology.
00003 
00004   Permission to use, copy, distribute and modify this software and   
00005   its documentation for any purpose is hereby granted without fee,        
00006   provided that the above copyright notice appear in all copies and that 
00007   both that copyright notice and this permission notice appear in 
00008   supporting documentation.
00009 
00010   Shigeru Chiba makes no representations about the suitability of this 
00011   software for any purpose.  It is provided "as is" without express or
00012   implied warranty.
00013 */
00014 
00015 #include <string.h>
00016 #include "member.h"
00017 #include "mop.h"
00018 #include "token.h"
00019 #include "env.h"
00020 #include "walker.h"
00021 #include "encoding.h"
00022 #include "ptree.h"
00023 
00024 // class Member
00025 
00026 Member::Member()
00027 {
00028     metaobject = nil;
00029     declarator = nil;
00030     nth = -1;
00031     removed = FALSE;
00032     new_name = nil;
00033     new_args = nil;
00034     new_init = nil;
00035     new_body = nil;
00036     arg_name_filled = FALSE;
00037 
00038     implementation = nil;
00039     original_decl = nil;
00040 }
00041 
00042 Member::Member(const Member& m)
00043 {
00044     metaobject = m.metaobject;
00045     declarator = m.declarator;
00046     nth = m.nth;
00047     removed = m.removed;
00048     new_name = m.new_name;
00049     new_args = m.new_args;
00050     new_init = m.new_init;
00051     new_body = m.new_body;
00052     arg_name_filled = m.arg_name_filled;
00053 
00054     implementation = m.implementation;
00055     original_decl = m.original_decl;
00056 }
00057 
00058 Member::Member(Class* c, Ptree* decl)
00059 {
00060     metaobject = c;
00061     declarator = decl;
00062     nth = -1;
00063     removed = FALSE;
00064     new_name = nil;
00065     new_args = nil;
00066     new_init = nil;
00067     new_body = nil;
00068     arg_name_filled = FALSE;
00069 
00070     implementation = nil;
00071     original_decl = nil;
00072 }
00073 
00074 void Member::Set(Class* c, Ptree* decl, int n)
00075 {
00076     metaobject = c;
00077     declarator = decl;
00078     nth = n;
00079     removed = FALSE;
00080     new_name = nil;
00081     new_args = nil;
00082     new_init = nil;
00083     new_body = nil;
00084     arg_name_filled = FALSE;
00085 
00086     implementation = nil;
00087     original_decl = nil;
00088 }
00089 
00090 void Member::Signature(TypeInfo& t) const
00091 {
00092     if(declarator == nil){
00093         MopErrorMessage("Member::Signature()", "not initialized object.");
00094         return;
00095     }
00096 
00097     char* type = declarator->GetEncodedType();
00098     if(type == nil)
00099         t.Unknown();
00100     else
00101         t.Set(type, metaobject->GetEnvironment());
00102 }
00103 
00104 Ptree* Member::Name()
00105 {
00106     int len;
00107     char* name = Name(len);
00108     return Encoding::NameToPtree(name, len);
00109 }
00110 
00111 char* Member::Name(int& len)
00112 {
00113     if(declarator == nil){
00114         MopErrorMessage("Member::Name()", "not initialized object.");
00115         return nil;
00116     }
00117 
00118     char* name = declarator->GetEncodedName();
00119     if(name != nil){
00120         Environment* e = metaobject->GetEnvironment();
00121         name = Encoding::GetBaseName(name, len, e);
00122     }
00123 
00124     return name;
00125 }
00126 
00127 Ptree* Member::Comments()
00128 {
00129     if(declarator == nil){
00130         MopErrorMessage("Member::Comments()", "not initialized object.");
00131         return nil;
00132     }
00133 
00134     if (declarator->IsA(ntDeclarator))
00135         return ((PtreeDeclarator*)declarator)->GetComments();
00136     else
00137         return nil;
00138 }
00139 
00140 int Member::Nth()
00141 {
00142     if(Find())
00143         return nth;
00144     else
00145         return -1;
00146 }
00147 
00148 Class* Member::Supplier()
00149 {
00150     if(Find())
00151         return metaobject->GetMemberList()->Ref(nth)->supplying;
00152     else
00153         return nil;
00154 }
00155 
00156 bool Member::IsConstructor()
00157 {
00158     if(declarator == nil){
00159         MopErrorMessage("Member::IsConstructor()", "not initialized object.");
00160         return FALSE;
00161     }
00162 
00163     char* name = declarator->GetEncodedName();
00164     if(name != nil){
00165         int len;
00166         Environment* e = metaobject->GetEnvironment();
00167         name = Encoding::GetBaseName(name, len, e);
00168         if(name != nil) {
00169             Class* sup = Supplier();
00170             if (sup != nil)
00171                 return sup->Name()->Eq(name, len);
00172         }
00173     }
00174 
00175     return FALSE;
00176 }
00177 
00178 bool Member::IsDestructor()
00179 {
00180     if(declarator == nil){
00181         MopErrorMessage("Member::IsDestructor()", "not initialized object.");
00182         return FALSE;
00183     }
00184 
00185     char* name = declarator->GetEncodedName();
00186     if(name != nil){
00187         int len;
00188         Environment* e = metaobject->GetEnvironment();
00189         name = Encoding::GetBaseName(name, len, e);
00190         if(name != nil)
00191             return bool(*name == '~');
00192     }
00193 
00194     return FALSE;
00195 }
00196 
00197 bool Member::IsFunction()
00198 {
00199     TypeInfo t;
00200     Signature(t);
00201     return t.IsFunction();
00202 }
00203 
00204 bool Member::IsPublic()
00205 {
00206     if(Find())
00207         return bool(metaobject->GetMemberList()->Ref(nth)->access
00208                     == PUBLIC);
00209     else
00210         return FALSE;
00211 }
00212 
00213 bool Member::IsProtected()
00214 {
00215     if(Find())
00216         return bool(metaobject->GetMemberList()->Ref(nth)->access
00217                     == PROTECTED);
00218     else
00219         return FALSE;
00220 }
00221 
00222 bool Member::IsPrivate()
00223 {
00224     if(Find())
00225         return bool(metaobject->GetMemberList()->Ref(nth)->access
00226                     == PRIVATE);
00227     else
00228         return FALSE;
00229 }
00230 
00231 bool Member::IsStatic()
00232 {
00233     if(Find())
00234         return metaobject->GetMemberList()->Ref(nth)->is_static;
00235     else
00236         return FALSE;
00237 }
00238 
00239 bool Member::IsMutable()
00240 {
00241     if(Find())
00242         return metaobject->GetMemberList()->Ref(nth)->is_mutable;
00243     else
00244         return FALSE;
00245 }
00246 
00247 bool Member::IsInline()
00248 {
00249     if(Find() && metaobject->GetMemberList()->Ref(nth)->is_inline)
00250         return TRUE;
00251 
00252     if(IsFunctionImplementation())
00253         return IsInlineFuncImpl();
00254     else
00255         return FALSE;
00256 }
00257 
00258 bool Member::IsInlineFuncImpl()
00259 {
00260     Ptree* header = implementation->Car();
00261     while(header != nil){
00262         Ptree* h = header->Car();
00263         if(h->IsA(INLINE))
00264             return TRUE;
00265 
00266         header = header->Cdr();
00267     }
00268 
00269     return FALSE;
00270 }
00271 
00272 bool Member::IsVirtual()
00273 {
00274     if(Find())
00275         return metaobject->GetMemberList()->Ref(nth)->is_virtual;
00276     else
00277         return FALSE;
00278 }
00279 
00280 bool Member::IsPureVirtual()
00281 {
00282     if(IsFunction())
00283         return declarator->Last()->Car()->Eq('0');
00284     else
00285         return FALSE;
00286 }
00287 
00288 Ptree* Member::GetUserAccessSpecifier()
00289 {
00290     if(Find())
00291         return metaobject->GetMemberList()->Ref(nth)->user_access;
00292     else
00293         return nil;
00294 }
00295 
00296 bool Member::GetUserArgumentModifiers(PtreeArray& mods)
00297 {
00298     Ptree* args;
00299 
00300     mods.Clear();
00301     if(!Find())
00302         return FALSE;
00303 
00304     if(!Walker::GetArgDeclList((PtreeDeclarator*)declarator, args))
00305         return FALSE;
00306 
00307     while(args != nil){
00308         Ptree* a = args->Car();
00309         if(!a->IsLeaf() && a->Car()->IsA(ntUserdefKeyword))
00310             mods.Append(a->Car());
00311         else
00312             mods.Append(nil);
00313         
00314         args = Ptree::ListTail(args, 2);        // skip ,
00315     }
00316 
00317     return TRUE;
00318 }
00319 
00320 Ptree* Member::GetUserMemberModifier()
00321 {
00322     if(Find())
00323         return metaobject->GetMemberList()->Ref(nth)->user_mod;
00324     else
00325         return nil;
00326 }
00327 
00328 bool Member::Find()
00329 {
00330     if(nth >= 0)
00331         return TRUE;
00332     else if(metaobject == nil || declarator == nil)
00333         return FALSE;
00334 
00335     MemberList* mlist = metaobject->GetMemberList();
00336 
00337     int len;
00338     char* name = Name(len);
00339     char* sig = declarator->GetEncodedType();
00340     if(mlist == nil || name == nil || sig == nil)
00341         return FALSE;
00342 
00343     nth = mlist->Lookup(name, len, sig);
00344     if(nth >= 0){
00345         MemberList::Mem* m = mlist->Ref(nth);
00346         metaobject = m->supplying;
00347         declarator = m->declarator;
00348         return TRUE;
00349     }
00350     else
00351         return FALSE;
00352 }
00353 
00354 void Member::SetQualifiedName(Ptree* name)
00355 {
00356     new_name = name;
00357 }
00358 
00359 void Member::SetName(Ptree* name)
00360 {
00361     if(IsFunctionImplementation())
00362         SetName(name, original_decl);
00363     else
00364         SetName(name, declarator);
00365 }
00366 
00367 void Member::SetName(Ptree* name, Ptree* decl)
00368 {
00369     if(decl == nil){
00370         MopErrorMessage("Member::SetName()", "not initialized object.");
00371         return;
00372     }
00373 
00374     char* encoded = decl->GetEncodedName();
00375     if(encoded != nil && *encoded == 'Q'){
00376         Ptree* qname = ((PtreeDeclarator*)decl)->Name();
00377         Ptree* old_name = qname->Last()->First();
00378         new_name = Ptree::ShallowSubst(name, old_name, qname);
00379     }
00380     else
00381         new_name = name;
00382 }
00383 
00384 Ptree* Member::ArgumentList()
00385 {
00386     if(IsFunctionImplementation())
00387         return ArgumentList(original_decl);
00388     else
00389         return ArgumentList(declarator);
00390 }
00391 
00392 Ptree* Member::ArgumentList(Ptree* decl)
00393 {
00394     Ptree* args;
00395     if(Walker::GetArgDeclList((PtreeDeclarator*)decl, args))
00396         return args;
00397     else
00398         return nil;
00399 }
00400 
00401 void Member::SetArgumentList(Ptree* args)
00402 {
00403     new_args = args;
00404 }
00405 
00406 Ptree* Member::MemberInitializers()
00407 {
00408     if(IsFunctionImplementation())
00409         return MemberInitializers(original_decl);
00410     else
00411         return MemberInitializers(declarator);
00412 }
00413 
00414 Ptree* Member::MemberInitializers(Ptree* decl)
00415 {
00416     if(IsConstructor()){
00417         Ptree* init = decl->Last()->Car();
00418         if(!init->IsLeaf() && init->Car()->Eq(':'))
00419             return init;
00420     }
00421 
00422     return nil;
00423 }
00424 
00425 void Member::SetMemberInitializers(Ptree* init)
00426 {
00427     new_init = init;
00428 }
00429 
00430 Ptree* Member::FunctionBody()
00431 {
00432     if(IsFunctionImplementation())
00433         return implementation->Nth(3);
00434     else if(Find()){
00435         Ptree* def = metaobject->GetMemberList()->Ref(nth)->definition;
00436         Ptree* decls = def->Third();
00437         if(decls->IsA(ntDeclarator))
00438             return def->Nth(3);
00439     }
00440 
00441     return nil;
00442 }
00443 
00444 void Member::SetFunctionBody(Ptree* body)
00445 {
00446     new_body = body;
00447 }
00448 
00449 Ptree* Member::Arguments()
00450 {
00451     return Arguments(ArgumentList(), 0);
00452 }
00453 
00454 Ptree* Member::Arguments(Ptree* args, int i)
00455 {
00456     Ptree* rest;
00457 
00458     if(args == nil)
00459         return args;
00460 
00461     if(args->Cdr() == nil)
00462         rest = nil;
00463     else{
00464         rest = Arguments(args->Cddr(), i + 1);  // skip ","
00465         rest = Ptree::Cons(args->Cadr(), rest);
00466     }
00467 
00468     Ptree* a = args->Car();
00469     Ptree* p;
00470     if(a->IsLeaf())
00471         p = a;
00472     else{
00473         if(a->Car()->IsA(ntUserdefKeyword, REGISTER))
00474             p = a->Third();
00475         else
00476             p = a->Second();
00477 
00478         p = ((PtreeDeclarator*)p)->Name();
00479     }
00480 
00481     if(p == nil){
00482         arg_name_filled = TRUE;
00483         p = Ptree::Make(Walker::argument_name, i);
00484     }
00485 
00486     return Ptree::Cons(p, rest);
00487 }
00488 
00489 void Member::Copy(Member* mem, void* ptr)
00490 {
00491     ChangedMemberList::Cmem* cmem = (ChangedMemberList::Cmem*)ptr;
00492     ChangedMemberList::Copy(mem, cmem, Class::Undefined);
00493     if(mem->IsFunctionImplementation()){
00494         cmem->declarator = mem->original_decl;
00495         cmem->def = mem->implementation;
00496     }
00497 }
00498 
00499 
00500 // class MemberFunction
00501 
00502 MemberFunction::MemberFunction(Class* c, Ptree* impl, Ptree* decl)
00503 : Member(c, decl)
00504 {
00505     implementation = impl;
00506     original_decl = decl;
00507 }
00508 
00509 
00510 // class MemberList
00511 
00512 MemberList::MemberList()
00513 {
00514     this_class = nil;
00515     num = 0;
00516     size = -1;
00517     array = nil;
00518 }
00519 
00520 MemberList::Mem* MemberList::Ref(int i)
00521 {
00522     const int unit = 16;
00523     if(i >= size){
00524         int old_size = size;
00525         size = ((unsigned int)i + unit) & ~(unit - 1);
00526         Mem* a = new (GC) Mem[size];
00527         if(old_size > 0)
00528             memmove(a, array, old_size * sizeof(Mem));
00529 
00530         array = a;
00531     }
00532 
00533     return &array[i];
00534 }
00535 
00536 void MemberList::Make(Class* metaobject)
00537 {
00538     this_class = metaobject;
00539     num = 0;
00540 
00541     AppendThisClass(metaobject);
00542 
00543     Environment* env = metaobject->GetEnvironment();
00544     Ptree* bases = metaobject->BaseClasses();
00545     while(bases != nil){
00546         bases = bases->Cdr();           // skip : or ,
00547         if(bases != nil){
00548             AppendBaseClass(env, bases->Car());
00549             bases = bases->Cdr();
00550         }
00551     }
00552 }
00553 
00554 void MemberList::AppendThisClass(Class* metaobject)
00555 {
00556     int access = PRIVATE;
00557     Ptree* user_access = nil;
00558     Ptree* members = metaobject->Members();
00559     while(members != nil){
00560         Ptree* def = members->Car();
00561         if(def->IsA(ntDeclaration)){
00562             Ptree* decl;
00563             int nth = 0;
00564             do{
00565                 int i = nth++;
00566                 decl = Walker::NthDeclarator(def, i);
00567                 if(decl != nil)
00568                     Append(def, decl, access, user_access);
00569             } while(decl != nil);
00570         }
00571         else if(def->IsA(ntAccessSpec)){
00572             access = def->Car()->What();
00573             user_access = nil;
00574         }
00575         else if(def->IsA(ntUserAccessSpec))
00576             user_access = def;
00577         else if(def->IsA(ntAccessDecl))
00578             /* not implemented */;
00579 
00580         members = members->Cdr();
00581     }
00582 }
00583 
00584 void MemberList::Append(Ptree* declaration, Ptree* decl,
00585                         int access, Ptree* user_access)
00586 {
00587     int len;
00588     Mem mem;
00589     char* name = decl->GetEncodedName();
00590     char* signature = decl->GetEncodedType();
00591     Environment* e = this_class->GetEnvironment();
00592     name = Encoding::GetBaseName(name, len, e);
00593 
00594     CheckHeader(declaration, &mem);
00595 
00596     Mem* m = Ref(num++);
00597     m->supplying = this_class;
00598     m->definition = declaration;
00599     m->declarator = decl;
00600     m->name = name;
00601     m->signature = signature;
00602     m->is_constructor = bool(this_class->Name()->Eq(name, len));
00603     m->is_destructor = bool(*name == '~');
00604     m->is_virtual = mem.is_virtual;
00605     m->is_static = mem.is_static;
00606     m->is_mutable = mem.is_mutable;
00607     m->is_inline = mem.is_inline;
00608     m->user_mod = mem.user_mod;
00609     m->access = access;
00610     m->user_access = user_access;
00611 }
00612 
00613 void MemberList::AppendBaseClass(Environment* env, Ptree* base_class)
00614 {
00615     int access = PRIVATE;
00616     while(base_class->Cdr() != nil){
00617         Ptree* p = base_class->Car();
00618         if(p->IsA(PUBLIC, PROTECTED, PRIVATE))
00619             access = p->What();
00620 
00621         base_class = base_class->Cdr();
00622     }   
00623 
00624     Class* metaobject = env->LookupClassMetaobject(base_class->Car());
00625     if(metaobject == nil)
00626         return;
00627 
00628     MemberList* mlist = metaobject->GetMemberList();
00629     for(int i = 0; i < mlist->num; ++i){
00630         Mem* m = &mlist->array[i];
00631         Mem* m2 = Lookup(m->name, m->signature);
00632         if(m2 != nil){                          // overwrittten
00633             if(!m2->is_virtual)
00634                 m2->is_virtual = m->is_virtual;
00635         }
00636         else if(m->access != PRIVATE){          // inherited
00637             m2 = Ref(num++);
00638             *m2 = *m;
00639             if(access == PRIVATE)
00640                 m2->access = PRIVATE;
00641             else if(access == PROTECTED)
00642                 m2->access = PROTECTED;
00643         }
00644     }
00645 }
00646 
00647 MemberList::Mem* MemberList::Lookup(char* name, char* signature)
00648 {
00649     for(int i = 0; i < num; ++i){
00650         Mem* m = Ref(i);
00651         if(strcmp(m->name, name) == 0 && strcmp(m->signature, signature) == 0)
00652             return m;
00653     }
00654 
00655     return nil;
00656 }
00657 
00658 int MemberList::Lookup(char* name, int len, char* signature)
00659 {
00660     for(int i = 0; i < num; ++i){
00661         Mem* m = Ref(i);
00662         if(strcmp(m->signature, signature) == 0
00663            && strncmp(m->name, name, len) == 0 && m->name[len] == '\0')
00664             return i;
00665     }
00666 
00667     return -1;
00668 }
00669 
00670 int MemberList::Lookup(Environment* env, Ptree* member, int index)
00671 {
00672     char* name;
00673     int len;
00674 
00675     if(member == nil)
00676         return -1;
00677     else if(member->IsLeaf()){
00678         name = member->GetPosition();
00679         len = member->GetLength();
00680     }
00681     else
00682         name = Encoding::GetBaseName(member->GetEncodedName(), len, env);
00683 
00684     for(int i = 0; i < num; ++i){
00685         Mem* m = Ref(i);
00686         if(strncmp(m->name, name, len) == 0 && m->name[len] == '\0')
00687             if(index-- <= 0)
00688                 return i;
00689     }
00690 
00691     return -1;
00692 }
00693 
00694 int MemberList::Lookup(Environment*, char* name, int index)
00695 {
00696     if(name == nil)
00697         return -1;
00698 
00699     for(int i = 0; i < num; ++i){
00700         Mem* m = Ref(i);
00701         if(strcmp(m->name, name) == 0)
00702             if(index-- <= 0)
00703                 return i;
00704     }
00705 
00706     return -1;
00707 }
00708 
00709 void MemberList::CheckHeader(Ptree* declaration, Mem* m)
00710 {
00711     m->is_virtual = FALSE;
00712     m->is_static = FALSE;
00713     m->is_mutable = FALSE;
00714     m->is_inline = FALSE;
00715     m->user_mod = nil;
00716 
00717     Ptree* header = declaration->Car();
00718     while(header != nil){
00719         Ptree* h = header->Car();
00720         if(h->IsA(VIRTUAL))
00721             m->is_virtual = TRUE;
00722         else if(h->IsA(STATIC))
00723             m->is_static = TRUE;
00724         else if(h->IsA(MUTABLE))
00725             m->is_mutable = TRUE;
00726         else if(h->IsA(INLINE))
00727             m->is_inline = TRUE;
00728         else if(h->IsA(ntUserdefKeyword))
00729             m->user_mod = h;
00730 
00731         header = header->Cdr();
00732     }
00733 
00734     Ptree* d = declaration->Third();
00735     if(d != nil && d->IsA(ntDeclarator))
00736         m->is_inline = TRUE;
00737 }
00738 
00739 // class ChangedMemberList
00740 
00741 ChangedMemberList::ChangedMemberList()
00742 {
00743     num = 0;
00744     size = -1;
00745     array = nil;
00746 }
00747 
00748 void ChangedMemberList::Append(Member* m, int access)
00749 {
00750     Cmem* mem = Ref(num++);
00751     Copy(m, mem, access);
00752 }
00753 
00754 void ChangedMemberList::Copy(Member* src, Cmem* dest, int access)
00755 {
00756     dest->declarator = src->declarator;
00757     dest->removed = src->removed;
00758     dest->name = src->new_name;
00759     dest->args = src->new_args;
00760     dest->init = src->new_init;
00761     dest->body = src->new_body;
00762     dest->arg_name_filled = src->arg_name_filled;
00763 
00764     if(src->Find()){
00765         MemberList::Mem* m = src->metaobject->GetMemberList()->Ref(src->nth);
00766         dest->def = m->definition;
00767         if(access == Class::Undefined)
00768             dest->access = m->access;
00769         else
00770             dest->access = access;
00771     }
00772     else{
00773         dest->def = nil;
00774         if(access == Class::Undefined)
00775             dest->access = Class::Public;
00776         else
00777             dest->access = access;
00778     }
00779 }
00780 
00781 ChangedMemberList::Cmem* ChangedMemberList::Lookup(Ptree* decl)
00782 {
00783     for(int i = 0; i < num; ++i){
00784         Cmem* m = Ref(i);
00785         if(m->declarator == decl)
00786             return m;
00787     }
00788 
00789     return nil;
00790 }
00791 
00792 ChangedMemberList::Cmem* ChangedMemberList::Get(int i)
00793 {
00794     if(i >= num)
00795         return nil;
00796     else
00797         return Ref(i);
00798 }
00799 
00800 ChangedMemberList::Cmem* ChangedMemberList::Ref(int i)
00801 {
00802     const int unit = 16;
00803     if(i >= size){
00804         int old_size = size;
00805         size = ((unsigned int)i + unit) & ~(unit - 1);
00806         Cmem* a = new (GC) Cmem[size];
00807         if(old_size > 0)
00808             memmove(a, array, old_size * sizeof(Cmem));
00809 
00810         array = a;
00811     }
00812 
00813     return &array[i];
00814 }

Generated on Mon Feb 10 17:32:51 2003 for VFiasco Semantics Compiler by doxygen1.2.15