aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--odb/context.cxx64
-rw-r--r--odb/context.hxx43
-rw-r--r--odb/pragma.cxx40
-rw-r--r--odb/relational/mysql/context.cxx10
-rw-r--r--odb/relational/mysql/context.hxx5
-rw-r--r--odb/relational/mysql/schema.cxx18
-rw-r--r--odb/relational/mysql/source.cxx4
-rw-r--r--odb/relational/pgsql/context.cxx12
-rw-r--r--odb/relational/pgsql/context.hxx5
-rw-r--r--odb/relational/pgsql/source.cxx4
-rw-r--r--odb/relational/schema.hxx8
-rw-r--r--odb/relational/sqlite/context.cxx12
-rw-r--r--odb/relational/sqlite/context.hxx6
-rw-r--r--odb/relational/sqlite/source.cxx4
-rw-r--r--odb/relational/type-processor.cxx93
-rw-r--r--odb/validator.cxx83
16 files changed, 282 insertions, 129 deletions
diff --git a/odb/context.cxx b/odb/context.cxx
index 04761f8..520caea 100644
--- a/odb/context.cxx
+++ b/odb/context.cxx
@@ -145,6 +145,47 @@ context ()
context* context::current_;
+bool context::
+null (semantics::data_member& m)
+{
+ semantics::type& t (m.type ());
+
+ // By default pointers can be null.
+ //
+ if (object_pointer (t))
+ return m.count ("null") ||
+ (!m.count ("not-null") &&
+ (t.count ("null") || !t.count ("not-null")));
+ else
+ // Everything else by default is not null.
+ //
+ return m.count ("null") ||
+ (!m.count ("not-null") && t.count ("null"));
+}
+
+bool context::
+null (semantics::data_member& m, string const& kp)
+{
+ if (kp.empty ())
+ return null (m);
+
+ semantics::type& c (m.type ());
+ semantics::type& t (member_type (m, kp));
+
+ if (object_pointer (t))
+ return m.count (kp + "-null") ||
+ (!m.count (kp + "-not-null") &&
+ (c.count (kp + "-null") ||
+ (!c.count (kp + "-not-null") &&
+ (t.count ("null") || !t.count ("not-null")))));
+ else
+ return m.count (kp + "-null") ||
+ (!m.count (kp + "-not-null") &&
+ (c.count (kp + "-null") ||
+ (!c.count (kp + "-not-null") &&
+ t.count ("null"))));
+}
+
string context::
upcase (string const& s)
{
@@ -192,7 +233,7 @@ comp_value_ (semantics::class_& c)
{
bool r (true);
- //@@ This is bad. Did I add new value pragmas and forgot to
+ //@@ This is bad. Did we add new value pragmas and forgot to
// account for them here?
//
r = r && c.count ("value");
@@ -206,7 +247,10 @@ comp_value_ (semantics::class_& c)
r = r && !c.count ("index-column");
r = r && !c.count ("key-column");
r = r && !c.count ("id-column");
+ r = r && !c.count ("null");
r = r && !c.count ("not-null");
+ r = r && !c.count ("value-null");
+ r = r && !c.count ("value-not-null");
r = r && !c.count ("unordered");
c.set ("composite-value", r);
@@ -269,10 +313,7 @@ column_type (semantics::data_member& m, string const& kp)
}
string context::
-database_type_impl (semantics::type& t,
- semantics::names* hint,
- semantics::context& ctx,
- column_type_flags f)
+database_type_impl (semantics::type& t, semantics::names* hint, bool id)
{
type_map_type::const_iterator end (data_->type_map_.end ()), i (end);
@@ -293,16 +334,9 @@ database_type_impl (semantics::type& t,
i = data_->type_map_.find (t.fq_name ());
if (i != end)
- {
- string r (ctx.count ("id") ? i->second.id_type : i->second.type);
-
- if ((f & ctf_default_null) == 0)
- r += " NOT NULL";
-
- return r;
- }
-
- return string ();
+ return id ? i->second.id_type : i->second.type;
+ else
+ return string ();
}
static string
diff --git a/odb/context.hxx b/odb/context.hxx
index 54f6832..a256866 100644
--- a/odb/context.hxx
+++ b/odb/context.hxx
@@ -123,6 +123,12 @@ public:
return c.abstract () || c.count ("abstract");
}
+ bool
+ null (semantics::data_member&);
+
+ bool
+ null (semantics::data_member&, string const& key_prefix);
+
// Database names and types.
//
public:
@@ -225,23 +231,6 @@ public:
return pointer_kind (p) == pk_weak;
}
- bool
- null_pointer (semantics::data_member& m)
- {
- return !(m.count ("not-null") || m.type ().count ("not-null"));
- }
-
- bool
- null_pointer (semantics::data_member& m, string const& key_prefix)
- {
- if (key_prefix.empty ())
- return null_pointer (m);
-
- return !(m.count (key_prefix + "-not-null") ||
- m.type ().count ("not-null") ||
- member_type (m, key_prefix).count ("not-null"));
- }
-
semantics::data_member*
inverse (semantics::data_member& m)
{
@@ -441,33 +430,19 @@ public:
// Per-database customizable functionality.
//
protected:
- typedef unsigned short column_type_flags;
-
- static column_type_flags const ctf_none = 0;
-
- // Default type should be NULL-able.
- //
- static column_type_flags const ctf_default_null = 0x01;
-
// Return empty string if there is no mapping.
//
string
- database_type (semantics::type& t,
- semantics::names* hint,
- semantics::context& c,
- column_type_flags f)
+ database_type (semantics::type& t, semantics::names* hint, bool id)
{
- return current ().database_type_impl (t, hint, c, f);
+ return current ().database_type_impl (t, hint, id);
}
// The default implementation uses the type map (populated by the database-
// specific context implementation) to come up with a mapping.
//
virtual string
- database_type_impl (semantics::type&,
- semantics::names*,
- semantics::context&,
- column_type_flags);
+ database_type_impl (semantics::type&, semantics::names*, bool);
public:
typedef context root_context;
diff --git a/odb/pragma.cxx b/odb/pragma.cxx
index 3b8d222..8408489 100644
--- a/odb/pragma.cxx
+++ b/odb/pragma.cxx
@@ -198,9 +198,13 @@ check_decl_type (tree d, string const& name, string const& p, location_t l)
return false;
}
}
- else if (p == "not_null")
+ else if (p == "null" ||
+ p == "not_null" ||
+ p == "value_null" ||
+ p == "value_not_null")
{
- // Not_null can be used for both members and types (container or pointer).
+ // Null pragmas can be used for both members and types (values,
+ // containers, and pointers).
//
if (tc != FIELD_DECL && !TYPE_P (d))
{
@@ -518,9 +522,15 @@ handle_pragma (cpp_reader* reader,
tt = pragma_lex (&t);
}
- else if (p == "not_null")
+ else if (p == "null" ||
+ p == "not_null" ||
+ p == "value_null" ||
+ p == "value_not_null")
{
+ // null
// not_null
+ // value_null
+ // value_not_null
//
// Make sure we've got the correct declaration type.
@@ -766,7 +776,10 @@ handle_pragma_qualifier (cpp_reader* reader, string const& p)
p == "index_type" ||
p == "key_type" ||
p == "table" ||
+ p == "null" ||
p == "not_null" ||
+ p == "value_null" ||
+ p == "value_not_null" ||
p == "inverse" ||
p == "unordered" ||
p == "transient")
@@ -903,12 +916,30 @@ handle_pragma_db_table (cpp_reader* reader)
}
extern "C" void
+handle_pragma_db_null (cpp_reader* reader)
+{
+ handle_pragma_qualifier (reader, "null");
+}
+
+extern "C" void
handle_pragma_db_not_null (cpp_reader* reader)
{
handle_pragma_qualifier (reader, "not_null");
}
extern "C" void
+handle_pragma_db_value_null (cpp_reader* reader)
+{
+ handle_pragma_qualifier (reader, "value_null");
+}
+
+extern "C" void
+handle_pragma_db_value_not_null (cpp_reader* reader)
+{
+ handle_pragma_qualifier (reader, "value_not_null");
+}
+
+extern "C" void
handle_pragma_db_inverse (cpp_reader* reader)
{
handle_pragma_qualifier (reader, "inverse");
@@ -945,7 +976,10 @@ register_odb_pragmas (void*, void*)
c_register_pragma_with_expansion ("db", "index_type", handle_pragma_db_itype);
c_register_pragma_with_expansion ("db", "key_type", handle_pragma_db_ktype);
c_register_pragma_with_expansion ("db", "table", handle_pragma_db_table);
+ c_register_pragma_with_expansion ("db", "null", handle_pragma_db_null);
c_register_pragma_with_expansion ("db", "not_null", handle_pragma_db_not_null);
+ c_register_pragma_with_expansion ("db", "value_null", handle_pragma_db_value_null);
+ c_register_pragma_with_expansion ("db", "value_not_null", handle_pragma_db_value_not_null);
c_register_pragma_with_expansion ("db", "inverse", handle_pragma_db_inverse);
c_register_pragma_with_expansion ("db", "unordered", handle_pragma_db_unordered);
c_register_pragma_with_expansion ("db", "transient", handle_pragma_db_transient);
diff --git a/odb/relational/mysql/context.cxx b/odb/relational/mysql/context.cxx
index e9446c2..431470a 100644
--- a/odb/relational/mysql/context.cxx
+++ b/odb/relational/mysql/context.cxx
@@ -234,12 +234,9 @@ namespace relational
}
string context::
- database_type_impl (semantics::type& t,
- semantics::names* hint,
- semantics::context& ctx,
- column_type_flags f)
+ database_type_impl (semantics::type& t, semantics::names* hint, bool id)
{
- string r (base_context::database_type_impl (t, hint, ctx, f));
+ string r (base_context::database_type_impl (t, hint, id));
if (!r.empty ())
return r;
@@ -290,9 +287,6 @@ namespace relational
if (e->unsigned_ ())
r += " UNSIGNED";
}
-
- if ((f & ctf_default_null) == 0)
- r += " NOT NULL";
}
return r;
diff --git a/odb/relational/mysql/context.hxx b/odb/relational/mysql/context.hxx
index 019b878..00ebe57 100644
--- a/odb/relational/mysql/context.hxx
+++ b/odb/relational/mysql/context.hxx
@@ -97,10 +97,7 @@ namespace relational
protected:
virtual string
- database_type_impl (semantics::type&,
- semantics::names*,
- semantics::context&,
- column_type_flags);
+ database_type_impl (semantics::type&, semantics::names*, bool);
public:
virtual
diff --git a/odb/relational/mysql/schema.cxx b/odb/relational/mysql/schema.cxx
index 0b44c53..3848c75 100644
--- a/odb/relational/mysql/schema.cxx
+++ b/odb/relational/mysql/schema.cxx
@@ -37,11 +37,27 @@ namespace relational
}
};
- struct object_columns: relational::object_columns
+ struct object_columns: relational::object_columns, context
{
object_columns (base const& x): base (x) {}
virtual void
+ null (semantics::data_member& m)
+ {
+ if (!context::null (m, prefix_))
+ os << " NOT NULL";
+ else
+ {
+ // MySQL TIMESTAMP is by default NOT NULL. If we want it
+ // to contain NULL values, we need to explicitly declare
+ // the column as NULL.
+ //
+ if (column_sql_type (m, prefix_).type == sql_type::TIMESTAMP)
+ os << " NULL";
+ }
+ }
+
+ virtual void
constraints (semantics::data_member& m)
{
base::constraints (m);
diff --git a/odb/relational/mysql/source.cxx b/odb/relational/mysql/source.cxx
index 17bffdc..d3b4129 100644
--- a/odb/relational/mysql/source.cxx
+++ b/odb/relational/mysql/source.cxx
@@ -588,7 +588,7 @@ namespace relational
{
os << "}";
- if (!null_pointer (mi.m, key_prefix_))
+ if (!null (mi.m, key_prefix_))
os << "else" << endl
<< "throw null_pointer ();";
}
@@ -786,7 +786,7 @@ namespace relational
<< endl
<< "if (i." << mi.var << "null)" << endl;
- if (null_pointer (mi.m, key_prefix_))
+ if (null (mi.m, key_prefix_))
os << member << " = ptr_traits::pointer_type ();";
else
os << "throw null_pointer ();";
diff --git a/odb/relational/pgsql/context.cxx b/odb/relational/pgsql/context.cxx
index 5a6b158..6c6c5a0 100644
--- a/odb/relational/pgsql/context.cxx
+++ b/odb/relational/pgsql/context.cxx
@@ -211,12 +211,9 @@ namespace relational
}
string context::
- database_type_impl (semantics::type& t,
- semantics::names* hint,
- semantics::context& ctx,
- column_type_flags f)
+ database_type_impl (semantics::type& t, semantics::names* hint, bool id)
{
- string r (base_context::database_type_impl (t, hint, ctx, f));
+ string r (base_context::database_type_impl (t, hint, id));
if (!r.empty ())
return r;
@@ -224,13 +221,8 @@ namespace relational
using semantics::enum_;
if (t.is_a<semantics::enum_> ())
- {
r = "INTEGER";
- if ((f & ctf_default_null) == 0)
- r += " NOT NULL";
- }
-
return r;
}
diff --git a/odb/relational/pgsql/context.hxx b/odb/relational/pgsql/context.hxx
index 66d9318..a4fbc00 100644
--- a/odb/relational/pgsql/context.hxx
+++ b/odb/relational/pgsql/context.hxx
@@ -85,10 +85,7 @@ namespace relational
protected:
virtual string
- database_type_impl (semantics::type& t,
- semantics::names* hint,
- semantics::context& ctx,
- column_type_flags f);
+ database_type_impl (semantics::type& t, semantics::names* hint, bool);
public:
virtual
diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx
index 0ed6890..3b7664d 100644
--- a/odb/relational/pgsql/source.cxx
+++ b/odb/relational/pgsql/source.cxx
@@ -502,7 +502,7 @@ namespace relational
{
os << "}";
- if (!null_pointer (mi.m, key_prefix_))
+ if (!null (mi.m, key_prefix_))
os << "else" << endl
<< "throw null_pointer ();";
}
@@ -674,7 +674,7 @@ namespace relational
<< endl
<< "if (i." << mi.var << "null)" << endl;
- if (null_pointer (mi.m, key_prefix_))
+ if (null (mi.m, key_prefix_))
os << member << " = ptr_traits::pointer_type ();";
else
os << "throw null_pointer ();";
diff --git a/odb/relational/schema.hxx b/odb/relational/schema.hxx
index b9243df..9d64276 100644
--- a/odb/relational/schema.hxx
+++ b/odb/relational/schema.hxx
@@ -189,6 +189,7 @@ namespace relational
os << " " << quote_id (name) << " ";
type (m);
+ null (m);
constraints (m);
reference (m);
@@ -202,6 +203,13 @@ namespace relational
}
virtual void
+ null (semantics::data_member& m)
+ {
+ if (!context::null (m, prefix_))
+ os << " NOT NULL";
+ }
+
+ virtual void
constraints (semantics::data_member& m)
{
if (m.count ("id"))
diff --git a/odb/relational/sqlite/context.cxx b/odb/relational/sqlite/context.cxx
index b026822..4d00621 100644
--- a/odb/relational/sqlite/context.cxx
+++ b/odb/relational/sqlite/context.cxx
@@ -197,12 +197,9 @@ namespace relational
}
string context::
- database_type_impl (semantics::type& t,
- semantics::names* hint,
- semantics::context& ctx,
- column_type_flags f)
+ database_type_impl (semantics::type& t, semantics::names* hint, bool id)
{
- string r (base_context::database_type_impl (t, hint, ctx, f));
+ string r (base_context::database_type_impl (t, hint, id));
if (!r.empty ())
return r;
@@ -210,13 +207,8 @@ namespace relational
using semantics::enum_;
if (t.is_a<semantics::enum_> ())
- {
r = "INTEGER";
- if ((f & ctf_default_null) == 0)
- r += " NOT NULL";
- }
-
return r;
}
diff --git a/odb/relational/sqlite/context.hxx b/odb/relational/sqlite/context.hxx
index c625069..b5c3d85 100644
--- a/odb/relational/sqlite/context.hxx
+++ b/odb/relational/sqlite/context.hxx
@@ -49,10 +49,8 @@ namespace relational
protected:
virtual string
- database_type_impl (semantics::type&,
- semantics::names*,
- semantics::context&,
- column_type_flags);
+ database_type_impl (semantics::type&, semantics::names*, bool);
+
public:
virtual
~context ();
diff --git a/odb/relational/sqlite/source.cxx b/odb/relational/sqlite/source.cxx
index 35a3246..6a99fc8 100644
--- a/odb/relational/sqlite/source.cxx
+++ b/odb/relational/sqlite/source.cxx
@@ -321,7 +321,7 @@ namespace relational
{
os << "}";
- if (!null_pointer (mi.m, key_prefix_))
+ if (!null (mi.m, key_prefix_))
os << "else" << endl
<< "throw null_pointer ();";
}
@@ -437,7 +437,7 @@ namespace relational
<< endl
<< "if (i." << mi.var << "null)" << endl;
- if (null_pointer (mi.m, key_prefix_))
+ if (null (mi.m, key_prefix_))
os << member << " = ptr_traits::pointer_type ();";
else
os << "throw null_pointer ();";
diff --git a/odb/relational/type-processor.cxx b/odb/relational/type-processor.cxx
index f7b0b2a..0f1c1d2 100644
--- a/odb/relational/type-processor.cxx
+++ b/odb/relational/type-processor.cxx
@@ -131,14 +131,7 @@ namespace relational
type = idt.get<string> ("type");
if (type.empty ())
- {
- column_type_flags f (ctf_none);
-
- if (null_pointer (m))
- f |= ctf_default_null;
-
- type = database_type (idt, id.belongs ().hint (), id, f);
- }
+ type = database_type (idt, id.belongs ().hint (), true);
}
else
{
@@ -149,12 +142,22 @@ namespace relational
type = t.get<string> ("type");
if (type.empty ())
- type = database_type (t, m.belongs ().hint (), m, ctf_none);
+ type = database_type (t, m.belongs ().hint (), m.count ("id"));
}
if (!type.empty ())
{
m.set ("column-type", type);
+
+ // Issue a warning if we are relaxing null-ness.
+ //
+ if (m.count ("null") && m.type ().count ("not-null"))
+ {
+ os << m.file () << ":" << m.line () << ":" << m.column () << ":"
+ << " warning: data member declared null while its type is "
+ << "declared not null" << endl;
+ }
+
return;
}
@@ -221,14 +224,7 @@ namespace relational
type = idt.get<string> ("type");
if (type.empty ())
- {
- column_type_flags f (ctf_none);
-
- if (null_pointer (m, prefix))
- f |= ctf_default_null;
-
- type = database_type (idt, id.belongs ().hint (), id, f);
- }
+ type = database_type (idt, id.belongs ().hint (), true);
}
else
{
@@ -236,7 +232,7 @@ namespace relational
type = t.get<string> ("type");
if (type.empty ())
- type = database_type (t, hint, m, ctf_none);
+ type = database_type (t, hint, false);
}
if (!type.empty ())
@@ -366,6 +362,10 @@ namespace relational
t.set ("container-kind", ck);
+ // Mark id column as not null.
+ //
+ t.set ("id-not-null", string ());
+
// Get the value type.
//
try
@@ -404,6 +404,33 @@ namespace relational
t.set ("value-tree-type", vt);
t.set ("value-tree-hint", vh);
+ // If we have a set container, automatically mark the value
+ // column as not null. If we already have an explicit null for
+ // this column, issue an error.
+ //
+ if (ck == ck_set)
+ {
+ if (t.count ("value-null"))
+ {
+ os << t.file () << ":" << t.line () << ":" << t.column () << ":"
+ << " error: set container cannot contain null values" << endl;
+
+ throw generation_failed ();
+ }
+ else
+ t.set ("value-not-null", string ());
+ }
+
+ // Issue a warning if we are relaxing null-ness in the
+ // container type.
+ //
+ if (t.count ("value-null") && vt->count ("not-null"))
+ {
+ os << t.file () << ":" << t.line () << ":" << t.column () << ":"
+ << " warning: container value declared null while its type "
+ << "is declared not null" << endl;
+ }
+
// Get the index type for ordered containers.
//
if (ck == ck_ordered)
@@ -443,6 +470,7 @@ namespace relational
t.set ("index-tree-type", it);
t.set ("index-tree-hint", ih);
+ t.set ("index-not-null", string ());
}
// Get the key type for maps.
@@ -484,6 +512,7 @@ namespace relational
t.set ("key-tree-type", kt);
t.set ("key-tree-hint", kh);
+ t.set ("key-not-null", string ());
}
}
@@ -507,6 +536,28 @@ namespace relational
if (ck == ck_ordered && m.count ("value-inverse"))
m.set ("unordered", string ()); // Keep compatible with pragma.
+ // Issue an error if we have a null column in a set container.
+ // This can only happen if the value is declared as null in
+ // the member.
+ //
+ if (ck == ck_set && m.count ("value-null"))
+ {
+ os << m.file () << ":" << m.line () << ":" << m.column () << ":"
+ << " error: set container cannot contain null values" << endl;
+
+ throw generation_failed ();
+ }
+
+ // Issue a warning if we are relaxing null-ness in the member.
+ //
+ if (m.count ("value-null") &&
+ (t.count ("value-not-null") || vt->count ("not-null")))
+ {
+ os << m.file () << ":" << m.line () << ":" << m.column () << ":"
+ << " warning: container value declared null while the container "
+ << "type or value type declares it as not null" << endl;
+ }
+
return true;
}
@@ -729,12 +780,6 @@ namespace relational
throw generation_failed ();
}
- if (m.count ("not-null") && !kp.empty ())
- {
- m.remove ("not-null");
- m.set (kp + "-not-null", string ()); // Keep compatible with pragma.
- }
-
// See if this is the inverse side of a bidirectional relationship.
// If so, then resolve the member and cache it in the context.
//
diff --git a/odb/validator.cxx b/odb/validator.cxx
index 487d69a..b07f5cd 100644
--- a/odb/validator.cxx
+++ b/odb/validator.cxx
@@ -15,6 +15,29 @@ using namespace std;
namespace
{
+ // Resolve null overrides.
+ //
+ static void
+ override_null (semantics::node& n, string const& prefix = "")
+ {
+ string p (prefix.empty () ? prefix : prefix + '-');
+
+ if (n.count (p + "null") && n.count (p + "not-null"))
+ {
+ if (n.get<location_t> (p + "null-loc") <
+ n.get<location_t> (p + "not-null-loc"))
+ {
+ n.remove (p + "null");
+ n.remove (p + "null-loc");
+ }
+ else
+ {
+ n.remove (p + "not-null");
+ n.remove (p + "not-null-loc");
+ }
+ }
+ }
+
struct data_member: traversal::data_member
{
data_member (bool& valid)
@@ -42,6 +65,11 @@ namespace
valid_ = false;
}
+
+ // Resolve null overrides.
+ //
+ override_null (m);
+ override_null (m, "value");
}
bool& valid_;
@@ -119,22 +147,44 @@ namespace
//
//
+ struct value_type: traversal::type
+ {
+ value_type (bool& valid): valid_ (valid) {}
+
+ virtual void
+ traverse (semantics::type& t)
+ {
+ // Resolve null overrides.
+ //
+ override_null (t);
+ override_null (t, "value");
+ }
+
+ bool& valid_;
+ };
+
+ //
+ //
struct class_: traversal::class_
{
- class_ (bool& valid, semantics::unit& unit)
- : valid_ (valid), unit_ (unit), member_ (valid)
+ class_ (bool& valid, semantics::unit& unit, value_type& vt)
+ : valid_ (valid), unit_ (unit), vt_ (vt), member_ (valid)
{
*this >> names_ >> member_;
}
-
virtual void
traverse (type& c)
{
if (c.count ("object"))
traverse_object (c);
- else if (context::comp_value (c))
- traverse_value (c);
+ else
+ {
+ if (context::comp_value (c))
+ traverse_value (c);
+
+ vt_.dispatch (c);
+ }
}
virtual void
@@ -234,8 +284,23 @@ namespace
}
}
else
+ {
c.set ("id-member", id);
+ // Automatically mark the id member as not null. If we already have
+ // an explicit null pragma for this member, issue an error.
+ //
+ if (id->count ("null"))
+ {
+ cerr << id->file () << ":" << id->line () << ":" << id->column ()
+ << ": error: object id member cannot be null" << endl;
+
+ valid_ = false;
+ }
+ else
+ id->set ("not-null", string ());
+ }
+
// Check members.
//
member_.count_ = 0;
@@ -317,6 +382,7 @@ namespace
bool& valid_;
semantics::unit& unit_;
+ value_type& vt_;
data_member member_;
traversal::names names_;
@@ -332,16 +398,21 @@ validate (options const&,
traversal::unit unit;
traversal::defines unit_defines;
+ traversal::declares unit_declares;
traversal::namespace_ ns;
- class_ c (valid, u);
+ value_type vt (valid);
+ class_ c (valid, u, vt);
unit >> unit_defines >> ns;
unit_defines >> c;
+ unit >> unit_declares >> vt;
traversal::defines ns_defines;
+ traversal::declares ns_declares;
ns >> ns_defines >> ns;
ns_defines >> c;
+ ns >> ns_declares >> vt;
unit.dispatch (u);