diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2012-10-02 16:06:56 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2012-10-02 16:06:56 +0200 |
commit | eac23648aea3c1aa547dd4bb9872948df49a065a (patch) | |
tree | 554783055991e5a56147661f490fdcfc196b2fe7 | |
parent | f4c702b57d6626c86795fb45d41ed652116aab5f (diff) |
Instantiate type of virtual data member with by-value accessor
-rw-r--r-- | odb/relational/processor.cxx | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/odb/relational/processor.cxx b/odb/relational/processor.cxx index 8ab9a1f..68e8ab6 100644 --- a/odb/relational/processor.cxx +++ b/odb/relational/processor.cxx @@ -746,19 +746,54 @@ namespace relational } // Check that the member type is default-constructible if we - // have a by value modifier. + // have a by value modifier. // if (k == "set" && ma.placeholder ()) { - // Assume all other types are default-constructible. - // semantics::class_* c (dynamic_cast<semantics::class_*> (&utype (m))); - if (c != 0 && !c->default_ctor ()) + // Assume all other types are default-constructible. + // + if (c != 0) { - error (ma.loc) << "modifier expression requires member type " - << "to be default-constructible" << endl; - throw operation_failed (); + // If this type is a class template instantiation, then make + // sure it is instantiated. While types used in real members + // will be instantiated, this is not necessarily the case for + // virtual members. Without the instantiation we won't be able + // to detect whether the type has the default ctor. + // + // It would have been cleaner to do it in post_process_pragmas() + // but there we don't yet know whether we need the default ctor. + // And it is a good idea not to require instantiability unless + // we really need it. + // + tree type (c->tree_node ()); + + if (!COMPLETE_TYPE_P (type) && + CLASSTYPE_TEMPLATE_INSTANTIATION (type)) + { + // Reset input location so that we get nice diagnostics in + // case of an error. Use the location of the virtual pragma. + // + location_t loc (m.get<location_t> ("virtual-location")); + input_location = loc; + + if (instantiate_class_template (type) == error_mark_node || + errorcount != 0 || + !COMPLETE_TYPE_P (type)) + { + error (loc) << "unable to instantiate virtual data member " << + "type" << endl; + throw operation_failed (); + } + } + + if (!c->default_ctor ()) + { + error (ma.loc) << "modifier expression requires member type " << + "to be default-constructible" << endl; + throw operation_failed (); + } } } } |