Synopsis - Cross-Reference

File: /Synopsis/Parsers/Cxx/Translator.cc
   1//
   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}