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