diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2012-01-08 17:27:40 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2012-01-08 17:27:40 +0200 |
commit | 4fd6bca4e75870958ea61b94e0a1e60e78cd91bc (patch) | |
tree | 2119cae72f45e1ceff1982d8364b4b678ac4ee69 | |
parent | 7cd11b5f604c7d786261568aa31cd2ae3638f61e (diff) |
Add support for defining composite value type as class template instantiations
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | doc/manual.xhtml | 49 | ||||
-rw-r--r-- | odb/common.cxx | 55 | ||||
-rw-r--r-- | odb/common.hxx | 21 | ||||
-rw-r--r-- | odb/context.cxx | 88 | ||||
-rw-r--r-- | odb/context.hxx | 25 | ||||
-rw-r--r-- | odb/include.cxx | 39 | ||||
-rw-r--r-- | odb/parser.cxx | 9 | ||||
-rw-r--r-- | odb/plugin.cxx | 12 | ||||
-rw-r--r-- | odb/pragma.cxx | 165 | ||||
-rw-r--r-- | odb/pragma.hxx | 14 | ||||
-rw-r--r-- | odb/relational/common.cxx | 8 | ||||
-rw-r--r-- | odb/relational/header.cxx | 8 | ||||
-rw-r--r-- | odb/relational/header.hxx | 62 | ||||
-rw-r--r-- | odb/relational/inline.cxx | 4 | ||||
-rw-r--r-- | odb/relational/inline.hxx | 37 | ||||
-rw-r--r-- | odb/relational/model.cxx | 4 | ||||
-rw-r--r-- | odb/relational/model.hxx | 14 | ||||
-rw-r--r-- | odb/relational/mysql/source.cxx | 4 | ||||
-rw-r--r-- | odb/relational/oracle/source.cxx | 4 | ||||
-rw-r--r-- | odb/relational/pgsql/source.cxx | 10 | ||||
-rw-r--r-- | odb/relational/processor.cxx | 39 | ||||
-rw-r--r-- | odb/relational/source.cxx | 6 | ||||
-rw-r--r-- | odb/relational/source.hxx | 44 | ||||
-rw-r--r-- | odb/relational/sqlite/source.cxx | 4 | ||||
-rw-r--r-- | odb/validator.cxx | 37 |
26 files changed, 588 insertions, 181 deletions
@@ -1,3 +1,10 @@ +Version 1.8.0 + + * Support for defining composite value types as C++ class template + instantiations. For more information, refer to Section 7.2, "Composite + Value Types" in the ODB manual as well as the 'composite' example in the + odb-examples package. + Version 1.7.0 * Support for the Oracle database. The provided connection factories diff --git a/doc/manual.xhtml b/doc/manual.xhtml index e21185b..ef36090 100644 --- a/doc/manual.xhtml +++ b/doc/manual.xhtml @@ -5665,7 +5665,7 @@ class basic_name </pre> <p>The complete version of the above code fragment and the other code - samples presented in this chapter can be found in the <code>composite</code> + samples presented in this section can be found in the <code>composite</code> example in the <code>odb-examples</code> package.</p> <p>A composite value type does not have to define a default constructor, @@ -5749,6 +5749,53 @@ class person }; </pre> + <p>A composite value type can also be defined as an instantiation + of a C++ class template, for example:</p> + +<pre class="c++"> +template <typename T> +struct point +{ + T x; + T y; + T z; +}; + +typedef point<int> int_point; +#pragma db value(int_point) + +#pragma db object +class object +{ + ... + + int_point center_; +}; +</pre> + + <p>Note that the database support code for such a composite value type + is generated when compiling the header containing the + <code>db value</code> pragma and not the header containing + the template definition or the <code>typedef</code> name. This + allows us to use templates defined in other files, such as + <code>std::pair</code> defined in the <code>utility</code> + standard header file:</p> + +<pre class="c++"> +#include <utility> // std::pair + +typedef std::pair<std::string, std::string> phone_numbers; +#pragma db value(phone_numbers) + +#pragma db object +class person +{ + ... + + phone_numbers phone_; +}; +</pre> + <p>We can also use data members from composite value types in database queries (<a href="#4">Chapter 4, "Querying the Database"</a>). For each composite value in a persistent class, the diff --git a/odb/common.cxx b/odb/common.cxx index 322a915..379c769 100644 --- a/odb/common.cxx +++ b/odb/common.cxx @@ -442,3 +442,58 @@ traverse (semantics::data_member& m) oc_.member_path_.pop_back (); } + +// +// typedefs +// + +void typedefs:: +traverse (semantics::typedefs& t) +{ + if (check (t)) + traversal::typedefs::traverse (t); +} + +bool typedefs:: +check (semantics::typedefs& t) +{ + // This typedef must be for a class template instantiation. + // + using semantics::class_instantiation; + class_instantiation* ci (dynamic_cast<class_instantiation*> (&t.type ())); + + if (ci == 0) + return false; + + // It must be a composite value. + // + if (!composite (*ci)) + return false; + + // This typedef name should be the one that was used in the pragma. + // + using semantics::names; + tree type (ci->get<tree> ("tree-node")); + + names* hint; + if (ci->count ("tree-hint")) + hint = ci->get<names*> ("tree-hint"); + else + { + hint = unit.find_hint (type); + ci->set ("tree-hint", hint); // Cache it. + } + + if (hint != &t) + return false; + + // And the pragma may have to be in the file we are compiling. + // + if (!included_) + { + if (class_file (*ci) != unit.file ()) + return false; + } + + return true; +} diff --git a/odb/common.hxx b/odb/common.hxx index 679e25c..f29eeca 100644 --- a/odb/common.hxx +++ b/odb/common.hxx @@ -250,4 +250,25 @@ private: traversal::inherits inherits_; }; +// Traverse composite values that are class template instantiations. +// +struct typedefs: traversal::typedefs, context +{ + typedefs (bool traverse_included) + : included_ (traverse_included) + { + } + + virtual void + traverse (semantics::typedefs&); + + // Returns true if we should traverse this typedef. + // + bool + check (semantics::typedefs&); + +private: + bool included_; +}; + #endif // ODB_COMMON_HXX diff --git a/odb/context.cxx b/odb/context.cxx index 532a6b7..267b233 100644 --- a/odb/context.cxx +++ b/odb/context.cxx @@ -3,11 +3,14 @@ // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC // license : GNU GPL v3; see accompanying LICENSE file +#include <odb/gcc.hxx> + #include <cctype> // std::toupper #include <cassert> #include <odb/context.hxx> #include <odb/common.hxx> +#include <odb/pragma.hxx> #include <odb/relational/mysql/context.hxx> #include <odb/relational/oracle/context.hxx> @@ -16,6 +19,23 @@ using namespace std; +// +// view_object +// + +string view_object:: +name () const +{ + if (!alias.empty ()) + return alias; + + return kind == object ? context::class_name (*obj) : orig_name; +} + +// +// context +// + namespace { char const* keywords[] = @@ -388,6 +408,30 @@ class_kind (semantics::class_& c) } string context:: +class_name (semantics::class_& c) +{ + return c.is_a<semantics::class_instantiation> () + ? c.get<semantics::names*> ("tree-hint")->name () + : c.name (); +} + +string context:: +class_fq_name (semantics::class_& c) +{ + return c.is_a<semantics::class_instantiation> () + ? c.fq_name (c.get<semantics::names*> ("tree-hint")) + : c.fq_name (); +} + +semantics::path context:: +class_file (semantics::class_& c) +{ + return c.is_a<semantics::class_instantiation> () + ? semantics::path (LOCATION_FILE (c.get<location_t> ("location"))) + : c.file (); +} + +string context:: upcase (string const& s) { string r; @@ -491,34 +535,20 @@ composite_ (semantics::class_& c) { bool r (true); - // List of pragmas that disqualify a value type from being treated as - // composite. - // - //@@ Did we add new simple value pragmas and forgot to account for - // them here? - // - r = r && c.count ("value"); - r = r && !c.count ("table"); - r = r && !c.count ("type"); - r = r && !c.count ("id-type"); - r = r && !c.count ("value-type"); - r = r && !c.count ("index-type"); - r = r && !c.count ("key-type"); - r = r && !c.count ("value-column"); - r = r && !c.count ("index-column"); - r = r && !c.count ("key-column"); - r = r && !c.count ("id-column"); - r = r && !c.count ("default"); - r = r && !c.count ("null"); - r = r && !c.count ("not-null"); - r = r && !c.count ("value-null"); - r = r && !c.count ("value-not-null"); - r = r && !c.count ("options"); - r = r && !c.count ("value-options"); - r = r && !c.count ("index-options"); - r = r && !c.count ("key-options"); - r = r && !c.count ("id-options"); - r = r && !c.count ("unordered"); + if (c.count ("value")) + { + for (pragma_name_set::const_iterator i (simple_value_pragmas_.begin ()), + e (simple_value_pragmas_.end ()); i != e; ++i) + { + if (c.count (*i)) + { + r = false; + break; + } + } + } + else + r = false; c.set ("composite-value", r); return r; @@ -532,7 +562,7 @@ table_name (semantics::class_& c) const if (c.count ("table")) name += c.get<string> ("table"); else - name += c.name (); + name += class_name (c); return name; } diff --git a/odb/context.hxx b/odb/context.hxx index 3be05a9..919e880 100644 --- a/odb/context.hxx +++ b/odb/context.hxx @@ -132,13 +132,7 @@ struct view_object // Return an alias or unqualified object name. // std::string - name () const - { - if (!alias.empty ()) - return alias; - - return kind == object ? obj->name () : orig_name; - } + name () const; enum kind_type { object, table }; @@ -430,6 +424,23 @@ public: static class_kind_type class_kind (semantics::class_&); + // Return class names. For ordinary classes, this will be the class + // name itself. For class template instantiations this will be the + // typedef name used in the pragma. + // + static string + class_name (semantics::class_&); + + static string + class_fq_name (semantics::class_&); + + // Return the class file. For ordinary classes, this will be the file + // where the class is defined. For class template instantiations this + // will be the file containing the pragma. + // + static semantics::path + class_file (semantics::class_&); + // Database names and types. // public: diff --git a/odb/include.cxx b/odb/include.cxx index 1c143f4..d5675a1 100644 --- a/odb/include.cxx +++ b/odb/include.cxx @@ -74,11 +74,6 @@ namespace virtual void traverse (type& c) { - // Not interested in classes that we are generating. - // - if (c.file () == unit.file ()) - return; - // We only generate things for objects and composite value types. In // particular, we don't care about views since they cannot be used in // definitions of other views, objects, or composite values. @@ -86,12 +81,36 @@ namespace if (!(object (c) || composite (c))) return; + // Not interested in classes that we are generating. + // + // If this is a class template instantiation, then get the file + // corresponding to the pragma, not the instantiation itself, + // since that's where we are generation the code for this class. + // While at it, also get the location. + // + using semantics::path; + + path f; + location_t l; + + if (c.is_a<semantics::class_instantiation> ()) + { + l = c.get<location_t> ("location"); + f = path (LOCATION_FILE (l)); + } + else + { + f = c.file (); + tree decl (TYPE_NAME (c.tree_node ())); + l = DECL_SOURCE_LOCATION (decl); + } + + if (f == unit.file ()) + return; + // This is a persistent object or composite value type declared in // another header file. Include its -odb header. // - tree decl (TYPE_NAME (c.tree_node ())); - location_t l (DECL_SOURCE_LOCATION (decl)); - if (l > BUILTINS_LOCATION) { line_map const* lm (linemap_lookup (line_table, l)); @@ -450,16 +469,20 @@ namespace include traversal::unit unit; traversal::defines unit_defines; + typedefs unit_typedefs (true); traversal::namespace_ ns; class_ c (imap); unit >> unit_defines >> ns; unit_defines >> c; + unit >> unit_typedefs >> c; traversal::defines ns_defines; + typedefs ns_typedefs (true); ns >> ns_defines >> ns; ns_defines >> c; + ns >> ns_typedefs >> c; unit.dispatch (ctx.unit); diff --git a/odb/parser.cxx b/odb/parser.cxx index a5f17c3..474aa3d 100644 --- a/odb/parser.cxx +++ b/odb/parser.cxx @@ -866,7 +866,6 @@ emit_type_decl (tree decl) tree decl_name (DECL_NAME (decl)); char const* name (IDENTIFIER_POINTER (decl_name)); - if (DECL_ARTIFICIAL (decl) && (tc == RECORD_TYPE || tc == UNION_TYPE || tc == ENUMERAL_TYPE)) { @@ -1967,13 +1966,7 @@ add_pragma (node& n, pragma const& p) if (trace) ts << "\t\t pragma " << p.pragma_name << endl; - // Convert '_' to '-' in the pragma name so we get foo-bar instead - // of foo_bar (that's the convention used). - // - string k (p.context_name); - for (size_t i (0); i < k.size (); ++i) - if (k[i] == '_') - k[i] = '-'; + string const& k (p.context_name); if (p.add == 0) { diff --git a/odb/plugin.cxx b/odb/plugin.cxx index fbf1fa0..dd813d8 100644 --- a/odb/plugin.cxx +++ b/odb/plugin.cxx @@ -107,6 +107,12 @@ gate_callback (void*, void*) try { + // Post process pragmas. + // + post_process_pragmas (); + + // Parse the GCC tree to semantic graph. + // parser p (*options_, loc_pragmas_, decl_pragmas_); auto_ptr<unit> u (p.parse (global_namespace, file_)); @@ -129,6 +135,12 @@ gate_callback (void*, void*) generator g; g.generate (*options_, *u, file_); } + catch (pragmas_failed const&) + { + // Diagnostics has aready been issued. + // + r = 1; + } catch (parser::failed const&) { // Diagnostics has aready been issued. diff --git a/odb/pragma.cxx b/odb/pragma.cxx index e6ebbf5..1a992d0 100644 --- a/odb/pragma.cxx +++ b/odb/pragma.cxx @@ -43,6 +43,7 @@ accumulate (compiler::context& ctx, string const& k, any const& v, location_t) // loc_pragmas loc_pragmas_; decl_pragmas decl_pragmas_; +pragma_name_set simple_value_pragmas_; static bool parse_expression (tree& t, @@ -214,22 +215,9 @@ resolve_scoped_name (tree& token, cpp_ttype ptt; // Not used. string st (lex.start (token, type)); - tree decl ( + return lookup::resolve_scoped_name ( - st, type, ptt, lex, current_scope (), name, is_type)); - - // Get the actual type if this is a TYPE_DECL. - // - if (is_type) - { - if (TREE_CODE (decl) == TYPE_DECL) - decl = TREE_TYPE (decl); - - if (TYPE_P (decl)) // Can be a template. - decl = TYPE_MAIN_VARIANT (decl); - } - - return decl; + st, type, ptt, lex, current_scope (), name, is_type); } catch (lookup::invalid_name const&) { @@ -294,6 +282,23 @@ check_qual_decl_type (tree d, return true; } +static void +add_qual_entry (compiler::context& ctx, + string const& k, + any const& v, + location_t l) +{ + // Store the TYPE_DECL node that was referred to in the pragma. This + // can be used later as a name hint in case the type is a template + // instantiation. Also store the pragma location which is used as + // the "definition point" for this instantiation. + // + ctx.set ("tree-node", v); + ctx.set ("location", l); + + ctx.set (k, true); +} + static bool check_spec_decl_type (tree d, string const& name, @@ -838,6 +843,14 @@ handle_pragma (cpp_reader* reader, if (vo.node == 0) return; // Diagnostics has already been issued. + // Get the actual type if this is a TYPE_DECL. Also get the main variant. + // + if (TREE_CODE (vo.node) == TYPE_DECL) + vo.node = TREE_TYPE (vo.node); + + if (TYPE_P (vo.node)) // Can be a template. + vo.node = TYPE_MAIN_VARIANT (vo.node); + if (tt == CPP_EQ) { // We have an alias. @@ -1519,6 +1532,13 @@ handle_pragma (cpp_reader* reader, if (adder == 0 && val.empty ()) val = true; + // Convert '_' to '-' in the context name so we get foo-bar instead + // of foo_bar (that's the convention used). + // + for (size_t i (0); i < name.size (); ++i) + if (name[i] == '_') + name[i] = '-'; + // Record this pragma. // add_pragma (pragma (p, name, val, loc, &check_spec_decl_type, adder), decl); @@ -1539,7 +1559,7 @@ handle_pragma_qualifier (cpp_reader* reader, string const& p) tree t; cpp_ttype tt; - tree decl (0); + tree decl (0), orig_decl (0); string decl_name; location_t loc (input_location); @@ -1562,11 +1582,22 @@ handle_pragma_qualifier (cpp_reader* reader, string const& p) if (tt == CPP_NAME || tt == CPP_SCOPE) { - decl = resolve_scoped_name (t, tt, decl_name, true, p); + orig_decl = resolve_scoped_name (t, tt, decl_name, true, p); - if (decl == 0) + if (orig_decl == 0) return; // Diagnostics has already been issued. + // Get the actual type if this is a TYPE_DECL. Also get the main + // variant. + // + if (TREE_CODE (orig_decl) == TYPE_DECL) + orig_decl = TREE_TYPE (orig_decl); + + if (TYPE_P (orig_decl)) // Can be a template. + decl = TYPE_MAIN_VARIANT (orig_decl); + else + decl = orig_decl; + // Make sure we've got the correct declaration type. // if (!check_qual_decl_type (decl, decl_name, p, loc)) @@ -1668,7 +1699,12 @@ handle_pragma_qualifier (cpp_reader* reader, string const& p) // Record this pragma. // - pragma prag (p, p, any (true), loc, &check_qual_decl_type, 0); + pragma prag (p, + p, // For now no need to translate '_' to '-'. + any (orig_decl), + loc, + &check_qual_decl_type, + &add_qual_entry); if (decl) decl_pragmas_[decl].insert (prag); @@ -1905,6 +1941,34 @@ handle_pragma_db (cpp_reader* r) extern "C" void register_odb_pragmas (void*, void*) { + // Initialize the list of simple value pragmas. + // + //@@ Did we add new simple value pragmas and forgot to account for + // them here? + // + simple_value_pragmas_.insert ("table"); + simple_value_pragmas_.insert ("type"); + simple_value_pragmas_.insert ("id-type"); + simple_value_pragmas_.insert ("value-type"); + simple_value_pragmas_.insert ("index-type"); + simple_value_pragmas_.insert ("key-type"); + simple_value_pragmas_.insert ("value-column"); + simple_value_pragmas_.insert ("index-column"); + simple_value_pragmas_.insert ("key-column"); + simple_value_pragmas_.insert ("id-column"); + simple_value_pragmas_.insert ("default"); + simple_value_pragmas_.insert ("null"); + simple_value_pragmas_.insert ("not-null"); + simple_value_pragmas_.insert ("value-null"); + simple_value_pragmas_.insert ("value-not-null"); + simple_value_pragmas_.insert ("options"); + simple_value_pragmas_.insert ("value-options"); + simple_value_pragmas_.insert ("index-options"); + simple_value_pragmas_.insert ("key-options"); + simple_value_pragmas_.insert ("id-options"); + simple_value_pragmas_.insert ("unordered"); + + // GCC has a limited number of pragma slots and we have exhausted them. // A workaround is to make 'db' a pragma rather than a namespace. This // way we only have one pragma but the drawback of this approach is the @@ -1950,3 +2014,66 @@ register_odb_pragmas (void*, void*) c_register_pragma_with_expansion ("db", "version", handle_pragma_db_version); */ } + +void +post_process_pragmas () +{ + // Make sure composite class template instantiations are fully + // instantiated. + // + for (decl_pragmas::iterator i (decl_pragmas_.begin ()), + e (decl_pragmas_.end ()); i != e; ++i) + { + tree type (i->first); + + if (!(CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))) + continue; + + // Check whether this is a composite value type. We don't want to + // instantiate simple values since they may be incomplete. + // + pragma const* p; + + for (pragma_set::iterator j (i->second.begin ()), e (i->second.end ()); + j != e; ++j) + { + string const& name (j->context_name); + + if (name == "value") + p = &*j; + else + { + // Make sure it is not one of the simple value pragmas. + // + if (simple_value_pragmas_.find (name) != simple_value_pragmas_.end ()) + { + p = 0; + break; + } + } + } + + if (p == 0) + continue; + + // Make sure it is instantiated. + // + tree decl (TYPE_NAME (p->value.value<tree> ())); + location_t loc (DECL_SOURCE_LOCATION (decl)); + + // Reset input location so that we get nice diagnostics in case + // of an error. + // + input_location = loc; + + if (instantiate_class_template (type) == error_mark_node || + errorcount != 0 || + !COMPLETE_TYPE_P (type)) + { + error (loc) << "unable to instantiate composite value class template" + << endl; + + throw pragmas_failed (); + } + } +} diff --git a/odb/pragma.hxx b/odb/pragma.hxx index 0b09b43..57531ba 100644 --- a/odb/pragma.hxx +++ b/odb/pragma.hxx @@ -101,15 +101,25 @@ struct pragma_set: std::set<pragma> // namespace case is the global_namespace node. // typedef std::map<tree, pragma_list> loc_pragmas; +extern loc_pragmas loc_pragmas_; // Pragmas associated with this declaration. // typedef std::map<tree, pragma_set> decl_pragmas; - -extern loc_pragmas loc_pragmas_; extern decl_pragmas decl_pragmas_; +// List of pragma names (in context name form) that disqualify a value +// type from being treated as composite (i.e., simple value pragmas). +// +typedef std::set<std::string> pragma_name_set; +extern pragma_name_set simple_value_pragmas_; + extern "C" void register_odb_pragmas (void*, void*); +struct pragmas_failed {}; + +void +post_process_pragmas (); + #endif // ODB_PRAGMA_HXX diff --git a/odb/relational/common.cxx b/odb/relational/common.cxx index b7255a2..92e2c8f 100644 --- a/odb/relational/common.cxx +++ b/odb/relational/common.cxx @@ -28,7 +28,7 @@ namespace relational query_columns_base (semantics::class_& c) //@@ context::{cur,top}_object : decl_ (false) { - scope_ = "query_columns_base< " + c.fq_name () + " >"; + scope_ = "query_columns_base< " + class_fq_name (c) + " >"; } void query_columns_base:: @@ -102,7 +102,7 @@ namespace relational os << "typedef" << endl << "odb::query_pointer<" << endl << " odb::pointer_query_columns<" << endl - << " " << ptr->fq_name () << "," << endl + << " " << class_fq_name (*ptr) << "," << endl << " " << name << "_alias_ > >" << endl << name << "_type_ ;" << endl @@ -142,7 +142,7 @@ namespace relational : ptr_ (ptr), decl_ (false) { scope_ = ptr ? "pointer_query_columns" : "query_columns"; - scope_ += "< " + c.fq_name () + ", table >"; + scope_ += "< " + class_fq_name (c) + ", table >"; } void query_columns:: @@ -263,7 +263,7 @@ namespace relational << "typedef" << endl << "odb::query_pointer<" << endl << " odb::pointer_query_columns<" << endl - << " " << ptr->fq_name () << "," << endl + << " " << class_fq_name (*ptr) << "," << endl << " " << name << "_alias_ > >" << endl << name << "_pointer_type_;" << endl; diff --git a/odb/relational/header.cxx b/odb/relational/header.cxx index 11d3cf6..0df7607 100644 --- a/odb/relational/header.cxx +++ b/odb/relational/header.cxx @@ -27,16 +27,20 @@ namespace relational { traversal::unit unit; traversal::defines unit_defines; + typedefs unit_typedefs (false); traversal::namespace_ ns; instance<class1> c; unit >> unit_defines >> ns; unit_defines >> c; + unit >> unit_typedefs >> c; traversal::defines ns_defines; + typedefs ns_typedefs (false); ns >> ns_defines >> ns; ns_defines >> c; + ns >> ns_typedefs >> c; unit.dispatch (ctx.unit); } @@ -44,16 +48,20 @@ namespace relational { traversal::unit unit; traversal::defines unit_defines; + typedefs unit_typedefs (false); traversal::namespace_ ns; instance<class2> c; unit >> unit_defines >> ns; unit_defines >> c; + unit >> unit_typedefs >> c; traversal::defines ns_defines; + typedefs ns_typedefs (false); ns >> ns_defines >> ns; ns_defines >> c; + ns >> ns_typedefs >> c; unit.dispatch (ctx.unit); } diff --git a/odb/relational/header.hxx b/odb/relational/header.hxx index 39f2bbf..ee6cecf 100644 --- a/odb/relational/header.hxx +++ b/odb/relational/header.hxx @@ -62,10 +62,12 @@ namespace relational << " "; } + string const& type (class_fq_name (c)); + if (obj) - os << "object_traits< " << c.fq_name () << " >::image_type"; + os << "object_traits< " << type << " >::image_type"; else - os << "composite_value_traits< " << c.fq_name () << " >::image_type"; + os << "composite_value_traits< " << type << " >::image_type"; } private: @@ -155,7 +157,7 @@ namespace relational } os << (ptr_ ? "pointer_query_columns" : "query_columns") << - "< " << c.fq_name () << ", table >"; + "< " << class_fq_name (c) << ", table >"; } private: @@ -180,11 +182,13 @@ namespace relational if (!object (c)) return; - os << "// " << c.name () << endl + string const& name (class_name (c)); + + os << "// " << name << endl << "//" << endl << "typedef " << (ptr_ ? "pointer_query_columns" : "query_columns") << - "< " << c.fq_name () << ", table > " << c.name () << ";" + "< " << class_fq_name (c) << ", table > " << name << ";" << endl; } @@ -205,7 +209,7 @@ namespace relational virtual void traverse (type& c) { - string const& type (c.fq_name ()); + string const& type (class_fq_name (c)); if (ptr_) { @@ -483,13 +487,13 @@ namespace relational if (base) { semantics::class_& b (dynamic_cast<semantics::class_&> (m.scope ())); + string const& type (class_fq_name (b)); if (object (b)) - os << ": access::object_traits< " << b.fq_name () << " >::" << - name; + os << ": access::object_traits< " << type << " >::" << name; else - os << ": access::composite_value_traits< " << b.fq_name () << - " >::" << public_name (m) << "_traits"; // No prefix_. + os << ": access::composite_value_traits< " << type << " >::" << + public_name (m) << "_traits"; // No prefix_. } os << "{"; @@ -911,7 +915,7 @@ namespace relational virtual void traverse (type& c) { - if (c.file () != unit.file ()) + if (class_file (c) != unit.file ()) return; if (object (c)) @@ -936,7 +940,7 @@ namespace relational traverse_object (type& c) { bool abstract (context::abstract (c)); - string const& type (c.fq_name ()); + string const& type (class_fq_name (c)); semantics::data_member* id (id_member (c)); bool auto_id (id ? id->count ("auto") : false); @@ -946,7 +950,7 @@ namespace relational column_count_type const& cc (column_count (c)); - os << "// " << c.name () << endl + os << "// " << class_name (c) << endl << "//" << endl; // class_traits @@ -994,19 +998,21 @@ namespace relational { if (base_id) { - string const& base (id->scope ().fq_name ()); + semantics::class_& b ( + dynamic_cast<semantics::class_&> (id->scope ())); + string const& type (class_fq_name (b)); - os << "typedef object_traits< " << base << " >::id_type id_type;"; + os << "typedef object_traits< " << type << " >::id_type id_type;"; if (optimistic != 0) - os << "typedef object_traits< " << base << " >::version_type " << + os << "typedef object_traits< " << type << " >::version_type " << "version_type;"; os << endl - << "static const bool auto_id = object_traits< " << base << + << "static const bool auto_id = object_traits< " << type << " >::auto_id;" << endl - << "typedef object_traits< " << base << " >::id_image_type " << + << "typedef object_traits< " << type << " >::id_image_type " << "id_image_type;" << endl; } @@ -1335,9 +1341,9 @@ namespace relational virtual void traverse_view (type& c) { - string const& type (c.fq_name ()); + string const& type (class_fq_name (c)); - os << "// " << c.name () << endl + os << "// " << class_name (c) << endl << "//" << endl; os << "template <>" << endl @@ -1394,8 +1400,8 @@ namespace relational bool alias (!i->alias.empty ()); semantics::class_& o (*i->obj); - string const& name (alias ? i->alias : o.name ()); - string const& type (o.fq_name ()); + string const& name (alias ? i->alias : class_name (o)); + string const& type (class_fq_name (o)); os << "// " << name << endl << "//" << endl; @@ -1438,7 +1444,7 @@ namespace relational bool alias (!vo->alias.empty ()); semantics::class_& o (*vo->obj); - string const& type (o.fq_name ()); + string const& type (class_fq_name (o)); if (alias && vo->alias != table_name (o)) os << "static const char query_alias[];" @@ -1535,9 +1541,9 @@ namespace relational virtual void traverse_composite (type& c) { - string const& type (c.fq_name ()); + string const& type (class_fq_name (c)); - os << "// " << c.name () << endl + os << "// " << class_name (c) << endl << "//" << endl; os << "template <>" << endl @@ -1626,7 +1632,7 @@ namespace relational virtual void traverse (type& c) { - if (c.file () != unit.file ()) + if (class_file (c) != unit.file ()) return; if (object (c)) @@ -1641,14 +1647,14 @@ namespace relational traverse_object (type& c) { bool abst (abstract (c)); - string const& type (c.fq_name ()); + string const& type (class_fq_name (c)); if (options.generate_query ()) { bool has_ptr (has_a (c, test_pointer)); if (has_ptr || !abst) - os << "// " << c.name () << endl + os << "// " << class_name (c) << endl << "//" << endl; // query_columns diff --git a/odb/relational/inline.cxx b/odb/relational/inline.cxx index e5371ab..5184a9a 100644 --- a/odb/relational/inline.cxx +++ b/odb/relational/inline.cxx @@ -20,16 +20,20 @@ namespace relational traversal::unit unit; traversal::defines unit_defines; + typedefs unit_typedefs (false); traversal::namespace_ ns; class_ c; unit >> unit_defines >> ns; unit_defines >> c; + unit >> unit_typedefs >> c; traversal::defines ns_defines; + typedefs ns_typedefs (false); ns >> ns_defines >> ns; ns_defines >> c; + ns >> ns_typedefs >> c; os << "namespace odb" << "{"; diff --git a/odb/relational/inline.hxx b/odb/relational/inline.hxx index 78078eb..629d1aa 100644 --- a/odb/relational/inline.hxx +++ b/odb/relational/inline.hxx @@ -55,15 +55,16 @@ namespace relational // In case of the const instance, we only generate the call if // there is a const callback. // + string const& type (class_fq_name (c)); + if (const_) { if (c.count ("callback-const")) - os << "static_cast< const " << c.fq_name () << "& > (x)." << + os << "static_cast< const " << type << "& > (x)." << name << " (e, db);"; } else - os << "static_cast< " << c.fq_name () << "& > (x)." << - name << " (e, db);"; + os << "static_cast< " << type << "& > (x)." << name << " (e, db);"; } else if (obj) inherits (c); @@ -83,7 +84,7 @@ namespace relational virtual void traverse (type& c) { - if (c.file () != unit.file ()) + if (class_file (c) != unit.file ()) return; if (object (c)) @@ -103,7 +104,7 @@ namespace relational traverse_object (type& c) { bool abstract (context::abstract (c)); - string const& type (c.fq_name ()); + string const& type (class_fq_name (c)); string traits ("access::object_traits< " + type + " >"); semantics::data_member* id (id_member (c)); @@ -111,7 +112,15 @@ namespace relational semantics::data_member* optimistic (context::optimistic (c)); - os << "// " << c.name () << endl + // Base class the contains the object id and version for optimistic + // concurrency. + // + semantics::class_* base ( + id != 0 && base_id + ? dynamic_cast<semantics::class_*> (&id->scope ()) + : 0); + + os << "// " << class_name (c) << endl << "//" << endl << endl; @@ -130,7 +139,7 @@ namespace relational if (id != 0) { if (base_id) - os << "return object_traits< " << id->scope ().fq_name () << + os << "return object_traits< " << class_fq_name (*base) << " >::id (obj);"; else os << "return obj." << id->name () << ";"; @@ -150,7 +159,7 @@ namespace relational << traits << "::" << endl << "id (const image_type& i)" << "{" - << "return object_traits< " << id->scope ().fq_name () << + << "return object_traits< " << class_fq_name (*base) << " >::id (i);" << "}"; } @@ -164,8 +173,8 @@ namespace relational << traits << "::" << endl << "version (const image_type& i)" << "{" - << "return object_traits< " << - optimistic->scope ().fq_name () << " >::version (i);" + << "return object_traits< " << class_fq_name (*base) << + " >::version (i);" << "}"; } @@ -177,7 +186,7 @@ namespace relational << "void " << traits << "::" << endl << "bind (" << bind_vector << " b, id_image_type& i)" << "{" - << "object_traits< " << id->scope ().fq_name () << + << "object_traits< " << class_fq_name (*base) << " >::bind (b, i);" << "}"; } @@ -189,7 +198,7 @@ namespace relational << "init (id_image_type& i, const id_type& id" << (optimistic != 0 ? ", const version_type* v" : "") << ")" << "{" - << "object_traits< " << id->scope ().fq_name () << + << "object_traits< " << class_fq_name (*base) << " >::init (i, id" << (optimistic != 0 ? ", v" : "") << ");" << "}"; } @@ -298,10 +307,10 @@ namespace relational virtual void traverse_view (type& c) { - string const& type (c.fq_name ()); + string const& type (class_fq_name (c)); string traits ("access::view_traits< " + type + " >"); - os << "// " << c.name () << endl + os << "// " << class_name (c) << endl << "//" << endl << endl; diff --git a/odb/relational/model.cxx b/odb/relational/model.cxx index e44ffec..9bb6070 100644 --- a/odb/relational/model.cxx +++ b/odb/relational/model.cxx @@ -123,16 +123,20 @@ namespace relational traversal::unit unit; traversal::defines unit_defines; + typedefs unit_typedefs (false); traversal::namespace_ ns; instance<class_> c (*m); unit >> unit_defines >> ns; unit_defines >> c; + unit >> unit_typedefs >> c; traversal::defines ns_defines; + typedefs ns_typedefs (false); ns >> ns_defines >> ns; ns_defines >> c; + ns >> ns_typedefs >> c; try { diff --git a/odb/relational/model.hxx b/odb/relational/model.hxx index 3d8cc4b..6fe5b0d 100644 --- a/odb/relational/model.hxx +++ b/odb/relational/model.hxx @@ -46,7 +46,7 @@ namespace relational // (unqualified) name. // string t (id_prefix_); - id_prefix_ = c.name () + "::"; + id_prefix_ = class_name (c) + "::"; object_columns_base::traverse_object (c); id_prefix_ = t; } @@ -69,7 +69,7 @@ namespace relational else // Composite base. Add its unqualified name to id_prefix. // - id_prefix_ += c.name () + "::"; + id_prefix_ += class_name (c) + "::"; object_columns_base::traverse_composite (m, c); @@ -273,7 +273,7 @@ namespace relational // (unqualified) name. // string t (id_prefix_); - id_prefix_ = c.name () + "::"; + id_prefix_ = class_name (c) + "::"; object_members_base::traverse_object (c); id_prefix_ = t; } @@ -281,7 +281,7 @@ namespace relational { // Top-level object. Set its id as a prefix. // - id_prefix_ = string (c.fq_name (), 2) + "::"; + id_prefix_ = string (class_fq_name (c), 2) + "::"; object_members_base::traverse_object (c); } } @@ -298,7 +298,7 @@ namespace relational else // Composite base. Add its unqualified name to id_prefix. // - id_prefix_ += c.name () + "::"; + id_prefix_ += class_name (c) + "::"; object_members_base::traverse_composite (m, c); @@ -469,7 +469,7 @@ namespace relational virtual void traverse (type& c) { - if (c.file () != unit.file ()) + if (class_file (c) != unit.file ()) return; if (!object (c) || abstract (c)) @@ -487,7 +487,7 @@ namespace relational return; } - string id (c.fq_name (), 2); // Remove leading '::'. + string id (class_fq_name (c), 2); // Remove leading '::'. sema_rel::object_table& t( model_.new_node<sema_rel::object_table> (id)); diff --git a/odb/relational/mysql/source.cxx b/odb/relational/mysql/source.cxx index 576f80c..06d40b7 100644 --- a/odb/relational/mysql/source.cxx +++ b/odb/relational/mysql/source.cxx @@ -645,7 +645,7 @@ namespace relational // Handle NULL pointers and extract the id. // os << "{" - << "typedef object_traits< " << c->fq_name () << + << "typedef object_traits< " << class_fq_name (*c) << " > obj_traits;"; if (weak_pointer (mt)) @@ -919,7 +919,7 @@ namespace relational // Handle NULL pointers and extract the id. // os << "{" - << "typedef object_traits< " << c->fq_name () << + << "typedef object_traits< " << class_fq_name (*c) << " > obj_traits;" << "typedef pointer_traits< " << mi.fq_type () << " > ptr_traits;" diff --git a/odb/relational/oracle/source.cxx b/odb/relational/oracle/source.cxx index 066947e..b4131e1 100644 --- a/odb/relational/oracle/source.cxx +++ b/odb/relational/oracle/source.cxx @@ -400,7 +400,7 @@ namespace relational // Handle NULL pointers and extract the id. // os << "{" - << "typedef object_traits< " << c->fq_name () << + << "typedef object_traits< " << class_fq_name (*c) << " > obj_traits;"; if (weak_pointer (mt)) @@ -667,7 +667,7 @@ namespace relational // Handle NULL pointers and extract the id. // os << "{" - << "typedef object_traits< " << c->fq_name () << + << "typedef object_traits< " << class_fq_name (*c) << " > obj_traits;" << "typedef pointer_traits< " << mi.fq_type () << " > ptr_traits;" diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx index 7200405..00ee777 100644 --- a/odb/relational/pgsql/source.cxx +++ b/odb/relational/pgsql/source.cxx @@ -555,7 +555,7 @@ namespace relational // Handle NULL pointers and extract the id. // os << "{" - << "typedef object_traits< " << c->fq_name () << + << "typedef object_traits< " << class_fq_name (*c) << " > obj_traits;"; if (weak_pointer (mt)) @@ -803,7 +803,7 @@ namespace relational // Handle NULL pointers and extract the id. // os << "{" - << "typedef object_traits< " << c->fq_name () << + << "typedef object_traits< " << class_fq_name (*c) << " > obj_traits;" << "typedef pointer_traits< " << mi.fq_type () << " > ptr_traits;" @@ -1014,7 +1014,7 @@ namespace relational semantics::data_member* optimistic (context::optimistic (c)); column_count_type const& cc (column_count (c)); - string const& n (c.fq_name ()); + string const& n (class_fq_name (c)); string traits ("access::object_traits< " + n + " >::"); string const& fn (flat_name (n)); string name_decl ("const char " + traits); @@ -1158,7 +1158,7 @@ namespace relational virtual void view_extra (type& c) { - string const& n (c.fq_name ()); + string const& n (class_fq_name (c)); string traits ("access::view_traits< " + n + " >::"); string const& fn (flat_name (n)); string name_decl ("const char " + traits); @@ -1231,7 +1231,7 @@ namespace relational // Prefix top-object name to avoid conflicts with inherited // member statement names. // - string stmt_prefix (top_object->fq_name () + m.fq_name ()); + string stmt_prefix (class_fq_name (*top_object) + m.fq_name ()); os << stmt_decl << endl << "select_all_name[] = " << diff --git a/odb/relational/processor.cxx b/odb/relational/processor.cxx index 41093de..8d80df0 100644 --- a/odb/relational/processor.cxx +++ b/odb/relational/processor.cxx @@ -825,11 +825,12 @@ namespace relational if (!c->complete ()) { os << m.file () << ":" << m.line () << ":" << m.column () << ": " - << "error: pointed-to class '" << c->fq_name () << "' " + << "error: pointed-to class '" << class_fq_name (*c) << "' " << "is incomplete" << endl; os << c->file () << ":" << c->line () << ":" << c->column () << ": " - << "info: class '" << c->name () << "' is declared here" << endl; + << "info: class '" << class_name (*c) << "' is declared here" + << endl; os << c->file () << ":" << c->line () << ":" << c->column () << ": " << "info: consider including its definition with the " @@ -843,11 +844,12 @@ namespace relational if (context::abstract (*c)) { os << m.file () << ":" << m.line () << ":" << m.column () << ": " - << "error: pointed-to class '" << c->fq_name () << "' " + << "error: pointed-to class '" << class_fq_name (*c) << "' " << "is abstract" << endl; os << c->file () << ":" << c->line () << ":" << c->column () << ": " - << "info: class '" << c->name () << "' is defined here" << endl; + << "info: class '" << class_name (*c) << "' is defined here" + << endl; throw operation_failed (); } @@ -857,11 +859,12 @@ namespace relational if (context::id_member (*c) == 0) { os << m.file () << ":" << m.line () << ":" << m.column () << ": " - << "error: pointed-to class '" << c->fq_name () << "' " + << "error: pointed-to class '" << class_fq_name (*c) << "' " << "has no object id" << endl; os << c->file () << ":" << c->line () << ":" << c->column () << ": " - << "info: class '" << c->name () << "' is defined here" << endl; + << "info: class '" << class_name (*c) << "' is defined here" + << endl; throw operation_failed (); } @@ -881,7 +884,7 @@ namespace relational os << m.file () << ":" << m.line () << ":" << m.column () << ": " << "error: unable to resolve data member '" << name << "' " << "specified with '#pragma db inverse' in class '" - << c->fq_name () << "'" << endl; + << class_fq_name (*c) << "'" << endl; throw operation_failed (); } @@ -891,8 +894,8 @@ namespace relational { os << m.file () << ":" << m.line () << ":" << m.column () << ": " << "ice: unable to find semantic graph node corresponding to " - << "data member '" << name << "' in class '" << c->fq_name () - << "'" << endl; + << "data member '" << name << "' in class '" + << class_fq_name (*c) << "'" << endl; throw operation_failed (); } @@ -1691,7 +1694,7 @@ namespace relational if (vq.kind == view_query::condition && !has_o) { error (c.file (), c.line (), c.column ()) - << "view '" << c.fq_name () << "' has an incomplete query " + << "view '" << class_fq_name (c) << "' has an incomplete query " << "template and no associated objects" << endl; info (c.file (), c.line (), c.column ()) @@ -1886,7 +1889,7 @@ namespace relational relationship const& r (rs.back ()); string name (r.pointer->alias.empty () - ? r.pointer->obj->fq_name () + ? class_fq_name (*r.pointer->obj) : r.pointer->alias); name += "::"; name += r.name; @@ -2004,7 +2007,7 @@ namespace relational try { string ptr; - string const& name (c.fq_name ()); + string const& type (class_fq_name (c)); tree decl (0); // Resolved template node. string decl_name; // User-provided template name. @@ -2016,7 +2019,7 @@ namespace relational string const& p (cp.name); if (p == "*") - ptr = name + "*"; + ptr = type + "*"; else if (p[p.size () - 1] == '*') ptr = p; else if (p.find ('<') != string::npos) @@ -2054,7 +2057,7 @@ namespace relational } else if (tc == TEMPLATE_DECL && DECL_CLASS_TEMPLATE_P (decl)) { - ptr = p + "< " + name + " >"; + ptr = p + "< " + type + " >"; decl_name = p; } else @@ -2079,10 +2082,10 @@ namespace relational string const& p (options.default_pointer ()); if (p == "*") - ptr = name + "*"; + ptr = type + "*"; else { - ptr = p + "< " + name + " >"; + ptr = p + "< " + type + " >"; decl_name = p; } @@ -2315,16 +2318,20 @@ namespace relational traversal::unit unit; traversal::defines unit_defines; + typedefs unit_typedefs (true); traversal::namespace_ ns; class_ c; unit >> unit_defines >> ns; unit_defines >> c; + unit >> unit_typedefs >> c; traversal::defines ns_defines; + typedefs ns_typedefs (true); ns >> ns_defines >> ns; ns_defines >> c; + ns >> ns_typedefs >> c; unit.dispatch (ctx.unit); } diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx index 749e0d6..39a2ddc 100644 --- a/odb/relational/source.cxx +++ b/odb/relational/source.cxx @@ -172,7 +172,7 @@ namespace relational if (multi_obj) { r += "::"; - r += vo->obj->name (); + r += context::class_name (*vo->obj); } } @@ -563,16 +563,20 @@ namespace relational traversal::unit unit; traversal::defines unit_defines; + typedefs unit_typedefs (false); traversal::namespace_ ns; instance<class_> c; unit >> unit_defines >> ns; unit_defines >> c; + unit >> unit_typedefs >> c; traversal::defines ns_defines; + typedefs ns_typedefs (false); ns >> ns_defines >> ns; ns_defines >> c; + ns >> ns_typedefs >> c; instance<include> i; i->generate (); diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx index 56a356b..6e92607 100644 --- a/odb/relational/source.hxx +++ b/odb/relational/source.hxx @@ -555,7 +555,7 @@ namespace relational if (!(obj || composite (c))) return; - os << "// " << c.name () << " base" << endl + os << "// " << class_name (c) << " base" << endl << "//" << endl; // If the derived class is readonly, then we will never be @@ -569,7 +569,7 @@ namespace relational << "{"; os << (obj ? "object" : "composite_value") << "_traits< " << - c.fq_name () << " >::bind (b + n, i, sk);"; + class_fq_name (c) << " >::bind (b + n, i, sk);"; column_count_type const& cc (column_count (c)); @@ -653,11 +653,11 @@ namespace relational if (!(obj || composite (c))) return; - os << "// " << c.name () << " base" << endl + os << "// " << class_name (c) << " base" << endl << "//" << endl; os << "if (" << (obj ? "object" : "composite_value") << "_traits< " << - c.fq_name () << " >::grow (i, t + " << index_ << "UL))" << endl + class_fq_name (c) << " >::grow (i, t + " << index_ << "UL))" << endl << "grew = true;" << endl; @@ -711,7 +711,7 @@ namespace relational if (!(obj || composite (c))) return; - os << "// " << c.name () << " base" << endl + os << "// " << class_name (c) << " base" << endl << "//" << endl; // If the derived class is readonly, then we will never be @@ -724,7 +724,7 @@ namespace relational << "{"; os << "if (" << (obj ? "object" : "composite_value") << "_traits< " << - c.fq_name () << " >::init (i, o, sk))" << endl + class_fq_name (c) << " >::init (i, o, sk))" << endl << "grew = true;"; if (check) @@ -776,10 +776,10 @@ namespace relational if (!(obj || composite (c))) return; - os << "// " << c.name () << " base" << endl + os << "// " << class_name (c) << " base" << endl << "//" << endl << (obj ? "object" : "composite_value") << "_traits< " << - c.fq_name () << " >::init (o, i, db);" + class_fq_name (c) << " >::init (o, i, db);" << endl; } }; @@ -793,10 +793,12 @@ namespace relational container_traits (semantics::class_& c) : object_members_base (true, true, false), c_ (c) { + string const& type (class_fq_name (c)); + if (object (c)) - scope_ = "access::object_traits< " + c.fq_name () + " >"; + scope_ = "access::object_traits< " + type + " >"; else - scope_ = "access::composite_value_traits< " + c.fq_name () + " >"; + scope_ = "access::composite_value_traits< " + type + " >"; } // Unless the database system can execute several interleaving @@ -1992,7 +1994,7 @@ namespace relational } else if (call_ == load_call && const_type (m->type ())) { - obj_prefix_ = "const_cast< " + c.fq_name () + "& > (\n" + + obj_prefix_ = "const_cast< " + class_fq_name (c) + "& > (\n" + obj_prefix_ + ")"; } @@ -2226,7 +2228,7 @@ namespace relational virtual void traverse (type& c) { - if (c.file () != unit.file ()) + if (class_file (c) != unit.file ()) return; context::top_object = context::cur_object = &c; @@ -2289,7 +2291,7 @@ namespace relational traverse_object (type& c) { bool abstract (context::abstract (c)); - string const& type (c.fq_name ()); + string const& type (class_fq_name (c)); string traits ("access::object_traits< " + type + " >"); bool has_ptr (has_a (c, test_pointer)); @@ -2312,7 +2314,7 @@ namespace relational column_count_type const& cc (column_count (c)); - os << "// " << c.name () << endl + os << "// " << class_name (c) << endl << "//" << endl << endl; @@ -3423,7 +3425,7 @@ namespace relational ++end; // Transform the range from [begin, end] to [begin, end). - string const& type (c.fq_name ()); + string const& type (class_fq_name (c)); string traits ("access::object_traits< " + type + " >"); // create_schema () @@ -3522,10 +3524,10 @@ namespace relational virtual void traverse_view (type& c) { - string const& type (c.fq_name ()); + string const& type (class_fq_name (c)); string traits ("access::view_traits< " + type + " >"); - os << "// " << c.name () << endl + os << "// " << class_name (c) << endl << "//" << endl << endl; @@ -3870,7 +3872,7 @@ namespace relational if (!ambig) { error (i->loc) - << "pointed-to object '" << c->name () << "' is " + << "pointed-to object '" << class_name (*c) << "' is " << "ambiguous" << endl; info (i->loc) @@ -3898,7 +3900,7 @@ namespace relational if (vo == 0) { error (i->loc) - << "pointed-to object '" << c->name () << "' " + << "pointed-to object '" << class_name (*c) << "' " << "specified in the join condition has not been " << "previously associated with this view" << endl; @@ -4257,10 +4259,10 @@ namespace relational virtual void traverse_composite (type& c) { - string const& type (c.fq_name ()); + string const& type (class_fq_name (c)); string traits ("access::composite_value_traits< " + type + " >"); - os << "// " << c.name () << endl + os << "// " << class_name (c) << endl << "//" << endl << endl; diff --git a/odb/relational/sqlite/source.cxx b/odb/relational/sqlite/source.cxx index 32ac13e..5a9f5fb 100644 --- a/odb/relational/sqlite/source.cxx +++ b/odb/relational/sqlite/source.cxx @@ -353,7 +353,7 @@ namespace relational // Handle NULL pointers and extract the id. // os << "{" - << "typedef object_traits< " << c->fq_name () << + << "typedef object_traits< " << class_fq_name (*c) << " > obj_traits;"; if (weak_pointer (mt)) @@ -545,7 +545,7 @@ namespace relational // Handle NULL pointers and extract the id. // os << "{" - << "typedef object_traits< " << c->fq_name () << + << "typedef object_traits< " << class_fq_name (*c) << " > obj_traits;" << "typedef pointer_traits< " << mi.fq_type () << " > ptr_traits;" diff --git a/odb/validator.cxx b/odb/validator.cxx index 8a94357..94fe1da 100644 --- a/odb/validator.cxx +++ b/odb/validator.cxx @@ -290,7 +290,7 @@ namespace cerr << c.file () << ":" << c.line () << ":" << c.column () << ": " << "error: unable to resolve member function '" << name << "' " << "specified with '#pragma db callback' for class '" - << c.name () << "'" << endl; + << context::class_name (c) << "'" << endl; valid_ = false; } @@ -331,7 +331,7 @@ namespace { // @@ Should we use hint here? // - string name (b.fq_name ()); + string name (context::class_fq_name (b)); cerr << c.file () << ":" << c.line () << ":" << c.column () << ":" << " error: base class '" << name << "' is a view or value type" @@ -540,7 +540,7 @@ namespace { // @@ Should we use hint here? // - string name (b.fq_name ()); + string name (context::class_fq_name (b)); cerr << c.file () << ":" << c.line () << ":" << c.column () << ":" << " error: base class '" << name << "' is an object, " @@ -619,7 +619,7 @@ namespace { // @@ Should we use hint here? // - string name (b.fq_name ()); + string name (context::class_fq_name (b)); cerr << c.file () << ":" << c.line () << ":" << c.column () << ":" << " error: base class '" << name << "' is a view or object " @@ -689,6 +689,26 @@ namespace traversal::names names_; }; + struct typedefs1: typedefs + { + typedefs1 (traversal::declares& d) + : typedefs (true), declares_ (d) + { + } + + void + traverse (semantics::typedefs& t) + { + if (check (t)) + traversal::typedefs::traverse (t); + else + declares_.traverse (t); + } + + private: + traversal::declares& declares_; + }; + // // Pass 2. // @@ -875,6 +895,7 @@ validate (options const& ops, traversal::unit unit; traversal::defines unit_defines; traversal::declares unit_declares; + typedefs1 unit_typedefs (unit_declares); traversal::namespace_ ns; value_type vt (valid); class1 c (valid, ops, u, vt); @@ -882,13 +903,16 @@ validate (options const& ops, unit >> unit_defines >> ns; unit_defines >> c; unit >> unit_declares >> vt; + unit >> unit_typedefs >> c; traversal::defines ns_defines; traversal::declares ns_declares; + typedefs1 ns_typedefs (ns_declares); ns >> ns_defines >> ns; ns_defines >> c; ns >> ns_declares >> vt; + ns >> ns_typedefs >> c; unit.dispatch (u); } @@ -896,17 +920,20 @@ validate (options const& ops, { traversal::unit unit; traversal::defines unit_defines; + typedefs unit_typedefs (true); traversal::namespace_ ns; - value_type vt (valid); class2 c (valid, ops, u); unit >> unit_defines >> ns; unit_defines >> c; + unit >> unit_typedefs >> c; traversal::defines ns_defines; + typedefs ns_typedefs (true); ns >> ns_defines >> ns; ns_defines >> c; + ns >> ns_typedefs >> c; unit.dispatch (u); } |