From 4f8832bc28718feae612a2c1ed79020d32709ee7 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 5 Mar 2012 16:07:28 +0200 Subject: Add support for specifying object/view pointer on namespace --- odb/pragma.cxx | 14 ++++++- odb/relational/processor.cxx | 95 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 97 insertions(+), 12 deletions(-) diff --git a/odb/pragma.cxx b/odb/pragma.cxx index d6043cc..080de98 100644 --- a/odb/pragma.cxx +++ b/odb/pragma.cxx @@ -456,8 +456,7 @@ check_spec_decl_type (tree d, return false; } } - else if (p == "pointer" || - p == "abstract" || + else if (p == "abstract" || p == "callback" || p == "query" || p == "object" || @@ -470,6 +469,17 @@ check_spec_decl_type (tree d, return false; } } + else if (p == "pointer") + { + // Table can be used for namespaces and classes (object or view). + // + if (tc != NAMESPACE_DECL && tc != RECORD_TYPE) + { + error (l) << "name '" << name << "' in db pragma " << p << " does " + << "not refer to a class" << endl; + return false; + } + } else if (p == "table") { // Table can be used for namespaces, members (container), and types diff --git a/odb/relational/processor.cxx b/odb/relational/processor.cxx index 0bede14..e354b0f 100644 --- a/odb/relational/processor.cxx +++ b/odb/relational/processor.cxx @@ -2153,21 +2153,96 @@ namespace relational } else { - // Use the default pointer. + // See if any of the namespaces containing this class specify + // a pointer. // - string const& p (options.default_pointer ()); - - if (p == "*") - ptr = type + "*"; - else + for (semantics::scope* s (&c.scope ());; s = &s->scope_ ()) { - ptr = p + "< " + type + " >"; - decl_name = p; + using semantics::namespace_; + + namespace_* ns (dynamic_cast (s)); + + if (ns == 0) + continue; // Some other scope. + + if (ns->extension ()) + ns = &ns->original (); + + if (!ns->count ("pointer")) + { + if (ns->global_scope ()) + break; + else + continue; + } + + class_pointer const& cp (ns->get ("pointer")); + string const& p (cp.name); + + // Namespace-specified pointer can only be '*' or are template. + // + if (p == "*") + ptr = type + "*"; + else if (p[p.size () - 1] == '*') + { + error (cp.loc) + << "name '" << p << "' specified with db pragma pointer " + << "at namespace level cannot be a raw pointer" << endl; + } + else if (p.find ('<') != string::npos) + { + error (cp.loc) + << "name '" << p << "' specified with db pragma pointer " + << "at namespace level cannot be a template-id" << endl; + } + else + { + // Resolve this name and make sure it is a template. + // + decl = resolve_name (p, cp.scope, true); + int tc (TREE_CODE (decl)); + + if (tc == TEMPLATE_DECL && DECL_CLASS_TEMPLATE_P (decl)) + { + ptr = p + "< " + type + " >"; + decl_name = p; + } + else + { + error (cp.loc) + << "name '" << p << "' specified with db pragma pointer " + << "does not name a template" << endl; + } + } + + if (ptr.empty ()) + throw operation_failed (); + + // Resolve scope is the scope of the pragma. + // + resolve_scope = cp.scope; + loc = cp.loc; + break; } - // Resolve scope is the scope of the class. + // Use the default pointer. // - resolve_scope = c.scope ().tree_node (); + if (ptr.empty ()) + { + string const& p (options.default_pointer ()); + + if (p == "*") + ptr = type + "*"; + else + { + ptr = p + "< " + type + " >"; + decl_name = p; + } + + // Resolve scope is the scope of the class. + // + resolve_scope = c.scope ().tree_node (); + } } // Check if we are using TR1. -- cgit v1.1