From 759c865ebbdf8401e58ef5df705f9d1ad3d83cc9 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 22 Nov 2010 14:18:40 +0200 Subject: Implement support for one-to-{one,many} inverse relationships New pragma: inverse. --- odb/type-processor.cxx | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) (limited to 'odb/type-processor.cxx') diff --git a/odb/type-processor.cxx b/odb/type-processor.cxx index 9de59b4..fcdb3eb 100644 --- a/odb/type-processor.cxx +++ b/odb/type-processor.cxx @@ -421,6 +421,7 @@ namespace // element type and see if it is an object. // using semantics::class_; + using semantics::data_member; tree inst (instantiate_template (pointer_traits_, t.tree_node ())); @@ -449,16 +450,52 @@ namespace throw; } - if (class_* c = dynamic_cast (unit.find (tn))) + class_* c (dynamic_cast (unit.find (tn))); + + if (c == 0 || !c->count ("object")) + return 0; + + m.set (kp + (kp.empty () ? "": "-") + "object-pointer", c); + + // See if this is the inverse side of a bidirectional relationship. + // If so, then resolve the member and cache it in the context. + // + if (m.count ("inverse")) { - if (c->count ("object")) + string name (m.get ("inverse")); + tree decl ( + lookup_qualified_name ( + tn, get_identifier (name.c_str ()), false, false)); + + if (decl == error_mark_node || TREE_CODE (decl) != FIELD_DECL) { - m.set (kp + (kp.empty () ? "": "-") + "object-pointer", c); - return c; + os << m.file () << ":" << m.line () << ":" << m.column () << ": " + << "error: unable to resolve data member '" << name << "' " + << "specified with '#pragma db inverse' in class '" + << c->fq_name () << "'" << endl; + throw generation_failed (); + } + + data_member* im (dynamic_cast (unit.find (decl))); + + if (im == 0) + { + os << m.file () << ":" << m.line () << ":" << m.column () << ": " + << "ice: unable to find semantic graph node corresponding to " + << "data member '" << name << "' in class '" << c->fq_name () + << "'" << endl; + throw generation_failed (); } + + // @@ Would be good to check that the other end is actually + // an object pointer and is not marked as inverse. But the + // other class may not have been processed yet. + // + m.remove ("inverse"); + m.set (kp + (kp.empty () ? "": "-") + "inverse", im); } - return 0; + return c; } tree -- cgit v1.1