From 33cd64535d2307a2e7884ee0796e1aae42937aaf Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 19 Aug 2010 14:36:47 +0200 Subject: Add validator pass Detect members with anonymous types. --- odb/makefile | 1 + odb/mysql/header.cxx | 34 ------------ odb/plugin.cxx | 16 +++++- odb/tracer/header.cxx | 28 ---------- odb/validator.cxx | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++ odb/validator.hxx | 25 +++++++++ 6 files changed, 184 insertions(+), 64 deletions(-) create mode 100644 odb/validator.cxx create mode 100644 odb/validator.hxx 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 #include #include +#include #include #include @@ -39,8 +40,19 @@ gate_callback (void*, void*) path file (main_input_filename); auto_ptr 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 +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include + +#include +#include + +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 +// 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 +#include + +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 -- cgit v1.1