diff options
-rw-r--r-- | odb/context.cxx | 17 | ||||
-rw-r--r-- | odb/context.hxx | 8 | ||||
-rw-r--r-- | odb/include.cxx | 2 | ||||
-rw-r--r-- | odb/validator.cxx | 32 |
4 files changed, 58 insertions, 1 deletions
diff --git a/odb/context.cxx b/odb/context.cxx index e6e50b8..726495f 100644 --- a/odb/context.cxx +++ b/odb/context.cxx @@ -1091,6 +1091,23 @@ class_file (semantics::class_& c) return c.file (); } +location_t context:: +class_location (semantics::class_& c) +{ + if (c.count ("definition")) + { + return c.get<location_t> ("definition"); + } + else if (c.is_a<semantics::class_instantiation> ()) + { + return c.get<location_t> ("location"); + } + else + { + return real_source_location (TYPE_NAME (c.tree_node ())); + } +} + string context:: upcase (string const& s) { diff --git a/odb/context.hxx b/odb/context.hxx index a3a58bf..57e50a7 100644 --- a/odb/context.hxx +++ b/odb/context.hxx @@ -1150,6 +1150,14 @@ public: static semantics::path class_file (semantics::class_&); + // Return the location (as location_t; useful for comparison) of + // an "ODB class" (i.e., an object, view, or composite value), + // taking into account things like definition point overrides, + // etc. + // + location_t + class_location (semantics::class_&); + // Database names and types. // public: diff --git a/odb/include.cxx b/odb/include.cxx index c397993..9c03f99 100644 --- a/odb/include.cxx +++ b/odb/include.cxx @@ -106,6 +106,8 @@ namespace path f; location_t l; + // Pretty much the same code as in context::class_location(). + // if (c.count ("definition")) { l = c.get<location_t> ("definition"); diff --git a/odb/validator.cxx b/odb/validator.cxx index 561d348..a843b59 100644 --- a/odb/validator.cxx +++ b/odb/validator.cxx @@ -1080,7 +1080,37 @@ namespace // Make sure the pointed-to class has object id unless it is in a // view where we can load no-id objects. // - if (id_member (*c) == 0 && !view_member (m)) + if (semantics::data_member* id = id_member (*c)) + { + semantics::type& idt (utype (*id)); + + // Make sure composite id is defined before this pointer. Failed + // that we get non-obvious C++ compiler errors in generated code. + // + using semantics::class_; + + if (class_* comp = composite_wrapper (idt)) + { + class_& s (dynamic_cast<class_&> (m.scope ())); + + location_t idl (class_location (*comp)); + location_t ml (class_location (s)); + + if (ml < idl) + { + error (m.location ()) + << "composite object id " << class_fq_name (*comp) << " of " + << "pointed-to class " << class_fq_name (*c) << " must be " + << "defined before the pointer" << endl; + + info (idl) + << "class " << class_name (*comp) << " is define here" << endl; + + valid_ = false; + } + } + } + else if (!view_member (m)) { os << m.file () << ":" << m.line () << ":" << m.column () << ": " << "error: pointed-to class '" << class_fq_name (*c) << "' " |