Synopsis - Cross-Reference
File: /Synopsis/Parsers/Cxx/Translator.cc1// 2// Copyright (C) 2000 Stefan Seefeld 3// Copyright (C) 2000 Stephen Davies 4// All rights reserved. 5// Licensed to the public under the terms of the GNU LGPL (>= 2), 6// see the file COPYING for details. 7// 8 9#include <Python.h> 10#include <Synopsis/Trace.hh> 11#include "Translator.hh" 12#include "Filter.hh" 13#include "exception.hh" 14#include <map> 15#include <set> 16#include <iostream> 17 18using namespace Synopsis; 19 20// The compiler firewalled private stuff 21struct Translator::Private 22{ 23 //. Constructor 24 Private(Translator* s) : m_syn(s) 25 { 26 PyObject *qname_module = PyImport_ImportModule("Synopsis.QualifiedName"); 27 if (!qname_module) throw py_error_already_set(); 28 m_qname_factory = PyObject_GetAttrString(qname_module, "QualifiedCxxName"); 29 if (!m_qname_factory) throw py_error_already_set(); 30 Py_DECREF(qname_module); 31 m_cxx = PyString_InternFromString("C++"); 32 Py_INCREF(Py_None); 33 add((ASG::Declaration*)0, Py_None); 34 Py_INCREF(Py_None); 35 add((Types::Type*)0, Py_None); 36 } 37 ~Private() 38 { 39 Py_DECREF(m_qname_factory); 40 } 41 42 //. Reference to parent synopsis object 43 Translator* m_syn; 44 PyObject* m_qname_factory; 45 //. Interned string for "C++" 46 PyObject* m_cxx; 47 //. Returns the string for "C++" as a borrowed reference 48 PyObject* cxx() 49 { 50 return m_cxx; 51 } 52 // Sugar 53 typedef std::map<void*, PyObject*> ObjMap; 54 // Maps from C++ objects to PyObjects 55 ObjMap obj_map; 56 // A set of builtin declarations to not to store in global namespace 57 std::set<ASG::Declaration*> builtin_decl_set; 58 59 // Note that these methods always succeed 60 61 //. Return the PyObject for the given ASG::SourceFile 62 PyObject* py(ASG::SourceFile*); 63 //. Return the PyObject for the given ASG::Include 64 PyObject* py(ASG::Include*); 65 //. Return the PyObject for the given ASG::Declaration 66 PyObject* py(ASG::Declaration*); 67 //. Return the PyObject for the given ASG::Inheritance 68 PyObject* py(ASG::Inheritance*); 69 //. Return the PyObject for the given ASG::Parameter 70 PyObject* py(ASG::Parameter*); 71 //. Return the PyObject for the given Types::Type 72 PyObject* py(Types::Type*); 73 //. Return the PyObject for the given string 74 PyObject* py(const std::string &); 75 76 //. Add the given pair 77 void add(void* cobj, PyObject* pyobj) 78 { 79 if (!pyobj) throw py_error_already_set(); 80 obj_map.insert(ObjMap::value_type(cobj, pyobj)); 81 } 82 83 // Convert a vector to a List 84 template <class T> 85 PyObject* List(const std::vector<T*>& vec) 86 { 87 PyObject* list = PyList_New(vec.size()); 88 int index = 0; 89 typename std::vector<T*>::const_iterator iter = vec.begin(); 90 while (iter != vec.end()) 91 PyList_SET_ITEM(list, index++, py(*iter++)); 92 return list; 93 } 94 95 // Convert a vector to a Tuple 96 template <class T> 97 PyObject* Tuple(const std::vector<T*>& vec) 98 { 99 PyObject* tuple = PyTuple_New(vec.size()); 100 int index = 0; 101 typename std::vector<T*>::const_iterator iter = vec.begin(); 102 while (iter != vec.end()) 103 PyTuple_SET_ITEM(tuple, index++, py(*iter++)); 104 return tuple; 105 } 106 107 PyObject* QName(const ScopedName& name) 108 { 109 PyObject* tuple = PyTuple_New(name.size()); 110 int index = 0; 111 ScopedName::const_iterator iter = name.begin(); 112 while (iter != name.end()) 113 PyTuple_SET_ITEM(tuple, index++, py(*iter++)); 114 PyObject *qname = PyObject_CallFunctionObjArgs(m_qname_factory, tuple, NULL); 115 Py_DECREF(tuple); 116 return qname; 117 } 118 119 // Convert a string vector to a List 120 PyObject* List(const std::vector<std::string> &vec) 121 { 122 PyObject* list = PyList_New(vec.size()); 123 int index = 0; 124 std::vector<std::string>::const_iterator iter = vec.begin(); 125 while (iter != vec.end()) 126 PyList_SET_ITEM(list, index++, py(*iter++)); 127 return list; 128 } 129 130 // Convert a string vector to a Tuple 131 PyObject* Tuple(const std::vector<std::string> &vec) 132 { 133 PyObject* tuple = PyTuple_New(vec.size()); 134 int index = 0; 135 std::vector<std::string>::const_iterator iter = vec.begin(); 136 while (iter != vec.end()) 137 PyTuple_SET_ITEM(tuple, index++, py(*iter++)); 138 return tuple; 139 } 140}; 141 142// Convert a Declaration vector to a List. Declarations can return 0 143// from py(), if they are not in the main file. 144template <> 145PyObject* Translator::Private::List(const std::vector<ASG::Declaration*>& vec) 146{ 147 std::vector<PyObject*> objects; 148 std::vector<ASG::Declaration*>::const_iterator iter = vec.begin(); 149 while (iter != vec.end()) 150 { 151 PyObject* obj = py(*iter++); 152 if (obj != 0) objects.push_back(obj); 153 } 154 155 PyObject* list = PyList_New(objects.size()); 156 int index = 0; 157 std::vector<PyObject*>::const_iterator piter = objects.begin(); 158 while (piter != objects.end()) 159 PyList_SET_ITEM(list, index++, *piter++); 160 return list; 161} 162 163PyObject* Translator::Private::py(ASG::SourceFile* file) 164{ 165 ObjMap::iterator iter = obj_map.find(file); 166 if (iter == obj_map.end()) 167 { 168 // Need to convert object first 169 add(file, m_syn->SourceFile(file)); 170 iter = obj_map.find(file); 171 if (iter == obj_map.end()) 172 { 173 std::cout << "Fatal: Still not PyObject after converting." << std::endl; 174 throw "Translator::Private::py(ASG::SourceFile*)"; 175 } 176 } 177 PyObject* obj = iter->second; 178 Py_INCREF(obj); 179 return obj; 180} 181 182PyObject* Translator::Private::py(ASG::Include* incl) 183{ 184 ObjMap::iterator iter = obj_map.find(incl); 185 if (iter == obj_map.end()) 186 { 187 // Need to convert object first 188 add(incl, m_syn->Include(incl)); 189 iter = obj_map.find(incl); 190 if (iter == obj_map.end()) 191 { 192 std::cout << "Fatal: Still not PyObject after converting." << std::endl; 193 throw "Translator::Private::py(ASG::Include*)"; 194 } 195 } 196 PyObject* obj = iter->second; 197 Py_INCREF(obj); 198 return obj; 199} 200 201PyObject* Translator::Private::py(ASG::Declaration* decl) 202{ 203 ObjMap::iterator iter = obj_map.find(decl); 204 if (iter == obj_map.end()) 205 { 206 // Need to convert object first 207 decl->accept(m_syn); 208 iter = obj_map.find(decl); 209 if (iter == obj_map.end()) 210 { 211 // Probably means it's not in the main file 212 return 0; 213 /* 214 std::cout << "Fatal: Still not PyObject after converting." << std::endl; 215 throw "Translator::Private::py(ASG::Declaration*)"; 216 */ 217 } 218 // Force addition of type to dictionary 219 PyObject* declared = py(decl->declared()); 220 Py_DECREF(declared); 221 } 222 PyObject* obj = iter->second; 223 Py_INCREF(obj); 224 return obj; 225} 226 227PyObject* Translator::Private::py(ASG::Inheritance* decl) 228{ 229 ObjMap::iterator iter = obj_map.find(decl); 230 if (iter == obj_map.end()) 231 { 232 // Need to convert object first 233 decl->accept(m_syn); 234 iter = obj_map.find(decl); 235 if (iter == obj_map.end()) 236 { 237 std::cout << "Fatal: Still not PyObject after converting." << std::endl; 238 throw "Translator::Private::py(ASG::Inheritance*)"; 239 } 240 } 241 PyObject* obj = iter->second; 242 Py_INCREF(obj); 243 return obj; 244} 245PyObject* Translator::Private::py(ASG::Parameter* decl) 246{ 247 ObjMap::iterator iter = obj_map.find(decl); 248 if (iter == obj_map.end()) 249 { 250 // Need to convert object first 251 decl->accept(m_syn); 252 iter = obj_map.find(decl); 253 if (iter == obj_map.end()) 254 { 255 std::cout << "Fatal: Still not PyObject after converting." << std::endl; 256 throw "Translator::Private::py(ASG::Parameter*)"; 257 } 258 } 259 PyObject* obj = iter->second; 260 Py_INCREF(obj); 261 return obj; 262} 263 264PyObject* Translator::Private::py(Types::Type* type) 265{ 266 ObjMap::iterator iter = obj_map.find(type); 267 if (iter == obj_map.end()) 268 { 269 // Need to convert object first 270 type->accept(m_syn); 271 iter = obj_map.find(type); 272 if (iter == obj_map.end()) 273 { 274 std::cout << "Fatal: Still not PyObject after converting." << std::endl; 275 throw "Translator::Private::py(Types::Type*)"; 276 } 277 } 278 PyObject* obj = iter->second; 279 Py_INCREF(obj); 280 return obj; 281} 282 283PyObject* Translator::Private::py(const std::string &str) 284{ 285 PyObject* pystr = PyString_FromStringAndSize(str.data(), str.size()); 286 //PyString_InternInPlace(&pystr); 287 return pystr; 288} 289 290Translator::Translator(FileFilter* filter, PyObject *ir) 291 : m_ir(ir), m_filter(filter) 292{ 293 Trace trace("Translator::Translator", Trace::TRANSLATION); 294 m_asg_module = PyImport_ImportModule("Synopsis.ASG"); 295 if (!m_asg_module) throw py_error_already_set(); 296 m_sf_module = PyImport_ImportModule("Synopsis.SourceFile"); 297 if (!m_sf_module) throw py_error_already_set(); 298 PyObject *asg = PyObject_GetAttrString(m_ir, "asg"); 299 m_declarations = PyObject_GetAttrString(asg, "declarations"); 300 if (!m_declarations) throw py_error_already_set(); 301 m_dictionary = PyObject_GetAttrString(asg, "types"); 302 if (!m_dictionary) throw py_error_already_set(); 303 Py_DECREF(asg); 304 305 m = new Private(this); 306} 307 308Translator::~Translator() 309{ 310 Trace trace("Translator::~Translator", Trace::TRANSLATION); 311 /* 312 PyObject *file = PyObject_CallMethod(scopes.back(), "declarations", 0); 313 size_t size = PyList_Size(file); 314 for (size_t i = 0; i != size; i++) 315 PyObject_CallMethod(declarations, "append", "O", PyList_GetItem(file, i)); 316 */ 317 318 Py_DECREF(m_declarations); 319 Py_DECREF(m_dictionary); 320 321 Py_DECREF(m_asg_module); 322 Py_DECREF(m_sf_module); 323 324 // Deref the objects we created 325 Private::ObjMap::iterator iter = m->obj_map.begin(); 326 Private::ObjMap::iterator end = m->obj_map.end(); 327 while (iter != end) 328 { 329 PyObject* obj = iter->second; 330 PyObject* repr = PyObject_Repr(obj); 331 //std::cout << (obj->ob_refcnt-1) << " " << PyString_AsString(repr) << std::endl; 332 Py_DECREF(repr); 333 Py_DECREF(obj); 334 iter->second = 0; 335 ++iter; 336 } 337 //std::cout << "Total: " << m->obj_map.size()<<" objects." << std::endl; 338 delete m; 339} 340 341void Translator::translate(ASG::Scope* scope)//, PyObject* asg) 342{ 343 ASG::Declaration::vector globals, &decls = scope->declarations(); 344 ASG::Declaration::vector::iterator it = decls.begin(); 345 346 // List all declarations not in the builtin_decl_set 347 for (; it != decls.end(); ++it) 348 if (m->builtin_decl_set.find(*it) == m->builtin_decl_set.end()) 349 globals.push_back(*it); 350 351 // Translate those declarations 352 PyObject* list; 353 PyObject_CallMethod(m_declarations, "extend", "O", 354 list = m->List(globals)); 355 Py_DECREF(list); 356 357 // Translate the sourcefiles, making sure the declarations list is done 358 // for each 359 PyObject* pyfiles = PyObject_GetAttrString(m_ir, "files"); 360 if (!pyfiles) throw py_error_already_set(); 361 assert(PyDict_Check(pyfiles)); 362 363 ASG::SourceFile::vector files; 364 m_filter->get_all_sourcefiles(files); 365 for (ASG::SourceFile::vector::iterator i = files.begin(); i != files.end(); ++i) 366 { 367 ASG::SourceFile* file = *i; 368 369 PyObject* decls, *new_decls, *incls, *new_incls; 370 PyObject* pyfile = m->py(file); 371 372 // Add the declarations if it's a main file 373 if (file->is_primary()) 374 { 375 decls = PyObject_GetAttrString(pyfile, "declarations"); 376 if (!decls) throw py_error_already_set(); 377 PyObject_CallMethod(decls, "extend", "O", new_decls = m->List(file->declarations())); 378 // TODO: add the includes 379 Py_DECREF(new_decls); 380 Py_DECREF(decls); 381 } 382 383 // Add the includes 384 incls = PyObject_GetAttrString(pyfile, "includes"); 385 if (!incls) throw py_error_already_set(); 386 PyObject_CallMethod(incls, "extend", "O", new_incls = m->List(file->includes())); 387 Py_DECREF(new_incls); 388 Py_DECREF(incls); 389 390 // Add to the ASG 391 PyObject* pyfilename = PyObject_GetAttrString(pyfile, "name"); 392 PyDict_SetItem(pyfiles, pyfilename, pyfile); 393 Py_DECREF(pyfilename); 394 Py_DECREF(pyfile); 395 } 396 397 Py_DECREF(pyfiles); 398} 399 400void Translator::set_builtin_decls(const ASG::Declaration::vector& builtin_decls) 401{ 402 // Insert Base*'s into a set for fasger lookup 403 ASG::Declaration::vector::const_iterator it = builtin_decls.begin(); 404 while (it != builtin_decls.end()) m->builtin_decl_set.insert(*it++); 405} 406 407PyObject *Translator::Base(Types::Base* type) 408{ 409 Trace trace("Translator::Base", Trace::TRANSLATION); 410 PyObject *name, *base; 411 base = PyObject_CallMethod(m_asg_module, "BuiltinTypeId", "OO", 412 m->cxx(), name = m->QName(type->name())); 413 PyObject_SetItem(m_dictionary, name, base); 414 Py_DECREF(name); 415 return base; 416} 417 418PyObject *Translator::Dependent(Types::Dependent* type) 419{ 420 Trace trace("Translator::Dependent", Trace::TRANSLATION); 421 PyObject *name, *base; 422 base = PyObject_CallMethod(m_asg_module, "DependentTypeId", "OO", 423 m->cxx(), name = m->QName(type->name())); 424 PyObject_SetItem(m_dictionary, name, base); 425 Py_DECREF(name); 426 return base; 427} 428 429PyObject *Translator::Unknown(Types::Named* type) 430{ 431 Trace trace("Translator::Unknown", Trace::TRANSLATION); 432 PyObject *name, *unknown; 433 unknown = PyObject_CallMethod(m_asg_module, "UnknownTypeId", "OO", 434 m->cxx(), name = m->QName(type->name())); 435 PyObject_SetItem(m_dictionary, name, unknown); 436 Py_DECREF(name); 437 return unknown; 438} 439 440PyObject *Translator::Declared(Types::Declared* type) 441{ 442 Trace trace("Translator::Declared", Trace::TRANSLATION); 443 PyObject *name, *declared, *decl; 444 declared = PyObject_CallMethod(m_asg_module, "DeclaredTypeId", "OOO", 445 m->cxx(), name = m->QName(type->name()), 446 decl = m->py(type->declaration())); 447 // Skip zero-length names (eg: dummy declarators/enumerators) 448 if (type->name().size()) 449 PyObject_SetItem(m_dictionary, name, declared); 450 Py_DECREF(name); 451 Py_DECREF(decl); 452 return declared; 453} 454 455PyObject *Translator::Template(Types::Template* type) 456{ 457 Trace trace("Translator::Template", Trace::TRANSLATION); 458 PyObject *name, *templ, *decl, *params; 459 templ = PyObject_CallMethod(m_asg_module, "TemplateId", "OOOO", 460 m->cxx(), name = m->QName(type->name()), 461 decl = m->py(type->declaration()), 462 params = m->List(type->parameters())); 463 PyObject_SetItem(m_dictionary, name, templ); 464 Py_DECREF(name); 465 Py_DECREF(decl); 466 Py_DECREF(params); 467 return templ; 468} 469 470PyObject *Translator::Modifier(Types::Modifier* type) 471{ 472 Trace trace("Translator::Modifier", Trace::TRANSLATION); 473 PyObject *modifier, *alias, *pre, *post; 474 modifier = PyObject_CallMethod(m_asg_module, "ModifierTypeId", "OOOO", 475 m->cxx(), alias = m->py(type->alias()), 476 pre = m->List(type->pre()), post = m->List(type->post())); 477 Py_DECREF(alias); 478 Py_DECREF(pre); 479 Py_DECREF(post); 480 return modifier; 481} 482 483PyObject *Translator::Array(Types::Array *type) 484{ 485 Trace trace("Translator::Array", Trace::TRANSLATION); 486 PyObject *array, *alias, *sizes; 487 array = PyObject_CallMethod(m_asg_module, "ArrayTypeId", "OOO", 488 m->cxx(), alias = m->py(type->alias()), 489 sizes = m->List(type->sizes())); 490 Py_DECREF(alias); 491 Py_DECREF(sizes); 492 return array; 493} 494 495PyObject *Translator::Parameterized(Types::Parameterized* type) 496{ 497 Trace trace("Translator::Parametrized", Trace::TRANSLATION); 498 PyObject *parametrized, *templ, *params; 499 parametrized = PyObject_CallMethod(m_asg_module, "ParametrizedTypeId", "OOO", 500 m->cxx(), templ = m->py(type->template_id()), 501 params = m->List(type->parameters())); 502 Py_DECREF(templ); 503 Py_DECREF(params); 504 return parametrized; 505} 506 507PyObject *Translator::FuncPtr(Types::FuncPtr* type) 508{ 509 Trace trace("Translator::FuncType", Trace::TRANSLATION); 510 PyObject *func, *ret, *pre, *params; 511 func = PyObject_CallMethod(m_asg_module, "FunctionTypeId", "OOOO", 512 m->cxx(), ret = m->py(type->return_type()), 513 pre = m->List(type->pre()), 514 params = m->List(type->parameters())); 515 Py_DECREF(ret); 516 Py_DECREF(pre); 517 Py_DECREF(params); 518 return func; 519} 520 521void Translator::addComments(PyObject* pydecl, ASG::Declaration* cdecl) 522{ 523 Trace trace("Translator::addComments", Trace::TRANSLATION); 524 PyObject *annotations = PyObject_GetAttrString(pydecl, "annotations"); 525 PyObject *comments = m->List(cdecl->comments()); 526 int size = PyList_GET_SIZE(comments); 527 if (size) 528 { 529 PyObject *lasg = PyList_GetItem(comments, size -1); 530 if (!PyString_Size(lasg)) 531 PyList_SetItem(comments, size -1, Py_None); 532 } 533 534 PyDict_SetItemString(annotations, "comments", comments); 535 // Also set the accessability.. 536 PyObject_SetAttrString(pydecl, "accessibility", PyInt_FromLong(int(cdecl->access()))); 537 Py_DECREF(annotations); 538 Py_DECREF(comments); 539} 540 541//. merge the file with an existing (python) object if it exists 542PyObject *Translator::SourceFile(ASG::SourceFile* file) 543{ 544 // don't construct, but instead find existing python object ! 545 Trace trace("Translator::SourceFile", Trace::TRANSLATION); 546 PyObject *files = PyObject_GetAttrString(m_ir, "files"); 547 if (!files) throw py_error_already_set(); 548 PyObject *pyfile = PyDict_GetItemString(files, const_cast<char *>(file->name().c_str())); 549 if (!pyfile) // the file wasn't found, create it now 550 { 551 PyObject *name, *abs_name; 552 pyfile = PyObject_CallMethod(m_sf_module, "SourceFile", "OOO", 553 name = m->py(file->name()), 554 abs_name = m->py(file->abs_name()), 555 m->cxx()); 556 if (!pyfile) throw py_error_already_set(); 557 Py_DECREF(name); 558 Py_DECREF(abs_name); 559 } 560 else Py_INCREF(pyfile); 561 562 // FIXME: why is this here ? Why can't we assume the preprocessor got it 563 // right ?? 564 565// // update the 'main' attribute to reflect the right value (this may 566// // differ from the original one if the preprocessor sees a different 567// // 'extra include' list from the one passed to the cxx parser 568// PyObject_CallMethod(pyfile, "set_is_main", "i", (int)file->is_main()); 569 570 Py_DECREF(files); 571 return pyfile; 572} 573 574PyObject *Translator::Include(ASG::Include* include) 575{ 576 Trace trace("Translator::Include", Trace::TRANSLATION); 577 PyObject *pyinclude, *target; 578 pyinclude = PyObject_CallMethod(m_sf_module, "Include", "Oii", 579 target = m->py(include->target()), 580 include->is_macro() ? 1 : 0, 581 include->is_next() ? 1 : 0); 582 if (!pyinclude) throw py_error_already_set(); 583 Py_DECREF(target); 584 return pyinclude; 585} 586 587PyObject *Translator::Declaration(ASG::Declaration* decl) 588{ 589 Trace trace("Translator::Declaration", Trace::TRANSLATION); 590 PyObject *pydecl, *file, *type, *name; 591 pydecl = PyObject_CallMethod(m_asg_module, "Declaration", "OiOO", 592 file = m->py(decl->file()), decl->line(), 593 type = m->py(decl->type()), name = m->QName(decl->name())); 594 if (!pydecl) throw py_error_already_set(); 595 addComments(pydecl, decl); 596 Py_DECREF(file); 597 Py_DECREF(type); 598 Py_DECREF(name); 599 return pydecl; 600} 601 602PyObject *Translator::Builtin(ASG::Builtin* decl) 603{ 604 Trace trace("Translator::Builtin", Trace::TRANSLATION); 605 PyObject *pybuiltin, *file, *type, *name; 606 pybuiltin = PyObject_CallMethod(m_asg_module, "Builtin", "OiOO", 607 file = m->py(decl->file()), decl->line(), 608 type = m->py(decl->type()), name = m->QName(decl->name())); 609 if (!pybuiltin) throw py_error_already_set(); 610 addComments(pybuiltin, decl); 611 Py_DECREF(file); 612 Py_DECREF(type); 613 Py_DECREF(name); 614 return pybuiltin; 615} 616 617PyObject *Translator::Macro(ASG::Macro* decl) 618{ 619 Trace trace("Translator::Macro", Trace::TRANSLATION); 620 PyObject *pymacro, *file, *type, *name, *params, *text; 621 if (decl->parameters()) params = m->List(*decl->parameters()); 622 else 623 { 624 params = Py_None; 625 Py_INCREF(Py_None); 626 } 627 pymacro = PyObject_CallMethod(m_asg_module, "Macro", "OiOOOO", 628 file = m->py(decl->file()), decl->line(), 629 type = m->py(decl->type()), name = m->QName(decl->name()), 630 params, text = m->py(decl->text())); 631 if (!pymacro) throw py_error_already_set(); 632 addComments(pymacro, decl); 633 Py_DECREF(file); 634 Py_DECREF(type); 635 Py_DECREF(name); 636 Py_DECREF(params); 637 Py_DECREF(text); 638 return pymacro; 639} 640 641PyObject *Translator::Forward(ASG::Forward* decl) 642{ 643 Trace trace("Translator::Forward", Trace::TRANSLATION); 644 PyObject *forward, *file, *type, *name; 645 forward = PyObject_CallMethod(m_asg_module, "Forward", "OiOO", 646 file = m->py(decl->file()), decl->line(), 647 type = m->py(decl->type()), name = m->QName(decl->name())); 648 // This is necessary to prevent inf. loops in several places 649 m->add(decl, forward); 650 if (decl->template_id()) 651 { 652 PyObject* ttype = m->py(decl->template_id()); 653 PyObject_SetAttrString(forward, "template", ttype); 654 Py_DECREF(ttype); 655 } 656 if (decl->is_template_specialization()) 657 { 658 PyObject_SetAttrString(forward, "is_template_specialization", Py_True); 659 } 660 addComments(forward, decl); 661 Py_DECREF(file); 662 Py_DECREF(type); 663 Py_DECREF(name); 664 return forward; 665} 666 667PyObject *Translator::Scope(ASG::Scope* decl) 668{ 669 Trace trace("Translator::Scope", Trace::TRANSLATION); 670 PyObject *scope, *file, *type, *name; 671 scope = PyObject_CallMethod(m_asg_module, "Scope", "OiOO", 672 file = m->py(decl->file()), decl->line(), 673 type = m->py(decl->type()), name = m->QName(decl->name())); 674 PyObject *decls = PyObject_GetAttrString(scope, "declarations"); 675 PyObject_CallMethod(decls, "extend", "O", m->List(decl->declarations())); 676 addComments(scope, decl); 677 Py_DECREF(file); 678 Py_DECREF(type); 679 Py_DECREF(name); 680 Py_DECREF(decls); 681 return scope; 682} 683 684PyObject *Translator::Namespace(ASG::Namespace* decl) 685{ 686 Trace trace("Translator::Namespace", Trace::TRANSLATION); 687 PyObject *module, *file, *type, *name; 688 module = PyObject_CallMethod(m_asg_module, "Module", "OiOO", 689 file = m->py(decl->file()), decl->line(), 690 type = m->py(decl->type()), name = m->QName(decl->name())); 691 PyObject *decls = PyObject_GetAttrString(module, "declarations"); 692 PyObject *new_decls = m->List(decl->declarations()); 693 PyObject_CallMethod(decls, "extend", "O", new_decls); 694 addComments(module, decl); 695 Py_DECREF(file); 696 Py_DECREF(type); 697 Py_DECREF(name); 698 Py_DECREF(decls); 699 Py_DECREF(new_decls); 700 return module; 701} 702 703PyObject *Translator::Inheritance(ASG::Inheritance* decl) 704{ 705 Trace trace("Translator::Inheritance", Trace::TRANSLATION); 706 PyObject *inheritance, *parent, *attrs; 707 inheritance = PyObject_CallMethod(m_asg_module, "Inheritance", "sOO", 708 "inherits", parent = m->py(decl->parent()), 709 attrs = m->List(decl->attributes())); 710 Py_DECREF(parent); 711 Py_DECREF(attrs); 712 return inheritance; 713} 714 715PyObject *Translator::Class(ASG::Class* decl) 716{ 717 Trace trace("Translator::Class", Trace::TRANSLATION); 718 PyObject *clas, *file, *type, *name; 719 clas = PyObject_CallMethod(m_asg_module, "Class", "OiOO", 720 file = m->py(decl->file()), 721 decl->line(), 722 type = m->py(decl->type()), 723 name = m->QName(decl->name())); 724 // This is necessary to prevent inf. loops in several places 725 m->add(decl, clas); 726 PyObject *new_decls, *new_parents; 727 PyObject *decls = PyObject_GetAttrString(clas, "declarations"); 728 PyObject_CallMethod(decls, "extend", "O", new_decls = m->List(decl->declarations())); 729 PyObject *parents = PyObject_GetAttrString(clas, "parents"); 730 PyObject_CallMethod(parents, "extend", "O", new_parents = m->List(decl->parents())); 731 if (decl->is_template_specialization()) 732 { 733 PyObject_SetAttrString(clas, "is_template_specialization", Py_True); 734 } 735 addComments(clas, decl); 736 Py_DECREF(file); 737 Py_DECREF(type); 738 Py_DECREF(name); 739 Py_DECREF(decls); 740 Py_DECREF(parents); 741 Py_DECREF(new_decls); 742 Py_DECREF(new_parents); 743 return clas; 744} 745 746PyObject *Translator::ClassTemplate(ASG::ClassTemplate *decl) 747{ 748 Trace trace("Translator::ClassTemplate", Trace::TRANSLATION); 749 PyObject *clas, *file, *type, *name; 750 clas = PyObject_CallMethod(m_asg_module, "ClassTemplate", "OiOO", 751 file = m->py(decl->file()), 752 decl->line(), 753 type = m->py(decl->type()), 754 name = m->QName(decl->name())); 755 // This is necessary to prevent inf. loops in several places 756 m->add(decl, clas); 757 PyObject *new_decls, *new_parents; 758 PyObject *decls = PyObject_GetAttrString(clas, "declarations"); 759 PyObject_CallMethod(decls, "extend", "O", new_decls = m->List(decl->declarations())); 760 761 PyObject* ttype = m->py(decl->template_id()); 762 PyObject_SetAttrString(clas, "template", ttype); 763 Py_DECREF(ttype); 764 765 PyObject *parents = PyObject_GetAttrString(clas, "parents"); 766 PyObject_CallMethod(parents, "extend", "O", new_parents = m->List(decl->parents())); 767 if (decl->is_template_specialization()) 768 { 769 PyObject_SetAttrString(clas, "is_template_specialization", Py_True); 770 } 771 addComments(clas, decl); 772 Py_DECREF(file); 773 Py_DECREF(type); 774 Py_DECREF(name); 775 Py_DECREF(decls); 776 Py_DECREF(parents); 777 Py_DECREF(new_decls); 778 Py_DECREF(new_parents); 779 return clas; 780} 781 782PyObject *Translator::Typedef(ASG::Typedef* decl) 783{ 784 Trace trace("Translator::Typedef", Trace::TRANSLATION); 785 // FIXME: what to do about the declarator? 786 PyObject *tdef, *file, *type, *name, *alias; 787 tdef = PyObject_CallMethod(m_asg_module, "Typedef", "OiOOOi", 788 file = m->py(decl->file()), decl->line(), 789 type = m->py(decl->type()), name = m->QName(decl->name()), 790 alias = m->py(decl->alias()), decl->constructed()); 791 addComments(tdef, decl); 792 Py_DECREF(file); 793 Py_DECREF(type); 794 Py_DECREF(name); 795 Py_DECREF(alias); 796 return tdef; 797} 798 799PyObject *Translator::Enumerator(ASG::Enumerator* decl) 800{ 801 Trace trace("Translator::Enumerator", Trace::TRANSLATION); 802 PyObject *enumor, *file, *name, *type; 803 if (decl->type() == "dummy") // work around a hack with another hack ;-) 804 { 805 std::vector<std::string> eos; 806 eos.push_back("EOS"); 807 enumor = PyObject_CallMethod(m_asg_module, "Builtin", "OiOO", 808 file = m->py(decl->file()), decl->line(), 809 type = m->py("EOS"), name = m->QName(eos)); 810 } 811 else 812 enumor = PyObject_CallMethod(m_asg_module, "Enumerator", "OiOs", 813 file = m->py(decl->file()), decl->line(), 814 name = m->QName(decl->name()), decl->value().c_str()); 815 addComments(enumor, decl); 816 Py_DECREF(file); 817 Py_DECREF(name); 818 return enumor; 819} 820 821PyObject *Translator::Enum(ASG::Enum* decl) 822{ 823 Trace trace("Translator::Enum", Trace::TRANSLATION); 824 PyObject *enumor, *file, *enums, *name; 825 enumor = PyObject_CallMethod(m_asg_module, "Enum", "OiOO", 826 file = m->py(decl->file()), decl->line(), 827 name = m->QName(decl->name()), enums = m->List(decl->enumerators())); 828 addComments(enumor, decl); 829 Py_DECREF(file); 830 Py_DECREF(enums); 831 Py_DECREF(name); 832 return enumor; 833} 834 835PyObject *Translator::Variable(ASG::Variable* decl) 836{ 837 Trace trace("Translator::Variable", Trace::TRANSLATION); 838 PyObject *var, *file, *type, *name, *vtype; 839 var = PyObject_CallMethod(m_asg_module, "Variable", "OiOOOi", 840 file = m->py(decl->file()), decl->line(), 841 type = m->py(decl->type()), name = m->QName(decl->name()), 842 vtype = m->py(decl->vtype()), decl->constructed()); 843 addComments(var, decl); 844 Py_DECREF(file); 845 Py_DECREF(type); 846 Py_DECREF(vtype); 847 Py_DECREF(name); 848 return var; 849} 850 851PyObject *Translator::Const(ASG::Const* decl) 852{ 853 Trace trace("Translator::Const", Trace::TRANSLATION); 854 PyObject *cons, *file, *type, *name, *ctype; 855 cons = PyObject_CallMethod(m_asg_module, "Const", "OiOOOs", 856 file = m->py(decl->file()), decl->line(), 857 type = m->py(decl->type()), ctype = m->py(decl->ctype()), 858 name = m->QName(decl->name()), decl->value().c_str()); 859 if (PyErr_Occurred()) PyErr_Print(); 860 addComments(cons, decl); 861 Py_DECREF(file); 862 Py_DECREF(type); 863 Py_DECREF(ctype); 864 Py_DECREF(name); 865 return cons; 866} 867 868PyObject *Translator::Parameter(ASG::Parameter* decl) 869{ 870 Trace trace("Translator::Parameter", Trace::TRANSLATION); 871 PyObject *param, *pre, *post, *type, *value, *name; 872 param = PyObject_CallMethod(m_asg_module, "Parameter", "OOOOO", 873 pre = m->List(decl->premodifier()), type = m->py(decl->type()), 874 post = m->List(decl->postmodifier()), 875 name = m->py(decl->name()), value = m->py(decl->value())); 876 Py_DECREF(pre); 877 Py_DECREF(post); 878 Py_DECREF(type); 879 Py_DECREF(value); 880 Py_DECREF(name); 881 return param; 882} 883 884PyObject *Translator::Function(ASG::Function* decl) 885{ 886 Trace trace("Translator::Function", Trace::TRANSLATION); 887 PyObject *func, *file, *type, *name, *pre, *ret, *post, *realname; 888 char const *class_ = decl->template_id() ? "FunctionTemplate" : "Function"; 889 func = PyObject_CallMethod(m_asg_module, const_cast<char *>(class_), "OiOOOOOO", 890 file = m->py(decl->file()), decl->line(), 891 type = m->py(decl->type()), pre = m->List(decl->premodifier()), 892 ret = m->py(decl->return_type()), post = m->List(decl->postmodifier()), 893 name = m->QName(decl->name()), realname = m->py(decl->realname())); 894 // This is necessary to prevent inf. loops in several places 895 m->add(decl, func); 896 if (decl->template_id()) 897 { 898 PyObject* ttype = m->py(decl->template_id()); 899 PyObject_SetAttrString(func, "template", ttype); 900 Py_DECREF(ttype); 901 } 902 PyObject* new_params; 903 PyObject* params = PyObject_GetAttrString(func, "parameters"); 904 PyObject_CallMethod(params, "extend", "O", new_params = m->List(decl->parameters())); 905 addComments(func, decl); 906 Py_DECREF(file); 907 Py_DECREF(type); 908 Py_DECREF(name); 909 Py_DECREF(pre); 910 Py_DECREF(ret); 911 Py_DECREF(post); 912 Py_DECREF(realname); 913 Py_DECREF(params); 914 Py_DECREF(new_params); 915 return func; 916} 917 918PyObject *Translator::Operation(ASG::Operation* decl) 919{ 920 Trace trace("Translator::Operation", Trace::TRANSLATION); 921 PyObject *oper, *file, *type, *name, *pre, *ret, *post, *realname; 922 char const *class_ = decl->template_id() ? "OperationTemplate" : "Operation"; 923 oper = PyObject_CallMethod(m_asg_module, const_cast<char *>(class_), "OiOOOOOO", 924 file = m->py(decl->file()), decl->line(), 925 type = m->py(decl->type()), pre = m->List(decl->premodifier()), 926 ret = m->py(decl->return_type()), post = m->List(decl->postmodifier()), 927 name = m->QName(decl->name()), realname = m->py(decl->realname())); 928 // This is necessary to prevent inf. loops in several places 929 m->add(decl, oper); 930 if (decl->template_id()) 931 { 932 PyObject* ttype = m->py(decl->template_id()); 933 PyObject_SetAttrString(oper, "template", ttype); 934 Py_DECREF(ttype); 935 } 936 PyObject* new_params; 937 PyObject* params = PyObject_GetAttrString(oper, "parameters"); 938 PyObject_CallMethod(params, "extend", "O", new_params = m->List(decl->parameters())); 939 addComments(oper, decl); 940 Py_DECREF(file); 941 Py_DECREF(type); 942 Py_DECREF(name); 943 Py_DECREF(pre); 944 Py_DECREF(ret); 945 Py_DECREF(post); 946 Py_DECREF(realname); 947 Py_DECREF(params); 948 Py_DECREF(new_params); 949 return oper; 950} 951 952PyObject *Translator::UsingDirective(ASG::UsingDirective* u) 953{ 954 Trace trace("Translator::UsingDirective", Trace::TRANSLATION); 955 PyObject *dir, *file, *type, *name; 956 dir = PyObject_CallMethod(m_asg_module, "UsingDirective", "OiOO", 957 file = m->py(u->file()), u->line(), 958 type = m->py(u->type()), name = m->QName(u->name())); 959 Py_DECREF(file); 960 Py_DECREF(type); 961 Py_DECREF(name); 962 return dir; 963} 964 965PyObject *Translator::UsingDeclaration(ASG::UsingDeclaration* u) 966{ 967 Trace trace("Translator::UsingDeclaration", Trace::TRANSLATION); 968 PyObject *decl, *file, *type, *name, *alias; 969 decl = PyObject_CallMethod(m_asg_module, "UsingDeclaration", "OiOOO", 970 file = m->py(u->file()), u->line(), 971 type = m->py(u->type()), name = m->QName(u->name()), 972 alias = m->QName(u->target()->name())); 973 Py_DECREF(alias); 974 Py_DECREF(file); 975 Py_DECREF(type); 976 Py_DECREF(name); 977 return decl; 978} 979 980void Translator::visit_declaration(ASG::Declaration* decl) 981{ 982 // Assume this is a dummy declaration 983 if (m_filter->should_store(decl)) m->add(decl, Declaration(decl)); 984} 985void Translator::visit_builtin(ASG::Builtin* decl) 986{ 987 if (m_filter->should_store(decl)) m->add(decl, Builtin(decl)); 988} 989void Translator::visit_macro(ASG::Macro* decl) 990{ 991 if (m_filter->should_store(decl)) m->add(decl, Macro(decl)); 992} 993void Translator::visit_scope(ASG::Scope* decl) 994{ 995 if (m_filter->should_store(decl)) m->add(decl, Scope(decl)); 996 //else 997 // m->add(decl, Forward(new ASG::Forward(decl))); 998} 999void Translator::visit_namespace(ASG::Namespace* decl) 1000{ 1001 // Namespaces are always included, because the Linker knows to combine 1002 // them always. The exception are "local namespaces", those created to 1003 // handle scopes created by braces in code. 1004 if (decl->type() != "local") m->add(decl, Namespace(decl)); 1005} 1006void Translator::visit_class(ASG::Class* decl) 1007{ 1008 // Add if the class is in the main file, *or* if it has any members 1009 // declared in the main file (eg: forward declared nested classes which 1010 // are fully defined in this main file) 1011 if (m_filter->should_store(decl)) m->add(decl, Class(decl)); 1012 //else 1013 // m->add(decl, Forward(new ASG::Forward(decl))); 1014} 1015void Translator::visit_class_template(ASG::ClassTemplate* decl) 1016{ 1017 // Add if the class is in the main file, *or* if it has any members 1018 // declared in the main file (eg: forward declared nested classes which 1019 // are fully defined in this main file) 1020 if (m_filter->should_store(decl)) m->add(decl, ClassTemplate(decl)); 1021} 1022void Translator::visit_forward(ASG::Forward* decl) 1023{ 1024 if (m_filter->should_store(decl)) m->add(decl, Forward(decl)); 1025 //else 1026 // m->add(decl, Forward(new ASG::Forward(decl))); 1027} 1028void Translator::visit_typedef(ASG::Typedef* decl) 1029{ 1030 if (m_filter->should_store(decl)) m->add(decl, Typedef(decl)); 1031 //else 1032 // m->add(decl, Forward(new ASG::Forward(decl))); 1033} 1034void Translator::visit_variable(ASG::Variable* decl) 1035{ 1036 if (m_filter->should_store(decl)) m->add(decl, Variable(decl)); 1037 //else 1038 // m->add(decl, Forward(new ASG::Forward(decl))); 1039} 1040void Translator::visit_const(ASG::Const* decl) 1041{ 1042 if (m_filter->should_store(decl)) m->add(decl, Const(decl)); 1043 //else 1044 // m->add(decl, Forward(new ASG::Forward(decl))); 1045} 1046void Translator::visit_enum(ASG::Enum* decl) 1047{ 1048 if (m_filter->should_store(decl)) m->add(decl, Enum(decl)); 1049 //else 1050 // m->add(decl, Forward(new ASG::Forward(decl))); 1051} 1052void Translator::visit_enumerator(ASG::Enumerator* decl) 1053{ 1054 m->add(decl, Enumerator(decl)); 1055} 1056void Translator::visit_function(ASG::Function* decl) 1057{ 1058 if (m_filter->should_store(decl)) m->add(decl, Function(decl)); 1059 //else 1060 // m->add(decl, Forward(new ASG::Forward(decl))); 1061} 1062void Translator::visit_operation(ASG::Operation* decl) 1063{ 1064 if (m_filter->should_store(decl)) m->add(decl, Operation(decl)); 1065 //else 1066 // m->add(decl, Forward(new ASG::Forward(decl))); 1067} 1068 1069void Translator::visit_inheritance(ASG::Inheritance* decl) 1070{ 1071 m->add(decl, Inheritance(decl)); 1072} 1073void Translator::visit_parameter(ASG::Parameter* decl) 1074{ 1075 m->add(decl, Parameter(decl)); 1076} 1077void Translator::visit_using_directive(ASG::UsingDirective* u) 1078{ 1079 m->add(u, UsingDirective(u)); 1080} 1081void Translator::visit_using_declaration(ASG::UsingDeclaration* u) 1082{ 1083 m->add(u, UsingDeclaration(u)); 1084} 1085 1086// 1087// Types::Visitor methods 1088// 1089/*void Translator::visitType(Types::Type* type) { 1090 m->add(type, this->Type(type)); 1091 }*/ 1092void Translator::visit_unknown(Types::Unknown* type) 1093{ 1094 m->add(type, Unknown(type)); 1095} 1096void Translator::visit_dependent(Types::Dependent* type) 1097{ 1098 m->add(type, Dependent(type)); 1099} 1100void Translator::visit_modifier(Types::Modifier* type) 1101{ 1102 m->add(type, Modifier(type)); 1103} 1104void Translator::visit_array(Types::Array *type) 1105{ 1106 m->add(type, Array(type)); 1107} 1108/*void Translator::visitNamed(Types::Named* type) { 1109 m->add(type, Named(type)); 1110 }*/ 1111void Translator::visit_base(Types::Base* type) 1112{ 1113 m->add(type, Base(type)); 1114} 1115void Translator::visit_declared(Types::Declared* type) 1116{ 1117 if (!m_filter->should_store(type->declaration())) 1118 m->add(type, Unknown(type)); 1119 else m->add(type, Declared(type)); 1120} 1121void Translator::visit_template_type(Types::Template* type) 1122{ 1123 if (!m_filter->should_store(type->declaration())) 1124 m->add(type, Unknown(type)); 1125 else m->add(type, Template(type)); 1126} 1127void Translator::visit_parameterized(Types::Parameterized* type) 1128{ 1129 m->add(type, Parameterized(type)); 1130} 1131void Translator::visit_func_ptr(Types::FuncPtr* type) 1132{ 1133 m->add(type, FuncPtr(type)); 1134}