aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-08-19 14:36:47 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-08-19 14:36:47 +0200
commit33cd64535d2307a2e7884ee0796e1aae42937aaf (patch)
tree6f20845b78387138def085377b3a07f984f09507
parent7615f4dd87092aec82569bce68d75efcb82a90ae (diff)
Add validator pass
Detect members with anonymous types.
-rw-r--r--odb/makefile1
-rw-r--r--odb/mysql/header.cxx34
-rw-r--r--odb/plugin.cxx16
-rw-r--r--odb/tracer/header.cxx28
-rw-r--r--odb/validator.cxx144
-rw-r--r--odb/validator.hxx25
6 files changed, 184 insertions, 64 deletions
diff --git a/odb/makefile b/odb/makefile
index d9e5a5d..5eb23a1 100644
--- a/odb/makefile
+++ b/odb/makefile
@@ -10,6 +10,7 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
cxx_ptun := \
sql-lexer.cxx \
context.cxx \
+validator.cxx \
generator.cxx \
parser.cxx \
plugin.cxx \
diff --git a/odb/mysql/header.cxx b/odb/mysql/header.cxx
index 5e64c12..237cb85 100644
--- a/odb/mysql/header.cxx
+++ b/odb/mysql/header.cxx
@@ -219,46 +219,12 @@ namespace mysql
// Find the id member and type.
//
id_member_.traverse (c);
-
- if (id_member_.member () == 0)
- {
- cerr << c.file () << ":" << c.line () << ":" << c.column () << ":"
- << " error: no data member designated as object id" << endl;
-
- cerr << c.file () << ":" << c.line () << ":" << c.column () << ":"
- << " info: use '#pragma odb id' to specify object id member"
- << endl;
- }
-
semantics::data_member& id (*id_member_.member ());
semantics::type& id_type (id.type ());
- if (id_type.anonymous ())
- {
- // Can be a template-id (which we should handle eventually) or an
- // anonymous type in member declaration (e.g., struct {...} m_;).
- //
- cerr << id.file () << ":" << id.line () << ":" << id.column () << ":"
- << " error: unnamed type in data member declaration" << endl;
-
- cerr << id.file () << ":" << id.line () << ":" << id.column () << ":"
- << " info: use 'typedef' to name this type"
- << endl;
-
- throw generation_failed ();
- }
-
member_count_.traverse (c);
size_t column_count (member_count_.count ());
- if (column_count == 0)
- {
- cerr << c.file () << ":" << c.line () << ":" << c.column () << ":"
- << " error: no persistent data members in the class" << endl;
-
- throw generation_failed ();
- }
-
os << "// " << c.name () << endl
<< "//" << endl;
diff --git a/odb/plugin.cxx b/odb/plugin.cxx
index 6cceea3..dd097cc 100644
--- a/odb/plugin.cxx
+++ b/odb/plugin.cxx
@@ -13,6 +13,7 @@
#include <odb/pragma.hxx>
#include <odb/parser.hxx>
#include <odb/options.hxx>
+#include <odb/validator.hxx>
#include <odb/generator.hxx>
#include <odb/semantics/unit.hxx>
@@ -39,8 +40,19 @@ gate_callback (void*, void*)
path file (main_input_filename);
auto_ptr<unit> u (p.parse (global_namespace, file));
- generator g;
- g.generate (*options_, *u, file);
+ //
+ //
+ validator v;
+ if (!v.validate (*options_, *u, file))
+ r = 1;
+
+ //
+ //
+ if (r == 0)
+ {
+ generator g;
+ g.generate (*options_, *u, file);
+ }
}
catch (parser::failed const&)
{
diff --git a/odb/tracer/header.cxx b/odb/tracer/header.cxx
index 011ff9d..0516847 100644
--- a/odb/tracer/header.cxx
+++ b/odb/tracer/header.cxx
@@ -32,37 +32,9 @@ namespace tracer
//
id_member t;
t.traverse (c);
-
- if (t.member () == 0)
- {
- cerr << c.file () << ":" << c.line () << ":" << c.column () << ":"
- << " error: no data member designated as object id" << endl;
-
- cerr << c.file () << ":" << c.line () << ":" << c.column () << ":"
- << " info: use '#pragma odb id' to specify object id member"
- << endl;
-
- throw generation_failed ();
- }
-
semantics::data_member& id (*t.member ());
semantics::type& id_type (id.type ());
- if (id_type.anonymous ())
- {
- // Can be a template-id (which we should handle eventually) or an
- // anonymous type in member declaration (e.g., struct {...} m_;).
- //
- cerr << id.file () << ":" << id.line () << ":" << id.column () << ":"
- << " error: unnamed type in data member declaration" << endl;
-
- cerr << id.file () << ":" << id.line () << ":" << id.column () << ":"
- << " info: use 'typedef' to name this type"
- << endl;
-
- throw generation_failed ();
- }
-
os << "// " << c.name () << endl
<< "//" << endl;
diff --git a/odb/validator.cxx b/odb/validator.cxx
new file mode 100644
index 0000000..a834244
--- /dev/null
+++ b/odb/validator.cxx
@@ -0,0 +1,144 @@
+// file : odb/validator.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 <iostream>
+
+#include <odb/traversal.hxx>
+#include <odb/validator.hxx>
+
+using namespace std;
+
+namespace
+{
+ struct data_member: traversal::data_member
+ {
+ data_member (bool& valid)
+ : valid_ (valid)
+ {
+ }
+
+ virtual void
+ traverse (type& m)
+ {
+ if (m.count ("transient"))
+ return;
+
+ count_++;
+ semantics::type& type (m.type ());
+
+ if (type.anonymous ())
+ {
+ // Can be a template-id (which we should handle eventually) or an
+ // anonymous type in member declaration (e.g., struct {...} m_;).
+ //
+ cerr << m.file () << ":" << m.line () << ":" << m.column () << ":"
+ << " error: unnamed type in data member declaration" << endl;
+
+ cerr << m.file () << ":" << m.line () << ":" << m.column () << ":"
+ << " info: use 'typedef' to name this type" << endl;
+
+ valid_ = false;
+ }
+
+ if (m.count ("id"))
+ {
+ if (id_ != 0)
+ {
+ cerr << m.file () << ":" << m.line () << ":" << m.column () << ":"
+ << " error: multiple object id members" << endl;
+
+ cerr << id_->file () << ":" << id_->line () << ":" << id_->column ()
+ << ": info: previous id member declared here" << endl;
+
+ valid_ = false;
+ }
+
+ id_ = &m;
+ }
+ }
+
+ bool& valid_;
+ size_t count_;
+ semantics::data_member* id_;
+ };
+
+ struct class_: traversal::class_
+ {
+ class_ (bool& valid, semantics::unit& unit)
+ : valid_ (valid), unit_ (unit), member_ (valid)
+ {
+ *this >> names_ >> member_;
+ }
+
+
+ virtual void
+ traverse (type& c)
+ {
+ if (c.file () != unit_.file () || !c.count ("object"))
+ return;
+
+ member_.count_ = 0;
+ member_.id_ = 0;
+
+ names (c);
+
+ if (member_.id_ == 0)
+ {
+ cerr << c.file () << ":" << c.line () << ":" << c.column () << ":"
+ << " error: no data member designated as object id" << endl;
+
+ cerr << c.file () << ":" << c.line () << ":" << c.column () << ":"
+ << " info: use '#pragma odb id' to specify object id member"
+ << endl;
+
+ valid_ = false;
+ }
+
+ if (member_.count_ == 0)
+ {
+ cerr << c.file () << ":" << c.line () << ":" << c.column () << ":"
+ << " error: no persistent data members in the class" << endl;
+
+ valid_ = false;
+ }
+ }
+
+ bool& valid_;
+ semantics::unit& unit_;
+
+ data_member member_;
+ traversal::names names_;
+ };
+}
+
+bool validator::
+validate (options const&,
+ semantics::unit& u,
+ semantics::path const&)
+{
+ bool valid (true);
+
+ traversal::unit unit;
+ traversal::defines unit_defines;
+ traversal::namespace_ ns;
+ class_ c (valid, u);
+
+ unit >> unit_defines >> ns;
+ unit_defines >> c;
+
+ traversal::defines ns_defines;
+
+ ns >> ns_defines >> ns;
+ ns_defines >> c;
+
+ unit.dispatch (u);
+
+ return valid;
+}
+
+validator::
+validator ()
+{
+}
diff --git a/odb/validator.hxx b/odb/validator.hxx
new file mode 100644
index 0000000..623001c
--- /dev/null
+++ b/odb/validator.hxx
@@ -0,0 +1,25 @@
+// file : odb/validator.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_VALIDATOR_HXX
+#define ODB_VALIDATOR_HXX
+
+#include <odb/options.hxx>
+#include <odb/semantics/unit.hxx>
+
+class validator
+{
+public:
+ validator ();
+
+ bool
+ validate (options const&, semantics::unit&, semantics::path const&);
+
+private:
+ validator (validator const&);
+ validator& operator= (validator const&);
+};
+
+#endif // ODB_VALIDATOR_HXX