diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2012-08-31 10:03:45 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2012-08-31 10:03:45 +0200 |
commit | c0957cfe1c73ecb6c96314e45e7d29b4199b20d6 (patch) | |
tree | 96a747f7196baa335cf83ff160527bb8333ca9e3 /odb/semantics/elements.cxx | |
parent | ed52acc5e65dd9ea2fb2d9c851c2faa61d5cb2d9 (diff) |
Add support for virtual data members
New test: common/virtual.
Diffstat (limited to 'odb/semantics/elements.cxx')
-rw-r--r-- | odb/semantics/elements.cxx | 84 |
1 files changed, 76 insertions, 8 deletions
diff --git a/odb/semantics/elements.cxx b/odb/semantics/elements.cxx index ddae187..367ccbd 100644 --- a/odb/semantics/elements.cxx +++ b/odb/semantics/elements.cxx @@ -9,8 +9,11 @@ #include <odb/cxx-lexer.hxx> #include <odb/semantics/elements.hxx> +#include <odb/semantics/namespace.hxx> #include <odb/semantics/unit.hxx> +using namespace std; + namespace semantics { // access @@ -319,6 +322,79 @@ namespace semantics return i != iterator_map_.end () ? i->second : names_.end (); } + static bool + is_base (type_id const& b, compiler::type_info const& d) + { + using compiler::type_info; + + for (type_info::base_iterator i (d.begin_base ()); + i != d.end_base (); ++i) + { + type_info const& ti (i->type_info ()); + + if (b == ti.type_id () || is_base (b, ti)) + return true; + } + + return false; + } + + names* scope:: + lookup (string const& name, + type_id const& ti, + unsigned int flags, + bool* hidden) const + { + names_iterator_pair p (find (name)); + names* r (0); + + for (names_const_iterator i (p.first); i != p.second; ++i) + { + type_id const& xti (typeid (i->named ())); + + // If types are equal, then we found a match. Also check if ti is + // a base type of xti. + // + if (xti == ti || is_base (ti, compiler::lookup (xti))) + { + if (r != 0) + { + // If both are namespaces, then the one is just an extension + // of the other. + // + if (!(r->named ().is_a<namespace_> () && + i->named ().is_a<namespace_> ())) + throw ambiguous (*r, *i); + } + else + r = &*i; + } + } + + if (r != 0) + return r; + + // If we found a name but the types didn't match, then bail out + // unless we want hidden names. + // + if (p.first != p.second) + { + if (hidden != 0) + *hidden = true; + + if ((flags & include_hidden) == 0) + return 0; + } + + // Look in the outer scope unless requested not to or if this is + // the global scope. + // + if ((flags & exclude_outer) == 0 && !global_scope ()) + return scope ().lookup (name, ti, flags, hidden); + + return 0; + } + void scope:: add_edge_left (names& e) { @@ -443,14 +519,6 @@ namespace semantics insert (ti); } - // virtual_data_member - // - { - type_info ti (typeid (virtual_data_member)); - ti.add_base (typeid (data_member)); - insert (ti); - } - // unsupported_type // { |