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

symbol_name.cc

Go to the documentation of this file.
00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT!         -*- c++ -*-
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         /* anonymous object */
00043         basename = gensym();
00044         kind     = k_Normal;
00045         this->scope = scope;
00046     } else if (!is_qualified_name(tree)) {
00047         /* it's a leaf. Leaf it so. */
00048         init_name(scope, tree, is_fdecl);
00049     } else {
00050         /* qualified name */
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             /* rooted lookup */
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();   // a scope name
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         /* now we have reached the final leaf */
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         /* class or namespace */
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         /* template */
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             /* operator */
00165             assert(p->Length() == 2);
00166             if (const char* pn = get_operator_name(p->Second())) {
00167                 /* it's a normal operator */
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             /* conversion operator */
00178             
00179             /*  This sucks.
00180                 
00181                 parse.cc, rOperatorName:
00182                   X                                normal operator
00183                   Reserved(new), Reserved(delete)  operator new
00184                   [Reserved(new) \[ \]]            array new/delete
00185                   [( )]                            funcall op
00186                   [\[ \]]                          index op
00187                   =>       leaf of type RESERVED
00188                   -or-  list starting with RESERVED leaf or "(" or "["
00189                   -or-  leaf containing operator (i.e. non-alphabetic)
00190                   
00191                   
00192                   typename
00193                   [typename [ptr-operators...]]
00194                   ...where typname = type-specifier-list or name
00195                   i.e.
00196                   [operator [a [*]]
00197                   [operator [:: a]]
00198                   [operator [a [* *]]]
00199                   [operator [[int] [[a :: *]]]]
00200                   [operator a]
00201                   [operator [a :: b]]
00202                   [operator [[a :: b] [*]]]
00203                   [operator [const [bool]]]
00204                   [operator [[bool] const]]
00205                   [operator [const a]]
00206                   
00207                   => single type if
00208                     leaf
00209                   => type + ptr-ops
00210                           list of length 2
00211                     -and- first is not a "::" */
00212             Ptree* opn = p->Second();
00213             if (!opn->IsLeaf() && opn->Length() == 2 && !opn->Car()->Eq("::") && !opn->Second()->IsLeaf()) {
00214                 /* this test doesn't wield out "const bool" etc. Use
00215                    brute force. Bummer, maybe parse_type does assert
00216                    or printBacktrace when something fails. Did I
00217                    already say this sucks? */
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             /* we're here when it's just one type */
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         /* must be template */
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 /***************************** Name Mangling *****************************/
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     // FIXME: g++ derives this name from the input file name, time,
00347     // and whatever. So should we do, too.
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";     // plus
00491         else if (tree->Eq('-'))
00492             return "__opm";     // minus
00493         else if (tree->Eq('*'))
00494             return "__opt";     // times
00495         else if (tree->Eq('/'))
00496             return "__opd";     // divide
00497         else if (tree->Eq('&'))
00498             return "__opa";     // and
00499         else if (tree->Eq('!'))
00500             return "__opn";     // not
00501         else if (tree->Eq('~'))
00502             return "__opc";     // complement
00503         else if (tree->Eq('%'))
00504             return "__opr";     // remainder
00505         else if (tree->Eq(','))
00506             return COMMA_OPERATOR_NAME;   // comma
00507         else if (tree->Eq('^'))
00508             return "__opx";     // xor
00509         else if (tree->Eq('|'))
00510             return "__opo";     // or
00511         else if (tree->Eq('<'))
00512             return "__oplt";    // less than
00513         else if (tree->Eq('>'))
00514             return "__opgt";    // greater than
00515         else if (tree->Eq('='))
00516             return ASSIGNMENT_OPERATOR_NAME;    // assign
00517         else if (tree->Eq("++"))
00518             return "__oppp";    // plusplus
00519         else if (tree->Eq("--"))
00520             return "__opmm";    // minusminus
00521         else if (tree->Eq("<<"))
00522             return "__opll";    // left left / less less
00523         else if (tree->Eq(">>"))
00524             return "__oprr";    // right right
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;    // arrow
00535         else if (tree->Eq("&&"))
00536             return "__opaa";    // andand
00537         else if (tree->Eq("||"))
00538             return "__opoo";    // oror
00539         else if (tree->Eq("*="))
00540             return "__optas";    // times-assign
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; // index
00573         else if (c->Eq('('))
00574             return CALL_OPERATOR_NAME;  // funcall
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 }

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