From a482f1c4dd4efab83d3b19309900f1cbf54383a5 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 15 Oct 2013 07:01:17 +0200 Subject: Automatically map C++11 enum classes (strong enums) --- odb/parser.cxx | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'odb/parser.cxx') diff --git a/odb/parser.cxx b/odb/parser.cxx index 14dd81a..140e09e 100644 --- a/odb/parser.cxx +++ b/odb/parser.cxx @@ -746,7 +746,7 @@ parse (tree global_scope, path const& main_file) define_fund (char_type_node); define_fund (wchar_type_node); - if (ops_.std () == cxx_version::cxx11) + if (ops_.std () >= cxx_version::cxx11) { define_fund (char16_type_node); define_fund (char32_type_node); @@ -1422,8 +1422,29 @@ emit_enum (tree e, e_node = &dynamic_cast (*n); else { - e_node = &unit_->new_node ( - file, line, clmn, e, TYPE_UNSIGNED (e) != 0); + e_node = &unit_->new_node (file, line, clmn, e); + + // Set the underlying type even for incomplete (forward-declared) enums. + // + tree ut (ENUM_UNDERLYING_TYPE (e)); + names* hint (unit_->find_hint (ut)); + integral_type* un = dynamic_cast ( + unit_->find (TYPE_MAIN_VARIANT (ut))); + + // For "old" enums GCC creates a distinct type node and the only way to + // get to one of the known integrals is via its name. + // + if (un == 0) + { + ut = TREE_TYPE (TYPE_NAME (ut)); + un = dynamic_cast (unit_->find (TYPE_MAIN_VARIANT (ut))); + } + + underlies& edge (unit_->new_edge (*un, *e_node)); + + if (hint != 0) + edge.hint (*hint); + unit_->insert (e, *e_node); } @@ -1459,9 +1480,17 @@ emit_enum (tree e, unit_->new_edge (*e_node, er_node); unit_->insert (decl, er_node); - // Inject enumerators into the outer scope. + // In C++11 the enumerators are always available in the enum's + // scope, even for old enums. + // + if (ops_.std () >= cxx_version::cxx11) + unit_->new_edge (*e_node, er_node, name, access::public_); + + // Inject enumerators into the outer scope unless this is an + // enum class. // - unit_->new_edge (*scope_, er_node, name, access); + if (UNSCOPED_ENUM_P (e)) + unit_->new_edge (*scope_, er_node, name, access); if (trace) ts << "\tenumerator " << name << " at " << file << ":" << line << endl; -- cgit v1.1