diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2024-04-30 14:35:45 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2024-04-30 14:35:45 +0200 |
commit | 2a8ca82757ddaafe72137171f560c12e6d009f1e (patch) | |
tree | 14c38c501296c733310a7a2efd3d760537607502 | |
parent | 617212e2dd92f1c7cae489a977d43b8a14f1c24b (diff) |
Fix Clang -Wno-undefined-var-template in dynamic multi-database support code
Note that after this change we can no longer support multi-file circular
dependencies in this mode since we need to generate extern template
declarations involving classes that may participate in the cycle (see now
excluded odb-tests/common/circular/multiple/).
-rw-r--r-- | odb-tests/build/root.build | 18 | ||||
-rw-r--r-- | odb-tests/common/circular/buildfile | 9 | ||||
-rw-r--r-- | odb/odb/common-query.cxx | 41 | ||||
-rw-r--r-- | odb/odb/context.cxx | 9 |
4 files changed, 50 insertions, 27 deletions
diff --git a/odb-tests/build/root.build b/odb-tests/build/root.build index 27552ac..41f0556 100644 --- a/odb-tests/build/root.build +++ b/odb-tests/build/root.build @@ -176,24 +176,6 @@ if! $skeleton } } - # @@ BUILD2 Clang issues the following warnings while compile the - # odb-generated headers: - # - # In file included from odb-tests/common/view/olv/test1-odb-sqlite.cxx:10: - # odb-tests/common/view/olv/test1-odb-sqlite.hxx:68:80: warning: instantiation of variable 'odb::query_columns<test1::object1, odb::id_common, odb::access::object_traits_impl< ::test1::object1, id_common>>::id' required here, but no definition is available [-Wundefined-var-template] - # 68 | id (query_columns< ::test1::object1, id_common, typename A::common_traits >::id, - # | ^ - # odb-tests/common/view/olv/test1-odb.hxx:91:21: note: forward declaration of template entity is here - # 91 | static id_type_ id; - # | ^ - # odb-tests/common/view/olv/test1-odb-sqlite.hxx:68:80: note: add an explicit instantiation declaration to suppress this warning if 'odb::query_columns<test1::object1, odb::id_common, odb::access::object_traits_impl< ::test1::object1, id_common>>::id' is explicitly instantiated in another translation unit - # 68 | id (query_columns< ::test1::object1, id_common, typename A::common_traits >::id, - # - # Note: -Wno-undefined-var-template is temporarily added to suppress them. - # - if ($cxx.id.type == 'clang') - cxx.coptions += -Wno-undefined-var-template - # Import odb that we are testing. # import! [metadata] odb = odb%exe{odb} diff --git a/odb-tests/common/circular/buildfile b/odb-tests/common/circular/buildfile new file mode 100644 index 0000000..2e793b9 --- /dev/null +++ b/odb-tests/common/circular/buildfile @@ -0,0 +1,9 @@ +# file : common/circular/buildfile +# license : GNU GPL v2; see accompanying LICENSE file + +./: {*/ -multiple/} + +# We cannot support this case in multi-database support since we need to +# generate extern template involving classes that participate in the cycle. +# +./: multiple/: include = (!$multi) diff --git a/odb/odb/common-query.cxx b/odb/odb/common-query.cxx index 517c92c..0b5d063 100644 --- a/odb/odb/common-query.cxx +++ b/odb/odb/common-query.cxx @@ -1031,14 +1031,30 @@ traverse (type& c) { // If we have the extern symbol, generate extern template declarations. // - if (!ext.empty ()) + // Without a declaration of explicit template instantiation Clang issues + // -Wundefined-var-template. Note that extern template is only available + // since C++11 and this only appears to be an issue in dynamic multi- + // database support for id_common. + // + // Note also that this break our support for multi-file circular + // dependencies (see odb-tests/common/circule/multiple/). + // + if (!ext.empty () || + (multi_dynamic && + db == database::common && + options.std () >= cxx_version::cxx11)) { bool has_ptr (has_a (c, test_pointer | exclude_base)); bool reuse_abst (abstract (c) && !polymorphic (c)); if (has_ptr || !reuse_abst) { - os << "#ifdef " << ext << endl + const string& guard ( + !ext.empty () + ? ext + : make_guard ("ODB_" + db.string () + "_QUERY_COLUMNS_DEF")); + + os << (!ext.empty () ? "#ifdef " : "#ifndef ") << guard << endl << endl; if (has_ptr) @@ -1055,7 +1071,7 @@ traverse (type& c) if (!reuse_abst) generate_inst (c); - os << "#endif // " << ext << endl + os << "#endif // " << guard << endl << endl; } } @@ -1128,7 +1144,7 @@ generate_inst (type& c) string const& type (class_fq_name (c)); // Explicit template instantiations. Here is what we need to - // instantiate + // instantiate: // // 1. Reuse inheritance bases all the way to the ultimate base. // Unlike poly inheritance, reuse inheritance uses the table @@ -1216,14 +1232,25 @@ generate_decl (type& c) // Do it before query_columns since the inheritance will trigger // instantiation and we won't be able to change visibility (GCC). // - if (obj_count != 0 && multi_dynamic && !ext.empty ()) + // See query_columns_type::traverse() for background. + // + if (obj_count != 0 && multi_dynamic && + (!ext.empty () || + (multi_dynamic && + db == database::common && + options.std () >= cxx_version::cxx11))) { - os << "#ifdef " << ext << endl + const string& guard ( + !ext.empty () + ? ext + : make_guard ("ODB_" + db.string () + "_QUERY_COLUMNS_DEF")); + + os << (!ext.empty () ? "#ifdef " : "#ifndef ") << guard << endl << endl; generate_inst (c); - os << "#endif // " << ext << endl + os << "#endif // " << guard << endl << endl; } diff --git a/odb/odb/context.cxx b/odb/odb/context.cxx index 13fc1b3..f678e64 100644 --- a/odb/odb/context.cxx +++ b/odb/odb/context.cxx @@ -2961,8 +2961,13 @@ strlit (string const& str) void context:: inst_header (bool decl, bool omit_exp) { - if (decl && !ext.empty ()) - os << ext << " "; + if (decl) + { + if (!ext.empty ()) + os << ext << " "; + else + os << "extern "; + } os << "template struct"; |