aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-07-24 14:52:31 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-07-24 14:52:31 +0200
commitac83439900ab5ed4febe68375d3936ae2a59d707 (patch)
tree705d6930ee10d1963f8061da0d64bd45f6301a10
parent81ea37904e4959414b53b225b4b5e56e1b561bdc (diff)
Allow pragmas to be either overriding or accumulating
-rw-r--r--odb/parser.cxx82
-rw-r--r--odb/pragma.cxx5
-rw-r--r--odb/pragma.hxx20
3 files changed, 66 insertions, 41 deletions
diff --git a/odb/parser.cxx b/odb/parser.cxx
index 5f42d5e..105333d 100644
--- a/odb/parser.cxx
+++ b/odb/parser.cxx
@@ -7,6 +7,7 @@
#include <set>
#include <map>
+#include <vector>
#include <string>
#include <cassert>
#include <sstream>
@@ -110,6 +111,8 @@ private:
//
// Pragma handling.
//
+ void
+ add_pragma (node&, pragma const&);
// Process positioned and named pragmas.
//
@@ -1876,26 +1879,7 @@ process_pragmas (tree t,
// Finally, copy the resulting pragma set to context.
//
for (pragma_set::iterator i (prags.begin ()); i != prags.end (); ++i)
- {
- if (trace)
- ts << "\t\t pragma " << i->name << " (" << i->value << ")"
- << endl;
-
- // Convert '_' to '-' in the pragma name so we get foo-bar instead
- // of foo_bar (that's the convention used).
- //
- string tmp (i->name);
- for (size_t j (0); j < tmp.size (); ++j)
- if (tmp[j] == '_')
- tmp[j] = '-';
-
- node.set (tmp, i->value);
-
- if (i->node != 0)
- node.set (tmp + "-node", i->node);
-
- node.set (tmp + "-loc", i->loc);
- }
+ add_pragma (node, *i);
}
void parser::impl::
@@ -1911,25 +1895,55 @@ process_named_pragmas (tree t, node& node)
// Copy the resulting pragma set to context.
//
for (pragma_set::iterator i (prags.begin ()); i != prags.end (); ++i)
- {
- if (trace)
- ts << "\t\t pragma " << i->name << " (" << i->value << ")"
- << endl;
+ add_pragma (node, *i);
+}
- // Convert '_' to '-' in the pragma name so we get foo-bar instead
- // of foo_bar (that's the convention used).
+void parser::impl::
+add_pragma (node& n, pragma const& p)
+{
+ if (trace)
+ ts << "\t\t pragma " << p.name << " (" << p.value << ")" << endl;
+
+ // Convert '_' to '-' in the pragma name so we get foo-bar instead
+ // of foo_bar (that's the convention used).
+ //
+ string kv (p.name);
+ for (size_t i (0); i < kv.size (); ++i)
+ if (kv[i] == '_')
+ kv[i] = '-';
+
+ string kl (kv + "-loc");
+ string kn (kv + "-node");
+
+ if (p.mode == pragma::override)
+ {
+ n.set (kv, p.value);
+ n.set (kn, p.node);
+ n.set (kl, p.loc);
+ }
+ else
+ {
+ // Having three parallel vectors is not the most efficient
+ // way to store this, but it is quite simple.
//
- string tmp (i->name);
- for (size_t j (0); j < tmp.size (); ++j)
- if (tmp[j] == '_')
- tmp[j] = '-';
+ typedef vector<string> values;
+ typedef vector<tree> nodes;
+ typedef vector<location_t> locations;
- node.set (tmp, i->value);
+ if (!n.count (kv))
+ {
+ n.set (kv, values ());
+ n.set (kn, nodes ());
+ n.set (kl, locations ());
+ }
- if (i->node != 0)
- node.set (tmp + "-node", i->node);
+ values& vs (n.get<values> (kv));
+ nodes& ns (n.get<nodes> (kn));
+ locations& ls (n.get<locations> (kl));
- node.set (tmp + "-loc", i->loc);
+ vs.push_back (p.value);
+ ns.push_back (p.node);
+ ls.push_back (p.loc);
}
}
diff --git a/odb/pragma.cxx b/odb/pragma.cxx
index a77cf48..6e1ecfa 100644
--- a/odb/pragma.cxx
+++ b/odb/pragma.cxx
@@ -272,6 +272,7 @@ handle_pragma (cpp_reader* reader,
string val;
tree node (0);
location_t loc (input_location);
+ pragma::mode_type mode (pragma::override);
if (p == "table")
{
@@ -794,7 +795,7 @@ handle_pragma (cpp_reader* reader,
// Record this pragma.
//
- pragma prag (p, val, node, loc);
+ pragma prag (mode, p, val, node, loc);
if (decl)
decl_pragmas_[decl].insert (prag);
@@ -989,7 +990,7 @@ handle_pragma_qualifier (cpp_reader* reader, string const& p)
// Record this pragma.
//
- pragma prag (p, "", 0, loc);
+ pragma prag (pragma::override, p, "", 0, loc);
if (decl)
decl_pragmas_[decl].insert (prag);
diff --git a/odb/pragma.hxx b/odb/pragma.hxx
index d8c4ab5..1fc034a 100644
--- a/odb/pragma.hxx
+++ b/odb/pragma.hxx
@@ -15,17 +15,27 @@
struct pragma
{
- pragma (std::string const& n, std::string const& v, tree tn, location_t l)
- : name (n), value (v), node (tn), loc (l)
+ enum mode_type {override, accumulate};
+
+ pragma (mode_type m,
+ std::string const& n,
+ std::string const& v,
+ tree tn,
+ location_t l)
+ : mode (m), name (n), value (v), node (tn), loc (l)
{
}
bool
operator< (pragma const& y) const
{
- return name < y.name;
+ if (mode == override)
+ return name < y.name;
+ else
+ return name < y.name || (name == y.name && loc < y.loc);
}
+ mode_type mode;
std::string name;
std::string value;
tree node;
@@ -34,8 +44,8 @@ struct pragma
typedef std::vector<pragma> pragma_list;
-// A set of pragmas. Insertion of a pragma with the same name
-// overrides the old value.
+// A set of pragmas. Insertion of a pragma with the same name and override
+// mode overrides the old value.
//
struct pragma_set: std::set<pragma>
{