aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-12-28 11:01:06 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-12-28 11:01:06 +0200
commit1f87ed70f983bc0fb920a0e1360de0977fe10c9f (patch)
tree27a46e525d178b08ed6d0de66dace9368275ef2c
parentec777147024fde72e4411cc6b1e1e49f4a1d1804 (diff)
Fix GCC 6 issue with PRAGMA_DB macro
In GCC 6 we use the position of the macro expansion, not the position inside the macro itself. This means that multiple pragmas inside PRAGMA_DB will all have the same position which we were not handling properly.
-rw-r--r--odb/parser.cxx8
-rw-r--r--odb/pragma.cxx8
-rw-r--r--odb/pragma.hxx52
3 files changed, 40 insertions, 28 deletions
diff --git a/odb/parser.cxx b/odb/parser.cxx
index 6dfff6f..079f6f3 100644
--- a/odb/parser.cxx
+++ b/odb/parser.cxx
@@ -852,12 +852,12 @@ parse (tree global_scope, path const& main_file)
}
pragma_set& s (decl_pragmas_[ns]);
- pragma_set::iterator it (s.find (p));
+ pragma_set::iterator it (s.find (p.context_name));
// Make sure we override only if this pragma came after the one
// already in the set.
//
- if (it == s.end () || it->loc < p.loc)
+ if (it == s.end () || it->second.loc <= p.loc)
s.insert (p);
}
@@ -2179,7 +2179,7 @@ process_pragmas (declaration const& decl,
// Finally, copy the resulting pragma set to context.
//
for (pragma_set::iterator i (prags.begin ()); i != prags.end (); ++i)
- add_pragma (node, *i);
+ add_pragma (node, i->second);
}
void parser::impl::
@@ -2195,7 +2195,7 @@ process_named_pragmas (declaration const& decl, node& node)
// Copy the resulting pragma set to context.
//
for (pragma_set::iterator i (prags.begin ()); i != prags.end (); ++i)
- add_pragma (node, *i);
+ add_pragma (node, i->second);
}
void parser::impl::
diff --git a/odb/pragma.cxx b/odb/pragma.cxx
index 0c925ca..62d97b4 100644
--- a/odb/pragma.cxx
+++ b/odb/pragma.cxx
@@ -4391,23 +4391,23 @@ post_process_pragmas ()
for (pragma_set::iterator j (i->second.begin ()), e (i->second.end ());
j != e; ++j)
{
- string const& name (j->context_name);
+ string const& name (j->second.context_name);
if (name == "object")
{
- p = &*j;
+ p = &j->second;
diag_name = "persistent object";
break;
}
else if (name == "view")
{
- p = &*j;
+ p = &j->second;
diag_name = "view";
break;
}
else if (name == "value")
{
- p = &*j;
+ p = &j->second;
diag_name = "composite value";
break;
}
diff --git a/odb/pragma.hxx b/odb/pragma.hxx
index d6b0f42..f13c6e0 100644
--- a/odb/pragma.hxx
+++ b/odb/pragma.hxx
@@ -181,16 +181,6 @@ struct pragma
{
}
- bool
- operator< (pragma const& y) const
- {
- if (add == 0)
- return context_name < y.context_name;
- else
- return context_name < y.context_name ||
- (context_name == y.context_name && loc < y.loc);
- }
-
std::string pragma_name; // Actual pragma name for diagnostics.
std::string context_name; // Context entry name.
cutl::container::any value;
@@ -204,29 +194,51 @@ typedef std::vector<pragma> pragma_list;
// A set of pragmas. Insertion of a pragma with the same name and no
// custom add function overrides the old value.
//
-struct pragma_set: std::set<pragma>
+struct pragma_set: std::multimap<std::string, pragma>
{
- typedef std::set<pragma> base;
+ typedef std::multimap<std::string, pragma> base;
pragma&
insert (pragma const& p)
{
- std::pair<iterator, bool> r (base::insert (p));
+ std::string const& n (p.context_name);
+ std::pair<iterator, iterator> r (equal_range (n));
+
+ iterator i (end ());
- pragma& x (const_cast<pragma&> (*r.first));
+ if (p.add == 0)
+ {
+ if (r.first != r.second)
+ {
+ i = r.first;
+ assert (++r.first == r.second);
- if (!r.second)
- x = p;
+ i->second = p;
+ }
+ }
+ else if (r.first != r.second)
+ assert ((--r.second)->second.loc <= p.loc);
- return x;
+ if (i == end ())
+ i = base::insert (base::value_type (n, p));
+
+ return i->second;
}
- template <typename I>
void
- insert (I begin, I end)
+ insert (const_iterator begin, const_iterator end)
{
for (; begin != end; ++begin)
- insert (*begin);
+ insert (begin->second);
+ }
+
+ // Return the last pragma in the equal range which (by construction) has the
+ // location greater or equal to all the other pragmas in this range.
+ //
+ iterator
+ find (std::string const& n)
+ {
+ return equal_range (n).second;
}
};