summaryrefslogtreecommitdiff
path: root/odb/validator.cxx
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 /odb/validator.cxx
parent7615f4dd87092aec82569bce68d75efcb82a90ae (diff)
Add validator pass
Detect members with anonymous types.
Diffstat (limited to 'odb/validator.cxx')
-rw-r--r--odb/validator.cxx144
1 files changed, 144 insertions, 0 deletions
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 ()
+{
+}