aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-03-05 16:07:28 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-03-05 16:07:28 +0200
commit4f8832bc28718feae612a2c1ed79020d32709ee7 (patch)
tree42378ab8b30c68773841900ee7d960a6ac9aba80
parentcd44a367fd73293b1c8edc36aa61667ca020a2eb (diff)
Add support for specifying object/view pointer on namespace
-rw-r--r--odb/pragma.cxx14
-rw-r--r--odb/relational/processor.cxx95
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<namespace_*> (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<class_pointer> ("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.