aboutsummaryrefslogtreecommitdiff
path: root/odb/type-processor.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-11-22 14:18:40 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-11-22 14:18:40 +0200
commit759c865ebbdf8401e58ef5df705f9d1ad3d83cc9 (patch)
tree142b8b4f0ef70774632ae6e9254b9514ccbc8d29 /odb/type-processor.cxx
parent4a50c5a7e9976587569276c768f85ad481694e70 (diff)
Implement support for one-to-{one,many} inverse relationships
New pragma: inverse.
Diffstat (limited to 'odb/type-processor.cxx')
-rw-r--r--odb/type-processor.cxx47
1 files changed, 42 insertions, 5 deletions
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<class_*> (unit.find (tn)))
+ class_* c (dynamic_cast<class_*> (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<string> ("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<data_member*> (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