diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2010-04-02 00:32:56 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2010-04-02 00:32:56 +0200 |
commit | 2c43c9dc379759f76e580c9c97fc5d9036659c25 (patch) | |
tree | e570756ca1d65a07df507c604134e0e075671607 /odb/source.cxx | |
parent | b7824f749e29f7c9d018e468e18c2c7b6bd3e4c9 (diff) |
Detect odb-enabled classes and generate c-tor implementation
Diffstat (limited to 'odb/source.cxx')
-rw-r--r-- | odb/source.cxx | 112 |
1 files changed, 112 insertions, 0 deletions
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 <boris@codesynthesis.com> +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include <odb/source.hxx> + +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<semantics::type*> (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); +} |