aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-06-16 09:20:40 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-06-16 09:20:40 +0200
commitbc6e269d1221f27d239044b376cc2c6e36dd1428 (patch)
treea8808c5e0e644112a7c9388ab9ae0cfbc62eb6c9
parentf88e9b93fd99b89e30ef702273f8272a2c8866ce (diff)
Diagnose forward use of composite object ids
-rw-r--r--odb/context.cxx17
-rw-r--r--odb/context.hxx8
-rw-r--r--odb/include.cxx2
-rw-r--r--odb/validator.cxx32
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) << "' "