From 8fc4fda0ce88fccbe40c36be3925237a4bca36d9 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 19 Sep 2011 16:42:28 +0200 Subject: Split validator into 2 passes, before and after processing This is necessary because we sometimes need information during validation (e.g., object pointer and container status) that is determined by the processor. --- odb/plugin.cxx | 13 ++- odb/validator.cxx | 236 +++++++++++++++++++++++++++++++++++------------------- odb/validator.hxx | 7 +- 3 files changed, 170 insertions(+), 86 deletions(-) diff --git a/odb/plugin.cxx b/odb/plugin.cxx index aba5e78..7f01478 100644 --- a/odb/plugin.cxx +++ b/odb/plugin.cxx @@ -110,11 +110,11 @@ gate_callback (void*, void*) parser p (*options_, loc_pragmas_, decl_pragmas_); auto_ptr u (p.parse (global_namespace, file_)); - // Validate. + // Validate, pass 1. // { validator v; - if (!v.validate (*options_, *u, file_)) + if (!v.validate (*options_, *u, file_, 1)) r = 1; } @@ -126,6 +126,15 @@ gate_callback (void*, void*) p.process (*options_, *u, file_); } + // Validate, pass 2. + // + if (r == 0) + { + validator v; + if (!v.validate (*options_, *u, file_, 2)) + r = 1; + } + // Generate. // if (r == 0) diff --git a/odb/validator.cxx b/odb/validator.cxx index 7fb6a68..90e6b7e 100644 --- a/odb/validator.cxx +++ b/odb/validator.cxx @@ -39,6 +39,10 @@ namespace } } + // + // Pass 1. + // + struct data_member: traversal::data_member { data_member (bool& valid) @@ -166,64 +170,6 @@ namespace traversal::inherits inherits_; }; - struct view_data_member: object_members_base - { - view_data_member (bool& valid) - : object_members_base (false, false, true), valid_ (valid), dm_ (0) - { - } - - virtual void - traverse_simple (semantics::data_member& m) - { - if (context::object_pointer (m.type ())) - { - semantics::data_member& dm (dm_ != 0 ? *dm_ : m); - - cerr << dm.file () << ":" << dm.line () << ":" << dm.column () << ":" - << " error: view data member '" << member_prefix_ << m.name () - << "' is an object pointer" << endl; - - cerr << dm.file () << ":" << dm.line () << ":" << dm.column () << ":" - << ": info: views cannot contain object pointers" << endl; - - valid_ = false; - } - } - - virtual void - traverse_container (semantics::data_member& m, semantics::type&) - { - semantics::data_member& dm (dm_ != 0 ? *dm_ : m); - - cerr << dm.file () << ":" << dm.line () << ":" << dm.column () << ":" - << " error: view data member '" << member_prefix_ << m.name () - << "' is a container" << endl; - - cerr << dm.file () << ":" << dm.line () << ":" << dm.column () << ":" - << ": info: views cannot contain containers" << endl; - - valid_ = false; - } - - virtual void - traverse_composite (semantics::data_member* m, semantics::class_& c) - { - semantics::data_member* old_dm (dm_); - - if (dm_ == 0) - dm_ = m; - - object_members_base::traverse_composite (m, c); - - dm_ = old_dm; - } - - private: - bool& valid_; - semantics::data_member* dm_; // Direct view data member. - }; - // // struct value_type: traversal::type @@ -244,9 +190,9 @@ namespace // // - struct class_: traversal::class_ + struct class1: traversal::class_ { - class_ (bool& valid, + class1 (bool& valid, options const& ops, semantics::unit& unit, value_type& vt) @@ -254,11 +200,9 @@ namespace options_ (ops), unit_ (unit), vt_ (vt), - member_ (valid), - view_member_ (valid) + member_ (valid) { *this >> names_ >> member_; - view_names_ >> view_member_; } virtual void @@ -500,8 +444,6 @@ namespace valid_ = false; } - - //names (c, view_names_); } virtual void @@ -577,38 +519,166 @@ namespace data_member member_; traversal::names names_; + }; - view_data_member view_member_; - traversal::names view_names_; + // + // Pass 2. + // + + struct view_members: object_members_base + { + view_members (bool& valid) + : object_members_base (false, false, true), valid_ (valid), dm_ (0) + { + } + + virtual void + traverse_simple (semantics::data_member& m) + { + if (context::object_pointer (m.type ())) + { + semantics::data_member& dm (dm_ != 0 ? *dm_ : m); + + cerr << dm.file () << ":" << dm.line () << ":" << dm.column () << ":" + << " error: view data member '" << member_prefix_ << m.name () + << "' is an object pointer" << endl; + + cerr << dm.file () << ":" << dm.line () << ":" << dm.column () << ":" + << ": info: views cannot contain object pointers" << endl; + + valid_ = false; + } + } + + virtual void + traverse_container (semantics::data_member& m, semantics::type&) + { + semantics::data_member& dm (dm_ != 0 ? *dm_ : m); + + cerr << dm.file () << ":" << dm.line () << ":" << dm.column () << ":" + << " error: view data member '" << member_prefix_ << m.name () + << "' is a container" << endl; + + cerr << dm.file () << ":" << dm.line () << ":" << dm.column () << ":" + << ": info: views cannot contain containers" << endl; + + valid_ = false; + } + + virtual void + traverse_composite (semantics::data_member* m, semantics::class_& c) + { + semantics::data_member* old_dm (dm_); + + if (dm_ == 0) + dm_ = m; + + object_members_base::traverse_composite (m, c); + + dm_ = old_dm; + } + + private: + bool& valid_; + semantics::data_member* dm_; // Direct view data member. + }; + + // + // + struct class2: traversal::class_ + { + class2 (bool& valid, options const& ops, semantics::unit& unit) + : valid_ (valid), options_ (ops), unit_ (unit), view_members_ (valid) + { + } + + virtual void + traverse (type& c) + { + if (context::object (c)) + traverse_object (c); + else if (context::view (c)) + traverse_view (c); + else if (context::composite (c)) + traverse_composite (c); + } + + virtual void + traverse_object (type&) + { + } + + virtual void + traverse_view (type& c) + { + // Make sure we don't have any containers or object pointers. + // + view_members_.traverse (c); + } + + virtual void + traverse_composite (type&) + { + } + + bool& valid_; + options const& options_; + semantics::unit& unit_; + + view_members view_members_; }; } bool validator:: -validate (options const& ops, semantics::unit& u, semantics::path const&) +validate (options const& ops, + semantics::unit& u, + semantics::path const&, + unsigned short pass) { auto_ptr ctx (create_context (cerr, u, ops)); bool valid (true); - traversal::unit unit; - traversal::defines unit_defines; - traversal::declares unit_declares; - traversal::namespace_ ns; - value_type vt (valid); - class_ c (valid, ops, u, vt); + if (pass == 1) + { + traversal::unit unit; + traversal::defines unit_defines; + traversal::declares unit_declares; + traversal::namespace_ ns; + value_type vt (valid); + class1 c (valid, ops, u, vt); + + unit >> unit_defines >> ns; + unit_defines >> c; + unit >> unit_declares >> vt; + + traversal::defines ns_defines; + traversal::declares ns_declares; - unit >> unit_defines >> ns; - unit_defines >> c; - unit >> unit_declares >> vt; + ns >> ns_defines >> ns; + ns_defines >> c; + ns >> ns_declares >> vt; - traversal::defines ns_defines; - traversal::declares ns_declares; + unit.dispatch (u); + } + else + { + traversal::unit unit; + traversal::defines unit_defines; + traversal::namespace_ ns; + value_type vt (valid); + class2 c (valid, ops, u); + + unit >> unit_defines >> ns; + unit_defines >> c; - ns >> ns_defines >> ns; - ns_defines >> c; - ns >> ns_declares >> vt; + traversal::defines ns_defines; - unit.dispatch (u); + ns >> ns_defines >> ns; + ns_defines >> c; + + unit.dispatch (u); + } return valid; } diff --git a/odb/validator.hxx b/odb/validator.hxx index efb01d3..370e5e0 100644 --- a/odb/validator.hxx +++ b/odb/validator.hxx @@ -12,8 +12,13 @@ class validator { public: + // The first pass is performed before processing. The second -- after. + // bool - validate (options const&, semantics::unit&, semantics::path const&); + validate (options const&, + semantics::unit&, + semantics::path const&, + unsigned short pass); validator () {} -- cgit v1.1