From 302b804ec633889f26dc54d937d9becc09246152 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 16 Nov 2010 08:49:35 +0200 Subject: Rework pointer traits, add naked, auto_ptr, and TR1 specializations --- odb/header.cxx | 20 ++++++++ odb/mysql/source.cxx | 2 +- odb/odb.cxx | 7 ++- odb/tracer/source.cxx | 2 +- odb/type-processor.cxx | 136 ++++++++++++++++++++++++++++++++++++++----------- 5 files changed, 135 insertions(+), 32 deletions(-) diff --git a/odb/header.cxx b/odb/header.cxx index 35a95ab..d7fed95 100644 --- a/odb/header.cxx +++ b/odb/header.cxx @@ -87,6 +87,26 @@ generate_header (context& ctx) << "#include " << endl << endl; + // In case of a boost TR1 implementation, we cannot distinguish + // between the boost::shared_ptr and std::tr1::shared_ptr usage since + // the latter is just a using-declaration for the former. To resolve + // this we will include TR1 traits if the Boost TR1 header is included. + // + if (ctx.unit.count ("tr1-pointer-used") && + ctx.unit.get ("tr1-pointer-used")) + { + ctx.os << "#include " << endl + << endl; + } + else if (ctx.unit.count ("boost-pointer-used") && + ctx.unit.get ("boost-pointer-used")) + { + ctx.os << "#ifdef BOOST_TR1_MEMORY_HPP_INCLUDED" << endl + << "# include " << endl + << "#endif" << endl + << endl; + } + /* traversal::unit unit; traversal::defines unit_defines; diff --git a/odb/mysql/source.cxx b/odb/mysql/source.cxx index 2e54a04..2f65de6 100644 --- a/odb/mysql/source.cxx +++ b/odb/mysql/source.cxx @@ -2176,7 +2176,7 @@ namespace mysql << "{" << "pointer_type p (access::object_factory< object_type, " << "pointer_type >::create ());" - << "pointer_traits< pointer_type >::guard g (p);" + << "pointer_traits< pointer_type >::guard_type g (p);" << "object_type& obj (pointer_traits< pointer_type >::get_ref (p));" << "init (obj, sts.image ());"; diff --git a/odb/odb.cxx b/odb/odb.cxx index a1beccf..075cf53 100644 --- a/odb/odb.cxx +++ b/odb/odb.cxx @@ -530,7 +530,12 @@ main (int argc, char* argv[]) << "# include " << endl << "#endif" << endl; - // Standard containers traits. + // Standard pointer traits. + // + os << "#include " << endl + << "#include " << endl; + + // Standard container traits. // os << "#include " << endl; } diff --git a/odb/tracer/source.cxx b/odb/tracer/source.cxx index 8d1bd4f..b77d69a 100644 --- a/odb/tracer/source.cxx +++ b/odb/tracer/source.cxx @@ -95,7 +95,7 @@ namespace tracer << endl << "pointer_type r (access::object_factory< object_type, " << "pointer_type >::create ());" - << "pointer_traits< pointer_type >::guard g (r);" + << "pointer_traits< pointer_type >::guard_type g (r);" << "r->" << id.name () << " = id;" << "g.release ();" << "return r;" diff --git a/odb/type-processor.cxx b/odb/type-processor.cxx index b99cfb9..921a90b 100644 --- a/odb/type-processor.cxx +++ b/odb/type-processor.cxx @@ -399,10 +399,26 @@ namespace // Assign object pointer. // if (obj) + assign_pointer (c); + } + + void + assign_pointer (type& c) + { + try { string ptr; string const& name (c.fq_name ()); + if (!unit.count ("tr1-pointer-used")) + { + unit.set ("tr1-pointer-used", false); + unit.set ("boost-pointer-used", false); + } + + bool& tr1 (unit.get ("tr1-pointer-used")); + bool& boost (unit.get ("boost-pointer-used")); + if (c.count ("pointer")) { string const& p (c.get ("pointer")); @@ -412,44 +428,66 @@ namespace else if (p[p.size () - 1] == '*') ptr = p; else if (p.find ('<') != string::npos) + { + // Template-id. See if it is from TR1. + // ptr = p; + tr1 = tr1 + || p.compare (0, 8, "std::tr1") == 0 + || p.compare (0, 10, "::std::tr1") == 0; + } else { // This is not a template-id. Resolve it and see if it is a // template or a type. // - try + tree decl (resolve_type (p, c.scope ())); + int tc (TREE_CODE (decl)); + + if (tc == TYPE_DECL) { - tree t (resolve_type (p, c.scope ())); - int tc (TREE_CODE (t)); - - if (tc == TYPE_DECL) - ptr = p; - else if (tc == TEMPLATE_DECL && DECL_CLASS_TEMPLATE_P (t)) - ptr = p + "< " + name + " >"; - else - { - cerr << c.file () << ":" << c.line () << ":" << c.column () - << ": error: name '" << p << "' specified with " - << "'#pragma object pointer' does not name a type " - << "or a template" << endl; + ptr = p; - throw generation_failed (); + // This can be a typedef'ed alias for a TR1 template-id. + // + if (tree ti = TYPE_TEMPLATE_INFO (TREE_TYPE (decl))) + { + tree t (TI_TEMPLATE (ti)); // DECL_TEMPLATE + + // Get to the most general template declaration. + // + while (DECL_TEMPLATE_INFO (t)) + t = DECL_TI_TEMPLATE (t); + + string n (decl_as_string (t, TFF_PLAIN_IDENTIFIER)); + + // In case of a boost TR1 implementation, we cannot + // distinguish between the boost:: and std::tr1:: + // usage since the latter is just a using-declaration + // for the former. + // + tr1 = tr1 + || n.compare (0, 8, "std::tr1") == 0 + || n.compare (0, 10, "::std::tr1") == 0; + + boost = boost + || n.compare (0, 17, "boost::shared_ptr") == 0 + || n.compare (0, 19, "::boost::shared_ptr") == 0; } } - catch (invalid_name const&) + else if (tc == TEMPLATE_DECL && DECL_CLASS_TEMPLATE_P (decl)) { - cerr << c.file () << ":" << c.line () << ":" << c.column () - << ": error: type name '" << p << "' specified with " - << "'#pragma object pointer' is invalid" << endl; - - throw generation_failed (); + ptr = p + "< " + name + " >"; + tr1 = tr1 + || p.compare (0, 8, "std::tr1") == 0 + || p.compare (0, 10, "::std::tr1") == 0; } - catch (unable_to_resolve const&) + else { cerr << c.file () << ":" << c.line () << ":" << c.column () - << ": error: unable to resolve type name '" << p - << "' specified with '#pragma object pointer'" << endl; + << ": error: name '" << p << "' specified with " + << "'#pragma object pointer' does not name a type " + << "or a template" << endl; throw generation_failed (); } @@ -464,16 +502,56 @@ namespace if (p == "*") ptr = name + "*"; else + { ptr = p + "< " + name + " >"; + tr1 = tr1 + || p.compare (0, 8, "std::tr1") == 0 + || p.compare (0, 10, "::std::tr1") == 0; + } } c.set ("object-pointer", ptr); } + catch (invalid_name const& ex) + { + cerr << c.file () << ":" << c.line () << ":" << c.column () + << ": error: type name '" << ex.name () << "' specified with " + << "'#pragma object pointer' is invalid" << endl; + + throw generation_failed (); + } + catch (unable_to_resolve const& ex) + { + cerr << c.file () << ":" << c.line () << ":" << c.column () + << ": error: unable to resolve type name '" << ex.name () + << "' specified with '#pragma object pointer'" << endl; + + throw generation_failed (); + } } private: - struct invalid_name {}; - struct unable_to_resolve {}; + struct invalid_name + { + invalid_name (string const& n): name_ (n) {} + + string const& + name () const {return name_;} + + private: + string name_; + }; + + struct unable_to_resolve + { + unable_to_resolve (string const& n): name_ (n) {} + + string const& + name () const {return name_;} + + private: + string name_; + }; tree resolve_type (string const& qn, semantics::scope& ss) @@ -491,7 +569,7 @@ namespace if (b == 0) scope = global_namespace; else - throw invalid_name (); + throw invalid_name (qn); } else { @@ -513,7 +591,7 @@ namespace } if (scope == error_mark_node) - throw unable_to_resolve (); + throw unable_to_resolve (qn); if (!last && TREE_CODE (scope) == TYPE_DECL) scope = TREE_TYPE (scope); @@ -523,7 +601,7 @@ namespace break; if (qn[++e] != ':') - throw invalid_name (); + throw invalid_name (qn); ++e; // Second ':'. -- cgit v1.1