aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-07-31 12:16:55 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-07-31 12:16:55 +0200
commit4fcb4ae749b3cf40f24ab1b9ddeb58b3ae0600f7 (patch)
tree6b6ad35e6895b7f1e8e81984fadc43ebfabd163e
parent9c9b8f3a03951e1b7cc489ce0ec018a03520c039 (diff)
Add support for changing location that ODB views as class definition
This is useful for making third-party/system types into ODB composite value types. New pragma: definition. New test: common/definition.
-rw-r--r--odb/common.cxx2
-rw-r--r--odb/context.cxx15
-rw-r--r--odb/include.cxx26
-rw-r--r--odb/pragma.cxx16
4 files changed, 45 insertions, 14 deletions
diff --git a/odb/common.cxx b/odb/common.cxx
index 0edcb0d..81a416b 100644
--- a/odb/common.cxx
+++ b/odb/common.cxx
@@ -593,7 +593,7 @@ check (semantics::typedefs& t)
if (hint != &t)
return false;
- // And the pragma may have to be in the file we are compiling.
+ // And the definition may have to be in the file we are compiling.
//
if (!included_)
{
diff --git a/odb/context.cxx b/odb/context.cxx
index 693ada4..8335ec4 100644
--- a/odb/context.cxx
+++ b/odb/context.cxx
@@ -501,9 +501,18 @@ class_fq_name (semantics::class_& c)
semantics::path context::
class_file (semantics::class_& c)
{
- return c.is_a<semantics::class_instantiation> ()
- ? semantics::path (LOCATION_FILE (c.get<location_t> ("location")))
- : c.file ();
+ // If we have an explicit definition location, use that.
+ //
+ if (c.count ("definition"))
+ return semantics::path (LOCATION_FILE (c.get<location_t> ("definition")));
+ //
+ // Otherwise, if it is a template instantiation, use the location
+ // of the qualifier.
+ //
+ else if (c.is_a<semantics::class_instantiation> ())
+ return semantics::path (LOCATION_FILE (c.get<location_t> ("location")));
+ else
+ return c.file ();
}
string context::
diff --git a/odb/include.cxx b/odb/include.cxx
index ca7e2aa..3d17b9a 100644
--- a/odb/include.cxx
+++ b/odb/include.cxx
@@ -84,7 +84,8 @@ namespace
// Not interested in classes that we are generating.
//
- // If this is a class template instantiation, then get the file
+ // If we have an explicit definition location, use that. Otherwise,
+ // if this is a class template instantiation, then get the file
// corresponding to the pragma, not the instantiation itself,
// since that's where we are generation the code for this class.
// While at it, also get the location.
@@ -94,7 +95,12 @@ namespace
path f;
location_t l;
- if (c.is_a<semantics::class_instantiation> ())
+ if (c.count ("definition"))
+ {
+ l = c.get<location_t> ("definition");
+ f = path (LOCATION_FILE (l));
+ }
+ else if (c.is_a<semantics::class_instantiation> ())
{
l = c.get<location_t> ("location");
f = path (LOCATION_FILE (l));
@@ -104,18 +110,21 @@ namespace
f = c.file ();
tree decl (TYPE_NAME (c.tree_node ()));
l = DECL_SOURCE_LOCATION (decl);
- }
- if (f == unit.file ())
- {
// Any include directives that follow are trailing (specified at
// the end of the main file). Note that we ignore views in this
// test so if a file defines only views, then all includes will
// be treated as leading. This is ok since views cannot have
- // circular dependencies.
+ // circular dependencies. We also ignore overridden locations for
+ // the purpose of this test since they are not really in the file
+ // being compiled. We assume that any includes that come after
+ // such classes are still leading.
//
- trailing_ = true;
- return;
+ if (f == unit.file ())
+ {
+ trailing_ = true;
+ return;
+ }
}
// This is a persistent object or composite value type declared in
@@ -129,7 +138,6 @@ namespace
{
lm = INCLUDED_FROM (line_table, lm);
- path f (c.file ());
f.complete ();
f.normalize ();
diff --git a/odb/pragma.cxx b/odb/pragma.cxx
index abb6692..ffe711f 100644
--- a/odb/pragma.cxx
+++ b/odb/pragma.cxx
@@ -404,7 +404,8 @@ check_spec_decl_type (tree d,
p == "query" ||
p == "object" ||
p == "optimistic" ||
- p == "polymorphic")
+ p == "polymorphic" ||
+ p == "definition")
{
if (tc != RECORD_TYPE)
{
@@ -1162,6 +1163,19 @@ handle_pragma (cxx_lexer& l,
tt = l.next (tl, &tn);
}
+ else if (p == "definition")
+ {
+ // definition
+ //
+
+ // Make sure we've got the correct declaration type.
+ //
+ if (decl != 0 && !check_spec_decl_type (decl, decl_name, p, loc))
+ return;
+
+ val = l.location ();
+ tt = l.next (tl, &tn);
+ }
else if (p == "callback")
{
// callback (name)