00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
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);
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);
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
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
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();
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 ;
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){
00633 if(!m2->is_virtual)
00634 m2->is_virtual = m->is_virtual;
00635 }
00636 else if(m->access != PRIVATE){
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
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 }