From 4fcb4ae749b3cf40f24ab1b9ddeb58b3ae0600f7 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 31 Jul 2012 12:16:55 +0200 Subject: 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. --- odb/common.cxx | 2 +- odb/context.cxx | 15 ++++++++++++--- odb/include.cxx | 26 +++++++++++++++++--------- odb/pragma.cxx | 16 +++++++++++++++- 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::path (LOCATION_FILE (c.get ("location"))) - : c.file (); + // If we have an explicit definition location, use that. + // + if (c.count ("definition")) + return semantics::path (LOCATION_FILE (c.get ("definition"))); + // + // Otherwise, if it is a template instantiation, use the location + // of the qualifier. + // + else if (c.is_a ()) + return semantics::path (LOCATION_FILE (c.get ("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 ()) + if (c.count ("definition")) + { + l = c.get ("definition"); + f = path (LOCATION_FILE (l)); + } + else if (c.is_a ()) { l = c.get ("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) -- cgit v1.1