summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2024-04-30 14:35:45 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2024-04-30 14:35:45 +0200
commit2a8ca82757ddaafe72137171f560c12e6d009f1e (patch)
tree14c38c501296c733310a7a2efd3d760537607502
parent617212e2dd92f1c7cae489a977d43b8a14f1c24b (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.build18
-rw-r--r--odb-tests/common/circular/buildfile9
-rw-r--r--odb/odb/common-query.cxx41
-rw-r--r--odb/odb/context.cxx9
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";