00001
00002
00003 #include "symbol_name.h"
00004 #include "symbol_name_i.h"
00005
00006
00007 #line 55 "symbol_name.cpp"
00008
00026 Symbol_name::Symbol_name(std::string s, Abstract_scope* scope, Kind k)
00027 : basename(s), scope(scope), qualified(0), conv_type(), kind(k), tpl_args(0), start_scope(scope)
00028 { }
00029
00030 #line 76 "symbol_name.cpp"
00031
00038 Symbol_name::Symbol_name(Ptree* tree, Abstract_scope* const scope, bool is_fdecl)
00039 : scope(0), qualified(false), tpl_args(0), start_scope(scope)
00040 {
00041 if (!tree) {
00042
00043 basename = gensym();
00044 kind = k_Normal;
00045 this->scope = scope;
00046 } else if (!is_qualified_name(tree)) {
00047
00048 init_name(scope, tree, is_fdecl);
00049 } else {
00050
00051 qualified = true;
00052
00053 Ptree* p = tree;
00054 bool look_global = true;
00055 Abstract_scope* current_scope = scope;
00056 #define ADVANCE(p) (p = p->Cdr(), assert(p != 0))
00057 if (p->Car()->Eq("::")) {
00058
00059 look_global = false;
00060 current_scope = current_scope->get_global_scope();
00061 ADVANCE(p);
00062 }
00063
00064 while (p && p->Cdr()) {
00065 Ptree* ele = p->Car();
00066 if (look_global) {
00067 Abstract_scope* s;
00068 while (current_scope && !(s = lookup_symbol_in_scope(ele, current_scope, start_scope)))
00069 current_scope = current_scope->get_parent();
00070 if (!current_scope)
00071 compile_error("no such scope " + std::string(ele->ToString()));
00072 current_scope = s;
00073 } else {
00074 current_scope = lookup_symbol_in_scope(ele, current_scope, start_scope);
00075 if (!current_scope)
00076 compile_error("no such scope " + std::string(ele->ToString()));
00077 }
00078 look_global = false;
00079 ADVANCE(p);
00080 expect_ptree(p->Car(), "::");
00081 ADVANCE(p);
00082 }
00083
00084
00085 init_name(current_scope, p->Car(), is_fdecl);
00086 }
00087 assert(this->scope);
00088 }
00089
00090 #line 134 "symbol_name.cpp"
00091
00092
00093 Symbol_name::~Symbol_name()
00094 { }
00095
00096 #line 138 "symbol_name.cpp"
00097
00101 bool
00102 Symbol_name::is_qualified_name(Ptree* p)
00103 {
00104 return (!p->IsLeaf() && p->Length() >= 2
00105 && (p->First()->Eq("::") || p->Second()->Eq("::")));
00106 }
00107
00108 #line 148 "symbol_name.cpp"
00109
00116 Abstract_scope*
00117 Symbol_name::lookup_symbol_in_scope(Ptree* p, Abstract_scope* scope, Abstract_scope* start_scope)
00118 {
00119 Symbol_pair sp;
00120 if (p->IsLeaf()) {
00121
00122 sp = scope->lookup_here(p->ToString(), false);
00123 Abstract_scope* s;
00124 if (sp.tag && (s = sp.tag->get_scope()))
00125 return s;
00126 if (sp.untag && (s = sp.untag->get_scope()))
00127 return s;
00128 } else {
00129
00130 assert(p->Length() == 2);
00131 sp = scope->lookup_here(p->Car()->ToString(), false);
00132 Template_class_symbol* tcs = dynamic_cast<Template_class_symbol*>(sp.tag);
00133 if (tcs)
00134 return tcs->get_specialisation_from_ptree(p->Second(), start_scope)->get_scope();
00135 }
00136
00137 if (sp.untag && sp.untag->get_kind() != Symbol::k_Function && sp.untag->get_kind() != Symbol::k_Variable)
00138 compile_error("not a scope name: " + std::string(p->ToString()));
00139 return 0;
00140 }
00141
00142 #line 180 "symbol_name.cpp"
00143
00151 void
00152 Symbol_name::init_name(Abstract_scope* s, Ptree* p, bool is_fdecl)
00153 {
00154 if (!p->IsLeaf()) {
00155 if (p->Car()->Eq('~')) {
00156 if (!s->is_constructor(p->Second()))
00157 compile_error("invalid destructor name");
00158 basename = DESTRUCTOR_NAME;
00159 kind = k_Destructor;
00160 scope = s;
00161 return;
00162 }
00163 if (p->Car()->Eq("operator")) {
00164
00165 assert(p->Length() == 2);
00166 if (const char* pn = get_operator_name(p->Second())) {
00167
00168 basename = pn;
00169 if (pn == NEW_OPERATOR_NAME || pn == ANEW_OPERATOR_NAME || pn == DELETE_OPERATOR_NAME || pn == ADELETE_OPERATOR_NAME)
00170 kind = k_Alloc;
00171 else
00172 kind = k_Operator;
00173 scope = s;
00174 return;
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 Ptree* opn = p->Second();
00213 if (!opn->IsLeaf() && opn->Length() == 2 && !opn->Car()->Eq("::") && !opn->Second()->IsLeaf()) {
00214
00215
00216
00217
00218 try {
00219 Type t = parse_type(opn->First(), start_scope, 0, false);
00220 if (!parse_abstract_declarator(opn->Second(), start_scope, &t))
00221 compile_error("invalid abstract-declarator for conversion operator");
00222 conv_type = t;
00223 kind = k_Conversion;
00224 basename = CONVERSION_OPERATOR_NAME;
00225 scope = s;
00226 return;
00227 }
00228 catch(...) { }
00229 }
00230
00231 conv_type = parse_type(opn, start_scope, 0, false);
00232 kind = k_Conversion;
00233 basename = CONVERSION_OPERATOR_NAME;
00234 scope = s;
00235 return;
00236 }
00237
00238
00239 if (p->Length() != 2)
00240 bogus_ptree_error("expected [name [< tplargs >]]", p);
00241 tpl_args = p->Second();
00242 p = p->First();
00243 }
00244
00245 if (!p->IsLeaf())
00246 bogus_ptree_error("expected leaf", p);
00247
00248 if (is_fdecl && s->is_constructor(p)) {
00249 basename = CONSTRUCTOR_NAME;
00250 kind = k_Constructor;
00251 scope = s;
00252 } else {
00253 basename = p->ToString();
00254 kind = k_Normal;
00255 scope = s;
00256 }
00257 }
00258
00259 #line 295 "symbol_name.cpp"
00260
00262 bool
00263 Symbol_name::is_qualified() const
00264 {
00265 return qualified;
00266 }
00267
00268 #line 317 "symbol_name.cpp"
00269
00272 Abstract_scope*
00273 Symbol_name::get_scope() const
00274 {
00275 return scope;
00276 }
00277
00278 #line 325 "symbol_name.cpp"
00279
00281 Type
00282 Symbol_name::get_type() const
00283 {
00284 assert(get_kind() == k_Conversion);
00285 return conv_type;
00286 }
00287
00288 #line 347 "symbol_name.cpp"
00289
00295 Symbol_pair
00296 Symbol_name::lookup_for_use(bool qual) const
00297 {
00298 Symbol_pair sp;
00299 if (qual || is_qualified())
00300 sp = get_scope()->lookup_here(get_name(), false);
00301 else
00302 sp = get_scope()->lookup_unqualified(get_name());
00303
00304 if (is_template()) {
00305 Template_class_symbol* tcs = dynamic_cast<Template_class_symbol*>(sp.tag);
00306 if (!tcs)
00307 compile_error(get_name() + " is not a template");
00308
00309 Type_vector tv;
00310 parse_template_arg_list(tpl_args, start_scope, &tv);
00311 sp.tag = sp.untag = tcs->get_specialisation(tv);
00312 }
00313 return sp;
00314 }
00315
00316 #line 373 "symbol_name.cpp"
00317
00319 Symbol_pair
00320 Symbol_name::lookup_for_decl() const
00321 {
00322 return get_scope()->lookup_here(get_name(), true);
00323 }
00324
00325 #line 380 "symbol_name.cpp"
00326
00327
00328
00330 std::string
00331 Symbol_name::gensym()
00332 {
00333 static int counter = 0;
00334 ++counter;
00335 std::ostringstream s;
00336 s << "__" << counter;
00337 return s.str();
00338 }
00339
00340 #line 393 "symbol_name.cpp"
00341
00343 std::string
00344 Symbol_name::get_unnamed_namespace_name()
00345 {
00346
00347
00348 return "__unnamed";
00349 }
00350
00351 #line 402 "symbol_name.cpp"
00352
00355 std::string
00356 Symbol_name::get_mangled_symbol_name(std::string scope, std::string name)
00357 {
00358 #ifdef OLD_MANGLER
00359 if (scope.length())
00360 return scope + "::" + name;
00361 else
00362 return name;
00363 #else
00364 return name + scope;
00365 #endif
00366 }
00367
00368 #line 417 "symbol_name.cpp"
00369
00372 std::string
00373 Symbol_name::get_mangled_scope_from_symbol(std::string name)
00374 {
00375 #ifdef OLD_MANGLER
00376 return name;
00377 #else
00378 std::ostringstream os;
00379 os << "?Q" << name.length() << name;
00380 return os.str();
00381 #endif
00382 }
00383
00384 #line 431 "symbol_name.cpp"
00385
00388 std::string
00389 Symbol_name::get_mangled_function_name(std::string fname, Type t, Type this_type)
00390 {
00391 #ifdef OLD_MANGLER
00392 return fname + "__" + t.make_pointer_type().get_encoded_type().substr(1);
00393 #else
00394 std::string type = t.get_function_signature();
00395 if (this_type.is_valid()) {
00396 if (this_type.is_qualified(Type::q_Volatile))
00397 type.insert(0, "V");
00398 if (this_type.is_qualified(Type::q_Const))
00399 type.insert(0, "C");
00400 }
00401 std::ostringstream os;
00402 os << fname << "?F" << type.length() << type;
00403 return os.str();
00404 #endif
00405 }
00406
00407 #line 452 "symbol_name.cpp"
00408
00411 std::string
00412 Symbol_name::get_mangled_template_name(std::string name, const Type_vector& types)
00413 {
00414 #ifdef OLD_MANGLER
00415 name += "__";
00416 for (unsigned i = 0; i < types.size(); ++i)
00417 name += types[i].make_pointer_type().get_encoded_type().substr(1);
00418 return name;
00419 #else
00420 std::string type_sig;
00421 for (unsigned i = 0; i < types.size(); ++i)
00422 type_sig += types[i].make_pointer_type().get_encoded_type().substr(1);
00423 std::ostringstream os;
00424 os << name << "?T" << type_sig.length() << type_sig;
00425 return os.str();
00426 #endif
00427 }
00428
00429 #line 472 "symbol_name.cpp"
00430
00433 std::string
00434 Symbol_name::get_mangled_block_scope(std::string fname)
00435 {
00436 return fname + get_block_name();
00437 }
00438
00439 #line 480 "symbol_name.cpp"
00440
00441 std::string
00442 Symbol_name::get_basename_from_symbol(std::string sym, std::string::size_type len)
00443 {
00444 #ifdef OLD_MANGLER
00445 return sym.substr(sym.length()-len, len);
00446 #else
00447 return sym.substr(0, len);
00448 #endif
00449 }
00450
00451 #line 490 "symbol_name.cpp"
00452
00454 std::string
00455 Symbol_name::get_block_name()
00456 {
00457 static int counter = 0;
00458 ++counter;
00459 std::ostringstream s;
00460 #ifdef OLD_MANGLER
00461 s << "." << counter;
00462 #else
00463 s << "?" << counter;
00464 #endif
00465 return s.str();
00466 }
00467 #line 505 "symbol_name.cpp"
00468
00469 const char Symbol_name::CONVERSION_OPERATOR_NAME[] = "__cvt",
00470 Symbol_name::CONSTRUCTOR_NAME[] = "__ctor",
00471 Symbol_name::DESTRUCTOR_NAME[] = "__dtor",
00472 Symbol_name::PTR_OPERATOR_NAME[] = "__opar",
00473 Symbol_name::CALL_OPERATOR_NAME[] = "__opf",
00474 Symbol_name::ASSIGNMENT_OPERATOR_NAME[] = "__opas",
00475 Symbol_name::INDEX_OPERATOR_NAME[] = "__opi",
00476 Symbol_name::NEW_OPERATOR_NAME[] = "__opnew",
00477 Symbol_name::ANEW_OPERATOR_NAME[] = "__opanew",
00478 Symbol_name::DELETE_OPERATOR_NAME[] = "__opdel",
00479 Symbol_name::ADELETE_OPERATOR_NAME[] = "__opadel",
00480 Symbol_name::COMMA_OPERATOR_NAME[] = "__opcom";
00481
00482 #line 518 "symbol_name.cpp"
00483
00485 const char*
00486 Symbol_name::get_operator_name(Ptree* tree)
00487 {
00488 if (tree->IsLeaf()) {
00489 if (tree->Eq('+'))
00490 return "__opp";
00491 else if (tree->Eq('-'))
00492 return "__opm";
00493 else if (tree->Eq('*'))
00494 return "__opt";
00495 else if (tree->Eq('/'))
00496 return "__opd";
00497 else if (tree->Eq('&'))
00498 return "__opa";
00499 else if (tree->Eq('!'))
00500 return "__opn";
00501 else if (tree->Eq('~'))
00502 return "__opc";
00503 else if (tree->Eq('%'))
00504 return "__opr";
00505 else if (tree->Eq(','))
00506 return COMMA_OPERATOR_NAME;
00507 else if (tree->Eq('^'))
00508 return "__opx";
00509 else if (tree->Eq('|'))
00510 return "__opo";
00511 else if (tree->Eq('<'))
00512 return "__oplt";
00513 else if (tree->Eq('>'))
00514 return "__opgt";
00515 else if (tree->Eq('='))
00516 return ASSIGNMENT_OPERATOR_NAME;
00517 else if (tree->Eq("++"))
00518 return "__oppp";
00519 else if (tree->Eq("--"))
00520 return "__opmm";
00521 else if (tree->Eq("<<"))
00522 return "__opll";
00523 else if (tree->Eq(">>"))
00524 return "__oprr";
00525 else if (tree->Eq("<="))
00526 return "__ople";
00527 else if (tree->Eq(">="))
00528 return "__opge";
00529 else if (tree->Eq("=="))
00530 return "__opeq";
00531 else if (tree->Eq("!="))
00532 return "__opne";
00533 else if (tree->Eq("->"))
00534 return PTR_OPERATOR_NAME;
00535 else if (tree->Eq("&&"))
00536 return "__opaa";
00537 else if (tree->Eq("||"))
00538 return "__opoo";
00539 else if (tree->Eq("*="))
00540 return "__optas";
00541 else if (tree->Eq("/="))
00542 return "__opdas";
00543 else if (tree->Eq("%="))
00544 return "__opras";
00545 else if (tree->Eq("+="))
00546 return "__oppas";
00547 else if (tree->Eq("-="))
00548 return "__opmas";
00549 else if (tree->Eq(">>="))
00550 return "__oprras";
00551 else if (tree->Eq("<<="))
00552 return "__opllas";
00553 else if (tree->Eq("&="))
00554 return "__opaas";
00555 else if (tree->Eq("^="))
00556 return "__opxas";
00557 else if (tree->Eq("|="))
00558 return "__opoas";
00559 else if (tree->Eq(".*"))
00560 return "__oppm";
00561 else if (tree->Eq("->*"))
00562 return "__opppm";
00563 else if (tree->Eq("new"))
00564 return NEW_OPERATOR_NAME;
00565 else if (tree->Eq("delete"))
00566 return DELETE_OPERATOR_NAME;
00567 else
00568 return 0;
00569 } else {
00570 Ptree* c = tree->Car();
00571 if (c->Eq('['))
00572 return INDEX_OPERATOR_NAME;
00573 else if (c->Eq('('))
00574 return CALL_OPERATOR_NAME;
00575 else if (c->Eq("new"))
00576 return ANEW_OPERATOR_NAME;
00577 else if (c->Eq("delete"))
00578 return ADELETE_OPERATOR_NAME;
00579 else
00580 return 0;
00581 }
00582 }