From 2c43c9dc379759f76e580c9c97fc5d9036659c25 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 2 Apr 2010 00:32:56 +0200 Subject: Detect odb-enabled classes and generate c-tor implementation --- libodb/odb/core.hxx | 16 ++++++++ odb/context.cxx | 21 ++++++---- odb/generator.cxx | 4 +- odb/makefile | 3 +- odb/source.cxx | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++ odb/source.hxx | 14 +++++++ 6 files changed, 160 insertions(+), 10 deletions(-) create mode 100644 libodb/odb/core.hxx create mode 100644 odb/source.cxx create mode 100644 odb/source.hxx diff --git a/libodb/odb/core.hxx b/libodb/odb/core.hxx new file mode 100644 index 0000000..a88012c --- /dev/null +++ b/libodb/odb/core.hxx @@ -0,0 +1,16 @@ +// file : odb/core.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_CORE_HXX +#define ODB_CORE_HXX + +namespace odb +{ + class image + { + }; +} + +#endif // ODB_CORE_HXX diff --git a/odb/context.cxx b/odb/context.cxx index f34bc5b..f2dce53 100644 --- a/odb/context.cxx +++ b/odb/context.cxx @@ -35,16 +35,21 @@ context (context& c) void namespace_:: traverse (type& ns) { - string name (ns.name ()); + // Only traverse namespaces from the main file. + // + if (ns.file () == unit.file ()) + { + string name (ns.name ()); - if (name.empty ()) - os << "namespace"; - else - os << "namespace " << name; + if (name.empty ()) + os << "namespace"; + else + os << "namespace " << name; - os << "{"; + os << "{"; - traversal::namespace_::traverse (ns); + traversal::namespace_::traverse (ns); - os << "}"; + os << "}"; + } } diff --git a/odb/generator.cxx b/odb/generator.cxx index 4538e54..87cc56f 100644 --- a/odb/generator.cxx +++ b/odb/generator.cxx @@ -16,6 +16,8 @@ #include #include +#include + using namespace std; using namespace cutl; @@ -130,7 +132,7 @@ generate (options const& ops, semantics::unit& unit, path const& p) (br ? '>' : '"') << endl << endl; - // generate_source (ctx); + generate_source (ctx); } auto_rm.cancel (); diff --git a/odb/makefile b/odb/makefile index 7375546..b66804d 100644 --- a/odb/makefile +++ b/odb/makefile @@ -10,7 +10,8 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make cxx_ptun := \ context.cxx \ generator.cxx \ -plugin.cxx +plugin.cxx \ +source.cxx cxx_ptun += \ semantics/class.cxx \ diff --git a/odb/source.cxx b/odb/source.cxx new file mode 100644 index 0000000..02d26c4 --- /dev/null +++ b/odb/source.cxx @@ -0,0 +1,112 @@ +// file : odb/source.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +namespace +{ + struct class_: traversal::class_, context + { + class_ (context& c) + : context (c) + { + } + + virtual void + traverse (type& c) + { + if (c.file () != unit.file () || !odb_class (c)) + return; + + string const& name (c.name ()); + + os << "// " << c.name () << endl + << "//" << endl; + + os << name << "::" << endl + << name << " (::odb::image& i)" + << "{" + << "}"; + } + + private: + bool + odb_class (type& c) + { + // See if this class defines the ODB-specific c-tor. + // + tree t (c.tree_node ()); + + for (tree f (TYPE_METHODS (t)); f != 0; f = TREE_CHAIN (f)) + { + if (DECL_CONSTRUCTOR_P (f)) + { + // Get the argument list and skip the first (this) argument. + // + tree a (TREE_CHAIN (DECL_ARGUMENTS (f))); + + if (a == 0) + continue; + + tree at (TREE_TYPE (a)); + + // Check that it is ::odb::image&. + // + if (TREE_CODE (at) != REFERENCE_TYPE) + continue; + + tree rt (TREE_TYPE (at)); + tree mt (TYPE_MAIN_VARIANT (rt)); + + semantics::node* node (unit.find (mt)); + + if (node == 0) + continue; + + semantics::type* t_node (dynamic_cast (node)); + + if (t_node == 0) + continue; + + if (t_node->anonymous () || t_node->fq_name () != "::odb::image") + continue; + + // Make sure it is unqualified. + // + if (cp_type_quals (rt) != TYPE_UNQUALIFIED) + continue; // @@ Should probably be an error/warning. + + // Check that it is the only argument. + // + if (TREE_CHAIN (a) != 0) + continue; // @@ Should probably be an error/warning. + + return true; + } + } + + return false; + } + }; +} + +void +generate_source (context& ctx) +{ + traversal::unit unit; + traversal::defines unit_defines; + namespace_ ns (ctx); + class_ c (ctx); + + unit >> unit_defines >> ns; + unit_defines >> c; + + traversal::defines ns_defines; + + ns >> ns_defines >> ns; + ns_defines >> c; + + unit.dispatch (ctx.unit); +} diff --git a/odb/source.hxx b/odb/source.hxx new file mode 100644 index 0000000..9fac039 --- /dev/null +++ b/odb/source.hxx @@ -0,0 +1,14 @@ +// file : odb/source.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_SOURCE_HXX +#define ODB_SOURCE_HXX + +#include "context.hxx" + +void +generate_source (context&); + +#endif // ODB_SOURCE_HXX -- cgit v1.1