00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #include <string.h>
00061 #include <iostream.h>
00062 #include "encoding.h"
00063 #include "token.h"
00064 #include "ptree.h"
00065 #include "env.h"
00066 #include "mop.h"
00067 #include "typeinfo.h"
00068
00069 Ptree* Encoding::bool_t = new LeafBOOLEAN("bool", 4);
00070 Ptree* Encoding::char_t = new LeafCHAR("char", 4);
00071 Ptree* Encoding::int_t = new LeafINT("int", 3);
00072 Ptree* Encoding::short_t = new LeafSHORT("short", 5);
00073 Ptree* Encoding::long_t = new LeafLONG("long", 4);
00074 Ptree* Encoding::float_t = new LeafFLOAT("float", 5);
00075 Ptree* Encoding::double_t = new LeafDOUBLE("double", 6);
00076 Ptree* Encoding::void_t = new LeafVOID("void", 4);
00077
00078 Ptree* Encoding::signed_t = new LeafSIGNED("signed", 6);
00079 Ptree* Encoding::unsigned_t = new LeafUNSIGNED("unsigned", 8);
00080 Ptree* Encoding::const_t = new LeafCONST("const", 5);
00081 Ptree* Encoding::volatile_t = new LeafVOLATILE("volatile", 8);
00082
00083 Ptree* Encoding::operator_name = new LeafReserved("operator", 8);
00084 Ptree* Encoding::new_operator = new LeafReserved("new", 3);
00085 Ptree* Encoding::anew_operator = new LeafReserved("new[]", 5);
00086 Ptree* Encoding::delete_operator = new LeafReserved("delete", 6);
00087 Ptree* Encoding::adelete_operator = new LeafReserved("delete[]", 8);
00088
00089 Ptree* Encoding::star = new Leaf("*", 1);
00090 Ptree* Encoding::ampersand = new Leaf("&", 1);
00091 Ptree* Encoding::comma = new Leaf(",", 1);
00092 Ptree* Encoding::dots = new Leaf("...", 3);
00093 Ptree* Encoding::scope = new Leaf("::", 2);
00094 Ptree* Encoding::tilder = new Leaf("~", 1);
00095 Ptree* Encoding::left_paren = new Leaf("(", 1);
00096 Ptree* Encoding::right_paren = new Leaf(")", 1);
00097 Ptree* Encoding::left_bracket = new Leaf("[", 1);
00098 Ptree* Encoding::right_bracket = new Leaf("]", 1);
00099 Ptree* Encoding::left_angle = new Leaf("<", 1);
00100 Ptree* Encoding::right_angle = new Leaf(">", 1);
00101
00102 const int DigitOffset = 0x80;
00103
00104 void Encoding::Reset(Encoding& e)
00105 {
00106 len = e.len;
00107 if(len > 0)
00108 memmove(name, e.name, len);
00109 }
00110
00111 char* Encoding::Get()
00112 {
00113 if(len == 0)
00114 return nil;
00115 else{
00116 char* s = new (GC) char[len + 1];
00117 memmove(s, name, len);
00118 s[len] = '\0';
00119 return s;
00120 }
00121 }
00122
00123 void Encoding::Print(ostream& s, char* p)
00124 {
00125 unsigned char* ptr = (unsigned char*)p;
00126 for(;*ptr != '\0'; ++ptr)
00127 if(*ptr < 0x80)
00128 s << char(*ptr);
00129 else
00130 s << char(*ptr - 0x80 + '0');
00131 }
00132
00133
00134
00135
00136 char* Encoding::GetBaseName(char* encode, int& len, Environment*& env)
00137 {
00138 if(encode == nil){
00139 len = 0;
00140 return nil;
00141 }
00142
00143 Environment* e = env;
00144 unsigned char* p = (unsigned char*)encode;
00145 if(*p == 'Q'){
00146 int n = p[1] - 0x80;
00147 p += 2;
00148 while(n-- > 1){
00149 int m = *p++;
00150 if(m == 'T')
00151 m = GetBaseNameIfTemplate(p, e);
00152 else if(m < 0x80){
00153 len = 0;
00154 return nil;
00155 }
00156 else{
00157 m -= 0x80;
00158 if(m <= 0){
00159 if(e != nil)
00160 e = e->GetBottom();
00161 }
00162 else
00163 e = ResolveTypedefName(e, (char*)p, m);
00164 }
00165
00166 p += m;
00167 }
00168
00169 env = e;
00170 }
00171
00172 if(*p == 'T'){
00173 int m = p[1] - 0x80;
00174 int n = p[m + 2] - 0x80;
00175 len = m + n + 3;
00176 return (char*)p;
00177 }
00178 else if(*p < 0x80){
00179 len = 0;
00180 return nil;
00181 }
00182 else{
00183 len = *p - 0x80;
00184 return (char*)p + 1;
00185 }
00186 }
00187
00188 Environment* Encoding::ResolveTypedefName(Environment* env,
00189 char* name, int len)
00190 {
00191 TypeInfo tinfo;
00192 Bind* bind;
00193 Class* c = nil;
00194
00195 if(env != nil)
00196 if (env->LookupType(name, len, bind) && bind != nil)
00197 switch(bind->What()){
00198 case Bind::isClassName :
00199 c = bind->ClassMetaobject();
00200 break;
00201 case Bind::isTypedefName :
00202 bind->GetType(tinfo, env);
00203 c = tinfo.ClassMetaobject();
00204
00205 env = nil;
00206 break;
00207 default :
00208 break;
00209 }
00210 else {
00211 env = env->LookupNamespace(name, len);
00212
00213
00214 }
00215
00216 if(c != nil)
00217 return c->GetEnvironment();
00218 else
00219 return env;
00220 }
00221
00222 int Encoding::GetBaseNameIfTemplate(unsigned char* name, Environment*& e)
00223 {
00224 int m = name[0] - 0x80;
00225 if(m <= 0)
00226 return name[1] - 0x80 + 2;
00227
00228 Bind* b;
00229 if(e != nil && e->LookupType((char*)&name[1], m, b))
00230 if(b != nil && b->What() == Bind::isTemplateClass){
00231 Class* c = b->ClassMetaobject();
00232 if(c != nil){
00233 e = c->GetEnvironment();
00234 return m + (name[m + 1] - 0x80) + 2;
00235 }
00236 }
00237
00238
00239 e = nil;
00240 return m + (name[m + 1] - 0x80) + 2;
00241 }
00242
00243 unsigned char* Encoding::GetTemplateArguments(unsigned char* name, int& len)
00244 {
00245 int m = name[0] - 0x80;
00246 if(m <= 0){
00247 len = name[1] - 0x80;
00248 return &name[2];
00249 }
00250 else{
00251 len = name[m + 1] - 0x80;
00252 return &name[m + 2];
00253 }
00254 }
00255
00256 void Encoding::CvQualify(Ptree* cv1, Ptree* cv2)
00257 {
00258 bool c = FALSE, v = FALSE;
00259 if(cv1 != nil && !cv1->IsLeaf())
00260 while(cv1 != nil){
00261 int kind = cv1->Car()->What();
00262 cv1 = cv1->Cdr();
00263 if(kind == CONST)
00264 c = TRUE;
00265 else if(kind == VOLATILE)
00266 v = TRUE;
00267 }
00268
00269 if(cv2 != nil && !cv2->IsLeaf())
00270 while(cv2 != nil){
00271 int kind = cv2->Car()->What();
00272 cv2 = cv2->Cdr();
00273 if(kind == CONST)
00274 c = TRUE;
00275 else if(kind == VOLATILE)
00276 v = TRUE;
00277 }
00278
00279 if(v)
00280 Insert('V');
00281
00282 if(c)
00283 Insert('C');
00284 }
00285
00286 void Encoding::GlobalScope()
00287 {
00288 Append(DigitOffset);
00289 }
00290
00291
00292
00293 void Encoding::SimpleName(Ptree* id)
00294 {
00295 AppendWithLen(id->GetPosition(), id->GetLength());
00296 }
00297
00298
00299
00300
00301 void Encoding::NoName()
00302 {
00303 static int i = 0;
00304 static unsigned char name[] = "`0000";
00305 int n = i++;
00306 name[1] = n / 1000 + '0';
00307 name[2] = (n / 100) % 10 + '0';
00308 name[3] = (n / 10) % 10 + '0';
00309 name[4] = n % 10 + '0';
00310 AppendWithLen((char*)name, 5);
00311 }
00312
00313 void Encoding::Template(Ptree* name, Encoding& args)
00314 {
00315 Append('T');
00316 SimpleName(name);
00317 AppendWithLen(args);
00318 }
00319
00320 void Encoding::Qualified(int n)
00321 {
00322 if(len + 1 >= MaxNameLen)
00323 MopErrorMessage("Encoding::Qualified()",
00324 "too long encoded name");
00325
00326 memmove(name + 2, name, len);
00327 len += 2;
00328 name[0] = 'Q';
00329 name[1] = (unsigned char)(DigitOffset + n);
00330 }
00331
00332 void Encoding::Destructor(Ptree* class_name)
00333 {
00334 int len = class_name->GetLength();
00335 Append((unsigned char)(DigitOffset + len + 1));
00336 Append('~');
00337 Append(class_name->GetPosition(), len);
00338 }
00339
00340 void Encoding::PtrOperator(int t)
00341 {
00342 if(t == '*')
00343 Insert('P');
00344 else
00345 Insert('R');
00346 }
00347
00348 void Encoding::PtrToMember(Encoding& encode, int n)
00349 {
00350 if(n < 2)
00351 Insert((char*)encode.name, encode.len);
00352 else{
00353 Insert((char*)encode.name, encode.len);
00354 Insert((unsigned char)(DigitOffset + n));
00355 Insert('Q');
00356 }
00357
00358 Insert('M');
00359 }
00360
00361 void Encoding::CastOperator(Encoding& type)
00362 {
00363 Append((unsigned char)(DigitOffset + type.len + 1));
00364 Append('@');
00365 Append((char*)type.name, type.len);
00366 }
00367
00368 void Encoding::Insert(unsigned char c)
00369 {
00370 if(len >= MaxNameLen)
00371 MopErrorMessage("Encoding::Insert()",
00372 "too long encoded name");
00373
00374 if(len > 0)
00375 memmove(name + 1, name, len);
00376
00377 ++len;
00378 name[0] = c;
00379 }
00380
00381 void Encoding::Insert(char* str, int n)
00382 {
00383 if(len + n >= MaxNameLen)
00384 MopErrorMessage("Encoding::Insert()",
00385 "too long encoded name");
00386
00387 if(len > 0)
00388 memmove(&name[n], name, len);
00389
00390 memmove(name, str, n);
00391 len += n;
00392 }
00393
00394 void Encoding::Append(unsigned char c)
00395 {
00396 if(len >= MaxNameLen)
00397 MopErrorMessage("Encoding::Append()",
00398 "too long encoded name");
00399
00400 name[len++] = c;
00401 }
00402
00403 void Encoding::Append(char* str, int n)
00404 {
00405 if(len + n >= MaxNameLen)
00406 MopErrorMessage("Encoding::Append(char*,int)",
00407 "too long encoded name");
00408
00409 memmove(&name[len], str, n);
00410 len += n;
00411 }
00412
00413 void Encoding::AppendWithLen(char* str, int n)
00414 {
00415 if(len + n + 1 >= MaxNameLen)
00416 MopErrorMessage("Encoding::AppendWithLen()",
00417 "too long encoded name");
00418
00419 name[len++] = (unsigned char)(DigitOffset + n);
00420 memmove(&name[len], str, n);
00421 len += n;
00422 }
00423
00424 Ptree* Encoding::MakePtree(unsigned char*& encoded, Ptree* decl)
00425 {
00426 Ptree* cv;
00427 Ptree* typespec = nil;
00428 if(decl != nil)
00429 decl = Ptree::List(decl);
00430
00431 for(;;){
00432 cv = nil;
00433 switch(*encoded++){
00434 case 'b' :
00435 typespec = Ptree::Snoc(typespec, bool_t);
00436 goto finish;
00437 case 'c' :
00438 typespec = Ptree::Snoc(typespec, char_t);
00439 goto finish;
00440 case 'i' :
00441 typespec = Ptree::Snoc(typespec, int_t);
00442 goto finish;
00443 case 's' :
00444 typespec = Ptree::Snoc(typespec, short_t);
00445 goto finish;
00446 case 'l' :
00447 typespec = Ptree::Snoc(typespec, long_t);
00448 goto finish;
00449 break;
00450 case 'j' :
00451 typespec = Ptree::Nconc(typespec, Ptree::List(long_t, long_t));
00452 goto finish;
00453 break;
00454 case 'f' :
00455 typespec = Ptree::Snoc(typespec, float_t);
00456 goto finish;
00457 break;
00458 case 'd' :
00459 typespec = Ptree::Snoc(typespec, double_t);
00460 goto finish;
00461 break;
00462 case 'r' :
00463 typespec = Ptree::Nconc(typespec, Ptree::List(long_t, double_t));
00464 goto finish;
00465 case 'v' :
00466 typespec = Ptree::Snoc(typespec, void_t);
00467 goto finish;
00468 case 'e' :
00469 return dots;
00470 case '?' :
00471 goto finish;
00472 case 'Q' :
00473 typespec = Ptree::Snoc(typespec, MakeQname(encoded));
00474 goto finish;
00475 case 'S' :
00476 typespec = Ptree::Snoc(typespec, signed_t);
00477 break;
00478 case 'U' :
00479 typespec = Ptree::Snoc(typespec, unsigned_t);
00480 break;
00481 case 'C' :
00482 if(*encoded == 'V'){
00483 ++encoded;
00484 cv = Ptree::List(const_t, volatile_t);
00485 }
00486 else
00487 cv = Ptree::List(const_t);
00488
00489 goto const_or_volatile;
00490 case 'V' :
00491 cv = Ptree::List(volatile_t);
00492 const_or_volatile :
00493 switch(*encoded) {
00494 case 'M' :
00495 case 'P' :
00496 case 'R' :
00497 decl = Ptree::Nconc(cv, decl);
00498 break;
00499 case 'F' :
00500 ++encoded;
00501 goto cv_function;
00502 default :
00503 typespec = Ptree::Nconc(cv, typespec);
00504 break;
00505 }
00506 break;
00507 case 'M' :
00508 {
00509 Ptree* ptr;
00510 if(*encoded == 'Q')
00511 ptr = MakeQname(++encoded);
00512 else
00513 ptr = MakeLeaf(encoded);
00514
00515 ptr = Ptree::List(ptr, scope, star);
00516 decl = Ptree::Cons(ptr, decl);
00517 }
00518
00519 goto pointer_or_reference;
00520 case 'P' :
00521 decl = Ptree::Cons(star, decl);
00522 goto pointer_or_reference;
00523 case 'R' :
00524 decl = Ptree::Cons(ampersand, decl);
00525 pointer_or_reference :
00526 if(*encoded == 'A' || *encoded == 'F')
00527 decl = Ptree::List(Ptree::List(left_paren, decl,
00528 right_paren));
00529
00530 break;
00531 case 'A' :
00532 decl = Ptree::Nconc(decl, Ptree::List(left_bracket,
00533 right_bracket));
00534 break;
00535 case 'F' :
00536 cv_function :
00537 {
00538 Ptree* args = nil;
00539 while(*encoded != '\0'){
00540 if(*encoded == '_'){
00541 ++encoded;
00542 break;
00543 }
00544 else if(*encoded == 'v'){
00545 encoded += 2;
00546 break;
00547 }
00548
00549 if(args != nil)
00550 args = Ptree::Snoc(args, comma);
00551
00552 args = Ptree::Snoc(args, MakePtree(encoded, nil));
00553 }
00554
00555 decl = Ptree::Nconc(decl, Ptree::List(left_paren, args,
00556 right_paren));
00557 if(cv != nil)
00558 decl = Ptree::Nconc(decl, cv);
00559 }
00560 break;
00561 case '\0' :
00562 goto finish;
00563 case 'T' :
00564 {
00565 Ptree* tlabel = MakeLeaf(encoded);
00566 Ptree* args = nil;
00567 int n = *encoded++ - DigitOffset;
00568 unsigned char* stop = encoded + n;
00569 while(encoded < stop){
00570 if(args != nil)
00571 args = Ptree::Snoc(args, comma);
00572
00573 args = Ptree::Snoc(args, MakePtree(encoded, nil));
00574 }
00575
00576 tlabel = Ptree::List(tlabel,
00577 Ptree::List(left_angle, args, right_angle));
00578 typespec = Ptree::Nconc(typespec, tlabel);
00579 goto finish;
00580 }
00581 case '*' :
00582 goto error;
00583 default :
00584 if(*--encoded >= DigitOffset){
00585 if(typespec == nil)
00586 typespec = MakeLeaf(encoded);
00587 else
00588 typespec = Ptree::Snoc(typespec, MakeLeaf(encoded));
00589
00590 goto finish;
00591 }
00592 error :
00593 MopErrorMessage("TypeInfo::MakePtree()",
00594 "sorry, cannot handle this type");
00595 break;
00596 }
00597 }
00598
00599 finish :
00600 return Ptree::List(typespec, decl);
00601 }
00602
00603 Ptree* Encoding::MakeQname(unsigned char*& encoded)
00604 {
00605 int n = *encoded++ - DigitOffset;
00606 Ptree* qname = nil;
00607 while(n-- > 0){
00608 Ptree* leaf = MakeLeaf(encoded);
00609 if(leaf != nil)
00610 qname = Ptree::Snoc(qname, leaf);
00611
00612 if(n > 0)
00613 qname = Ptree::Snoc(qname, scope);
00614 }
00615
00616 return qname;
00617 }
00618
00619 Ptree* Encoding::MakeLeaf(unsigned char*& encoded)
00620 {
00621 Ptree* leaf;
00622 int len = *encoded++ - DigitOffset;
00623 if(len > 0)
00624 leaf = new Leaf((char*)encoded, len);
00625 else
00626 leaf = nil;
00627
00628 encoded += len;
00629 return leaf;
00630 }
00631
00632 bool Encoding::IsSimpleName(unsigned char* p)
00633 {
00634 return *p >= DigitOffset;
00635 }
00636
00637 Ptree* Encoding::NameToPtree(char* name, int len)
00638 {
00639 if(name == nil)
00640 return nil;
00641
00642 if(name[0] == 'n'){
00643 if(len == 5 && strncmp(name, "new[]", 5) == 0)
00644 return Ptree::List(operator_name, anew_operator);
00645 else if(len == 3 && strncmp(name, "new", 3) == 0)
00646 return Ptree::List(operator_name, new_operator);
00647 }
00648 else if(name[0] == 'd'){
00649 if(len == 8 && strncmp(name, "delete[]", 8) == 0)
00650 return Ptree::List(operator_name, adelete_operator);
00651 else if(len == 6 && strncmp(name, "delete", 6) == 0)
00652 return Ptree::List(operator_name, delete_operator);
00653 }
00654 else if(name[0] == '~')
00655 return Ptree::List(tilder, new Leaf(&name[1], len - 1));
00656 else if(name[0] == '@'){
00657 unsigned char* encoded = (unsigned char*)&name[1];
00658 return Ptree::List(operator_name, MakePtree(encoded, nil));
00659 }
00660
00661 if(is_letter(name[0]))
00662 return new Leaf(name, len);
00663 else
00664 return Ptree::List(operator_name, new Leaf(name, len));
00665 }
00666