aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-09-03 17:36:08 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-09-03 17:36:08 +0200
commit66f4084caafd3dc0fd74bf6a7f57b785a5a1e051 (patch)
treed09e60f2f9d74f0aba65b296705bb599a51f808e
parent106564592df2f75889d69614ad50ac5de3dd3cab (diff)
Diagnose base classes that are defined after us
This can happen with templates/CRP
-rw-r--r--odb/validator.cxx50
1 files changed, 48 insertions, 2 deletions
diff --git a/odb/validator.cxx b/odb/validator.cxx
index 6975736..51768a0 100644
--- a/odb/validator.cxx
+++ b/odb/validator.cxx
@@ -444,7 +444,54 @@ namespace
virtual void
traverse (type& c)
{
- switch (class_kind (c))
+ class_kind_type ck (class_kind (c));
+
+ if (ck != class_other)
+ {
+ for (type::inherits_iterator i (c.inherits_begin ());
+ i != c.inherits_end (); ++i)
+ {
+ type& b (i->base ());
+
+ if (class_kind (b) == class_other)
+ continue;
+
+ location_t cl;
+ location_t bl;
+
+ // If we are in the same file, then use real locations (as
+ // opposed to definition locations) since that's the order
+ // in which we will be generating the code.
+ //
+ if (class_file (c) == class_file (b))
+ {
+ cl = class_real_location (c);
+ bl = class_real_location (b);
+ }
+ else
+ {
+ cl = class_location (c);
+ bl = class_location (b);
+ }
+
+ if (cl < bl)
+ {
+ // We cannot use class_name() for b since it might not have
+ // yet been processed (tree-hint).
+ //
+ error (cl) << "base class " << b.name () << " must "
+ << "be defined before derived class " << class_name (c)
+ << endl;
+
+ info (bl) << "class " << b.name () << " is define here"
+ << endl;
+
+ valid_ = false;
+ }
+ }
+ }
+
+ switch (ck)
{
case class_object:
names (c);
@@ -1121,7 +1168,6 @@ namespace
}
}
-
virtual void
traverse (type& m)
{