aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-04-25 18:30:45 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-04-25 19:25:48 +0200
commit2f1d254fb49e8cc8bd9ea2137758614e5825eaed (patch)
tree40e632c43b8ef470892b5ba3a0a9cbbcd9675cd1
parentc4af692746181b5bb0ac50489555341feefd943c (diff)
Add typedef hints, move hint map to semantics::unit
-rw-r--r--odb/parser.cxx33
-rw-r--r--odb/semantics/elements.hxx18
-rw-r--r--odb/semantics/unit.hxx19
3 files changed, 53 insertions, 17 deletions
diff --git a/odb/parser.cxx b/odb/parser.cxx
index c5397a1..9bd8abc 100644
--- a/odb/parser.cxx
+++ b/odb/parser.cxx
@@ -51,7 +51,6 @@ private:
};
typedef multiset<tree_decl> decl_set;
- typedef map<tree, names*> name_hint_map;
private:
void
@@ -168,7 +167,6 @@ private:
size_t error_;
decl_set decls_;
- name_hint_map name_hints_;
};
bool parser::impl::tree_decl::
@@ -428,10 +426,8 @@ emit_class (tree c, path const& file, size_t line, size_t clmn, bool stub)
// See if there is a name hint for this type.
//
- name_hint_map::const_iterator it (name_hints_.find (t));
-
- if (it != name_hints_.end ())
- edge.hint (*it->second);
+ if (names* hint = unit_->find_hint (t))
+ edge.hint (*hint);
if (trace)
{
@@ -582,10 +578,8 @@ emit_union (tree u, path const& file, size_t line, size_t clmn, bool stub)
// See if there is a name hint for this type.
//
- name_hint_map::const_iterator it (name_hints_.find (t));
-
- if (it != name_hints_.end ())
- edge.hint (*it->second);
+ if (names* hint = unit_->find_hint (t))
+ edge.hint (*hint);
if (trace)
{
@@ -959,15 +953,22 @@ emit_type_decl (tree decl)
type& node (emit_type (t, decl_access (decl), f, l, c));
typedefs& edge (unit_->new_edge<typedefs> (*scope_, node, name));
- if (name_hints_.find (t) != name_hints_.end ())
+ // Find our hint.
+ //
+ if (tree ot = DECL_ORIGINAL_TYPE (decl))
{
- cerr << f << ':' << l << ':' << c << ": ice: "
- << " name hint already exist for tree node";
-
- throw failed ();
+ if (names* hint = unit_->find_hint (ot))
+ edge.hint (*hint);
}
- name_hints_[t] = &edge;
+ // Add this edge to the hint map. It may already be there if we
+ // are handling something like this:
+ //
+ // typedef foo bar;
+ // typedef bar foo;
+ //
+ if (unit_->find_hint (t) == 0)
+ unit_->insert_hint (t, edge);
if (trace)
{
diff --git a/odb/semantics/elements.hxx b/odb/semantics/elements.hxx
index b11211e..25b412a 100644
--- a/odb/semantics/elements.hxx
+++ b/odb/semantics/elements.hxx
@@ -223,9 +223,24 @@ namespace semantics
return access_;
}
+ // Names edge in terms of which this edge was defined. Can be NULL.
+ //
+ public:
+ void
+ hint (names& hint)
+ {
+ hint_ = &hint;
+ }
+
+ names*
+ hint () const
+ {
+ return hint_;
+ }
+
public:
names (string const& name, access_type access = access_type::public_)
- : name_ (name), access_ (access)
+ : name_ (name), access_ (access), hint_ (0)
{
}
@@ -246,6 +261,7 @@ namespace semantics
nameable* named_;
string name_;
access_type access_;
+ names* hint_;
};
//
diff --git a/odb/semantics/unit.hxx b/odb/semantics/unit.hxx
index 306d4c3..ac9f4f5 100644
--- a/odb/semantics/unit.hxx
+++ b/odb/semantics/unit.hxx
@@ -38,6 +38,22 @@ namespace semantics
tree_node_map_[key] = &value;
}
+ // Mapping from tree nodes to name hints.
+ //
+ public:
+ names*
+ find_hint (tree key) const
+ {
+ name_hint_map::const_iterator i (name_hint_map_.find (key));
+ return i != name_hint_map_.end () ? i->second : 0;
+ }
+
+ void
+ insert_hint (tree key, names& name)
+ {
+ name_hint_map_[key] = &name;
+ }
+
public:
template <class T>
T&
@@ -158,6 +174,9 @@ namespace semantics
typedef std::map<tree, node*> tree_node_map;
tree_node_map tree_node_map_;
+
+ typedef std::map<tree, names*> name_hint_map;
+ name_hint_map name_hint_map_;
};
}