From 2b02d443ab344bc02dfc2891fb1a57c6520c393f Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 19 Aug 2010 17:05:24 +0200 Subject: Use type names as specified in the header that we compile --- odb/context.cxx | 2 +- odb/mysql/common.cxx | 5 +++- odb/mysql/header.cxx | 16 +++++------ odb/mysql/source.cxx | 4 +-- odb/parser.cxx | 36 ++++++++++++++++++++---- odb/semantics/elements.cxx | 64 +++++++++++++++++++++++++++++++++++++++++-- odb/semantics/elements.hxx | 28 +++++++++++++++++++ odb/semantics/fundamental.cxx | 9 ++++++ odb/semantics/fundamental.hxx | 3 ++ odb/tracer/header.cxx | 20 ++++++++------ odb/validator.cxx | 3 +- 11 files changed, 161 insertions(+), 29 deletions(-) diff --git a/odb/context.cxx b/odb/context.cxx index 77ca708..64d875d 100644 --- a/odb/context.cxx +++ b/odb/context.cxx @@ -162,7 +162,7 @@ column_type (semantics::data_member& m) const if (m.count ("type")) return m.get ("type"); - string const& name (m.type ().fq_name ()); + string const& name (m.type ().fq_name (m.belongs ().hint ())); type_map_type::const_iterator i (data_->type_map_.find (name)); if (i != data_->type_map_.end ()) diff --git a/odb/mysql/common.cxx b/odb/mysql/common.cxx index 011e510..d294527 100644 --- a/odb/mysql/common.cxx +++ b/odb/mysql/common.cxx @@ -198,7 +198,10 @@ namespace mysql void query_column:: pre (type& m) { - type_ = "mysql::value_traits< " + m.type ().fq_name () + " >::value_type"; + type_ = "mysql::value_traits< " + + m.type ().fq_name (m.belongs ().hint ()) + + " >::value_type"; + name_ = escape (public_name (m)); if (decl_) diff --git a/odb/mysql/header.cxx b/odb/mysql/header.cxx index 237cb85..bdb98a4 100644 --- a/odb/mysql/header.cxx +++ b/odb/mysql/header.cxx @@ -216,12 +216,6 @@ namespace mysql string const& type (c.fq_name ()); - // Find the id member and type. - // - id_member_.traverse (c); - semantics::data_member& id (*id_member_.member ()); - semantics::type& id_type (id.type ()); - member_count_.traverse (c); size_t column_count (member_count_.count ()); @@ -241,8 +235,14 @@ namespace mysql // id_type // - os << "typedef " << id_type.fq_name () << " id_type;" - << endl; + { + id_member_.traverse (c); + semantics::data_member& id (*id_member_.member ()); + + os << "typedef " << id.type ().fq_name (id.belongs ().hint ()) << + " id_type;" + << endl; + } // image_type // diff --git a/odb/mysql/source.cxx b/odb/mysql/source.cxx index 9cf69b1..1a9e6c8 100644 --- a/odb/mysql/source.cxx +++ b/odb/mysql/source.cxx @@ -353,7 +353,7 @@ namespace mysql virtual void pre (type& m) { - type = m.type ().fq_name (); + type = m.type ().fq_name (m.belongs ().hint ()); if (id_) member = "id"; @@ -516,7 +516,7 @@ namespace mysql virtual void pre (type& m) { - type = m.type ().fq_name (); + type = m.type ().fq_name (m.belongs ().hint ()); os << "// " << m.name () << endl << "//" << endl; diff --git a/odb/parser.cxx b/odb/parser.cxx index 1f7ba46..59c1046 100644 --- a/odb/parser.cxx +++ b/odb/parser.cxx @@ -6,6 +6,7 @@ #include // Keep it first. #include +#include #include #include #include @@ -49,6 +50,7 @@ private: }; typedef multiset decl_set; + typedef map name_hint_map; private: void @@ -149,6 +151,7 @@ private: size_t error_; decl_set decls_; + name_hint_map name_hints_; }; bool parser::impl::tree_decl:: @@ -376,8 +379,15 @@ emit_class (tree c, path const& file, size_t line, size_t clmn, bool stub) data_member& member_node ( unit_->new_node (file, line, clmn)); - unit_->new_edge (member_node, type_node); unit_->new_edge (*c_node, member_node, name, a); + belongs& edge (unit_->new_edge (member_node, type_node)); + + // 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 (trace) { @@ -514,8 +524,15 @@ emit_union (tree u, path const& file, size_t line, size_t clmn, bool stub) data_member& member_node ( unit_->new_node (file, line, clmn)); - unit_->new_edge (member_node, type_node); unit_->new_edge (*u_node, member_node, name, a); + belongs& edge (unit_->new_edge (member_node, type_node)); + + // 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 (trace) { @@ -868,15 +885,24 @@ emit_type_decl (tree decl) size_t c (DECL_SOURCE_COLUMN (decl)); type& node (emit_type (t, f, l, c)); - unit_->new_edge (*scope_, node, name); + typedefs& edge (unit_->new_edge (*scope_, node, name)); + + if (name_hints_.find (t) != name_hints_.end ()) + { + cerr << f << ':' << l << ':' << c << ": ice: " + << " name hint already exist for tree node"; + + throw failed (); + } + + name_hints_[t] = &edge; if (trace) { string s (emit_type_name (t, false)); ts << "typedef " << s << " (" << &node << ") -> " << name << " at " - << DECL_SOURCE_FILE (decl) << ":" - << DECL_SOURCE_LINE (decl) << endl; + << f << ":" << l << endl; } return 0; diff --git a/odb/semantics/elements.cxx b/odb/semantics/elements.cxx index 29b1f8e..a25df86 100644 --- a/odb/semantics/elements.cxx +++ b/odb/semantics/elements.cxx @@ -21,13 +21,73 @@ namespace semantics // nameable // + bool nameable:: + fq_anonymous () const + { + // Nameable is fq-anonymous if all the paths to the global scope + // have at least one anonymous link. + // + if (anonymous ()) + return true; + + if (named ().global_scope ()) + return false; + + if (defined_ != 0 && !defined_->scope ().fq_anonymous ()) + return false; + + for (names_list::const_iterator i (named_.begin ()), e (named_.end ()); + i != e; ++i) + { + if (!(*i)->scope ().fq_anonymous ()) + return false; + } + + return true; + } + + bool nameable:: + fq_anonymous (names* hint) const + { + if (hint == 0 && defined_ == 0) + return true; + + names& n (hint ? *hint : *defined_); + + if (n.global_scope ()) + return false; + + return n.scope ().fq_anonymous (); + } + string nameable:: fq_name () const { if (named ().global_scope ()) return ""; - else - return scope ().fq_name () + "::" + name (); + + if (defined_ != 0 && !defined_->scope ().fq_anonymous ()) + return defined_->scope ().fq_name () + "::" + name (); + + for (names_list::const_iterator i (named_.begin ()), e (named_.end ()); + i != e; ++i) + { + if (!(*i)->scope ().fq_anonymous ()) + return (*i)->scope ().fq_name () + "::" + name (); + } + + return ""; + } + + string nameable:: + fq_name (names* hint) const + { + names& n (hint ? *hint : *defined_); + + if (n.global_scope ()) + return ""; + + return n.scope ().fq_name () + "::" + n.name (); } // scope diff --git a/odb/semantics/elements.hxx b/odb/semantics/elements.hxx index 8d9a379..03925f5 100644 --- a/odb/semantics/elements.hxx +++ b/odb/semantics/elements.hxx @@ -276,6 +276,14 @@ namespace semantics return defined_ == 0 && named_.empty (); } + bool + fq_anonymous () const; + + // If hint it 0, use the defines edge. + // + bool + fq_anonymous (names* hint) const; + string name () const { @@ -285,6 +293,11 @@ namespace semantics virtual string fq_name () const; + // If hint it 0, use the defines edge. + // + virtual string + fq_name (names* hint) const; + scope_type& scope () const { @@ -494,7 +507,21 @@ namespace semantics } public: + void + hint (names& hint) + { + hint_ = &hint; + } + + names* + hint () const + { + return hint_; + } + + public: belongs () + : hint_ (0) { } @@ -513,6 +540,7 @@ namespace semantics private: type_type* type_; instance_type* instance_; + names* hint_; }; // diff --git a/odb/semantics/fundamental.cxx b/odb/semantics/fundamental.cxx index 7da222d..76efbe4 100644 --- a/odb/semantics/fundamental.cxx +++ b/odb/semantics/fundamental.cxx @@ -14,6 +14,15 @@ namespace semantics return name (); } + string fund_type:: + fq_name (names* hint) const + { + if (hint == 0) + return name (); + + return type::fq_name (hint); + } + // type info // namespace diff --git a/odb/semantics/fundamental.hxx b/odb/semantics/fundamental.hxx index cd68688..991bc54 100644 --- a/odb/semantics/fundamental.hxx +++ b/odb/semantics/fundamental.hxx @@ -19,6 +19,9 @@ namespace semantics virtual string fq_name () const; + virtual string + fq_name (names*) const; + protected: fund_type (tree tn) : type (tn) {} diff --git a/odb/tracer/header.cxx b/odb/tracer/header.cxx index 0516847..dee0498 100644 --- a/odb/tracer/header.cxx +++ b/odb/tracer/header.cxx @@ -28,13 +28,6 @@ namespace tracer string const& type (c.fq_name ()); - // Find the id member and type. - // - id_member t; - t.traverse (c); - semantics::data_member& id (*t.member ()); - semantics::type& id_type (id.type ()); - os << "// " << c.name () << endl << "//" << endl; @@ -51,8 +44,14 @@ namespace tracer // id_type // - os << "typedef " << id_type.fq_name () << " id_type;" - << endl; + { + id_member_.traverse (c); + semantics::data_member& id (*id_member_.member ()); + + os << "typedef " << id.type ().fq_name (id.belongs ().hint ()) << + " id_type;" + << endl; + } // type_name () // @@ -95,6 +94,9 @@ namespace tracer os << "};"; } + + private: + id_member id_member_; }; } diff --git a/odb/validator.cxx b/odb/validator.cxx index a834244..1acdea8 100644 --- a/odb/validator.cxx +++ b/odb/validator.cxx @@ -27,8 +27,9 @@ namespace count_++; semantics::type& type (m.type ()); + semantics::belongs& b (m.belongs ()); - if (type.anonymous ()) + if (type.fq_anonymous (m.belongs ().hint ())) { // Can be a template-id (which we should handle eventually) or an // anonymous type in member declaration (e.g., struct {...} m_;). -- cgit v1.1