From 1f87ed70f983bc0fb920a0e1360de0977fe10c9f Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 28 Dec 2016 11:01:06 +0200 Subject: 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. --- odb/pragma.hxx | 52 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 20 deletions(-) (limited to 'odb/pragma.hxx') 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_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 +struct pragma_set: std::multimap { - typedef std::set base; + typedef std::multimap base; pragma& insert (pragma const& p) { - std::pair r (base::insert (p)); + std::string const& n (p.context_name); + std::pair r (equal_range (n)); + + iterator i (end ()); - pragma& x (const_cast (*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 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; } }; -- cgit v1.1