public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Frank B. Brokken" <f.b.brokken@rug.nl>
To: Ian Lance Taylor <iant@google.com>
Cc: George Danchev <danchev@spnet.net>,
	gcc-help@gcc.gnu.org,        tony mancill <tmancill@debian.org>
Subject: Re: missing symbols with bobcat C++ library on armel
Date: Wed, 25 May 2011 15:14:00 -0000	[thread overview]
Message-ID: <20110525134815.GD31243@suffix.rc.rug.nl> (raw)
In-Reply-To: <mcr62oyex4u.fsf@coign.corp.google.com>

[-- Attachment #1: Type: text/plain, Size: 6266 bytes --]

Dear Ian Lance Taylor, you wrote:
> 
> George Danchev <danchev@spnet.net> writes:
> 
> > Missing symbols are probably related to the following usage pattern (all valid 
> > code in my opinion) of members:
> > MultiStreambuf::overflow(int c)
> > MultiStreambuf::sync()
> > MultiStreambuf::xsputn(char const *buffer, std::streamsize n)
> >
> > * all are private virtual;
> > * all implemented in separate translation unit (multistreambuf.ih);
> > * all inlined
> > * dtor for MultiStreambuf class is not explicitly defined.
> 
> You don't mention it, but the log shows undefined references to the
> vtable for FBB:MultiStreambuf.  I have not looked at the code, but this
> certainly sounds like a missing key method.  Can you show us just the
> declaration of MultiStreambuf from the .h file?  That will let us tell
> you what the key method is.  If that key method is not defined anywhere,
> then these kinds of errors are possible.


Thanks for your reaction to George's questions. 

If you want to have a look at MultiStreambuf's header file, here it is:

-------------------------------------------------------
#ifndef INCLUDED_BOBCAT_MULTISTREAMBUF_
#define INCLUDED_BOBCAT_MULTISTREAMBUF_

#include <cstdio>
#include <streambuf>
#include <vector>
#include <ostream>
#include <string>

namespace FBB
{

class MultiStreambuf: public std::streambuf
{
    public:
        enum Mode
        {
            OFF,                // stream not used
            ON,                 // stream always used
            ONCE,               // stream used until flushed
            RESET,              // stream once used. Set to ONCE to re-use
        };

        class stream            // holds a pointer to a stream and a indicator
        {                       // telling us whether or not to use the stream
            friend class MultiStreambuf;

            std::ostream *d_os;
            Mode          d_mode;

            public:
                stream(std::ostream &os, Mode mode = ON);
                void setMode(Mode mode);
                Mode mode() const;
                std::ostream &ostream();
            private:
                static void setOnce(stream &os);
        };

        typedef std::vector<stream>::iterator iterator;
        typedef std::vector<stream>::const_iterator const_iterator;

    private:
        std::string d_buffer;
        std::vector<stream> d_os;

    public:
        MultiStreambuf() = default;
        explicit MultiStreambuf(std::ostream &os, Mode mode = ON);
        explicit MultiStreambuf(std::vector<stream> const &osvector);

        void insert(std::ostream &os, Mode mode = ON);
        void insert(std::vector<stream> const &os);
        iterator begin();
        iterator end();
        const_iterator begin() const;
        const_iterator end() const;
        void setOnce();             // reset all `RESET' modes to `ONCE'
        
    protected:
        int pSync();

    private:
        virtual int overflow(int c);
        virtual std::streamsize xsputn(char const *buffer, std::streamsize n);
        virtual int sync();

        struct Insert
        {
            std::string &buffer;
            bool ok;
        };
        static void insertStruct(stream &os, Insert &insert); 
};

inline MultiStreambuf::stream::stream(std::ostream &os, Mode mode)
:
    d_os(&os),
    d_mode(mode)
{}

inline void MultiStreambuf::stream::setMode(Mode mode)
{
    d_mode = mode;
}

inline MultiStreambuf::Mode MultiStreambuf::stream::mode() const
{
    return d_mode;
}

inline std::ostream &MultiStreambuf::stream::ostream()
{
    return *d_os;
}

inline void MultiStreambuf::stream::setOnce(stream &os)
{
    if (os.d_mode == RESET)
        os.d_mode = ONCE;
}

inline MultiStreambuf::MultiStreambuf(std::ostream &os, Mode mode)
{
    insert(os, mode);
}

inline MultiStreambuf::MultiStreambuf(std::vector<stream> const &osvector)
{
    insert(osvector);
}

inline void MultiStreambuf::insert(std::ostream &os, Mode mode)
{
    d_os.push_back(stream(os, mode));
}

inline void MultiStreambuf::insert(std::vector<stream> const &os)
{
    d_os.insert(d_os.end(), os.begin(), os.end());
}

inline MultiStreambuf::iterator MultiStreambuf::begin()
{
    return d_os.begin();
}

inline MultiStreambuf::iterator MultiStreambuf::end()
{
    return d_os.end();
}

inline MultiStreambuf::const_iterator MultiStreambuf::begin() const
{
    return d_os.begin();
}

inline MultiStreambuf::const_iterator MultiStreambuf::end() const
{
    return d_os.end();
}

} // namespace FBB
        
#endif
-------------------------------------------------------


You won't see the implementations of the private virtual members here, as they
are provided in the following header file, which is included by
MultiStreambuf's sources:

-------------------------------------------------------
#include "multistreambuf"

#include <algorithm>
#include <bobcat/fnwrap>

using namespace FBB;

inline std::streamsize MultiStreambuf::xsputn(char const *buffer, 
                                              std::streamsize n)
{
    d_buffer.append(buffer, n);
    return n;
}

inline int MultiStreambuf::sync()
{
    return pSync();
}

inline int MultiStreambuf::overflow(int c)
{
    if (c == EOF)
        pSync();
    else 
        d_buffer += c;

    return c;
}
-------------------------------------------------------


Since it looks like armel's compiler skips the inline definitions of virtual
members when compiling for a shared library, we're in the process of removing
all inline definitions of virtual members, replacing them by non-inline
definitions in separate source files. From tests done so far by George Danchev
we get the impression that this might very well solve (or bypass?) the issue.

If the above is not what you wanted me to send you, please let me know.

Cheers,

-- 
    Frank B. Brokken
    Center for Information Technology, University of Groningen
    (+31) 50 363 9281 
    Public PGP key: http://pgp.surfnet.nl
    Key Fingerprint: DF32 13DE B156 7732 E65E  3B4D 7DB2 A8BE EAE4 D8AA

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 482 bytes --]

  reply	other threads:[~2011-05-25 13:48 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-25  8:30 George Danchev
2011-05-25 13:48 ` Ian Lance Taylor
2011-05-25 15:14   ` Frank B. Brokken [this message]
2011-05-25 16:13     ` Ian Lance Taylor
2011-05-25 18:22       ` Frank B. Brokken
2011-05-25 18:43         ` Ian Lance Taylor
2011-05-25 19:10           ` Axel Freyn
2011-05-25 22:33           ` Frank B. Brokken
2011-05-27  8:13       ` George Danchev
2011-05-27 13:39         ` Ian Lance Taylor

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110525134815.GD31243@suffix.rc.rug.nl \
    --to=f.b.brokken@rug.nl \
    --cc=danchev@spnet.net \
    --cc=gcc-help@gcc.gnu.org \
    --cc=iant@google.com \
    --cc=tmancill@debian.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).