From bc6e269d1221f27d239044b376cc2c6e36dd1428 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 16 Jun 2015 09:20:40 +0200 Subject: Diagnose forward use of composite object ids --- odb/context.cxx | 17 +++++++++++++++++ odb/context.hxx | 8 ++++++++ odb/include.cxx | 2 ++ odb/validator.cxx | 32 +++++++++++++++++++++++++++++++- 4 files changed, 58 insertions(+), 1 deletion(-) 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 ("definition"); + } + else if (c.is_a ()) + { + return c.get ("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 ("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 (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) << "' " -- cgit v1.1